mirror of
https://github.com/janoside/btc-rpc-explorer.git
synced 2026-08-13 12:33:13 +02:00
homepage: live halving countdown section when very close (98%+)
This commit is contained in:
parent
1bf7ad3cb8
commit
4fc15aa9a9
6 changed files with 149 additions and 10 deletions
BIN
public/audio/609335__kenneth_cooney__levelup.wav
Normal file
BIN
public/audio/609335__kenneth_cooney__levelup.wav
Normal file
Binary file not shown.
|
|
@ -84,6 +84,59 @@ router.get("/next-block", asyncHandler(async (req, res, next) => {
|
|||
res.render("snippets/index-next-block");
|
||||
}));
|
||||
|
||||
router.get("/index-halving-countdown", asyncHandler(async (req, res, next) => {
|
||||
try {
|
||||
const getblockchaininfo = await utils.timePromise("snippet.index-halving-countdown.getBlockchainInfo", async () => {
|
||||
return await coreApi.getBlockchainInfo();
|
||||
});
|
||||
|
||||
let promises = [];
|
||||
|
||||
res.locals.getblockchaininfo = getblockchaininfo;
|
||||
res.locals.difficultyPeriod = parseInt(Math.floor(getblockchaininfo.blocks / coinConfig.difficultyAdjustmentBlockCount));
|
||||
|
||||
let blockHeights = [];
|
||||
if (getblockchaininfo.blocks) {
|
||||
for (let i = 0; i < 1; i++) {
|
||||
blockHeights.push(getblockchaininfo.blocks - i);
|
||||
}
|
||||
} else if (global.activeBlockchain == "regtest") {
|
||||
// hack: default regtest node returns getblockchaininfo.blocks=0, despite
|
||||
// having a genesis block; hack this to display the genesis block
|
||||
blockHeights.push(0);
|
||||
}
|
||||
|
||||
promises.push(utils.timePromise("snippet.index-halving-countdown.getBlockHeaderByHeight", async () => {
|
||||
let h = coinConfig.difficultyAdjustmentBlockCount * res.locals.difficultyPeriod;
|
||||
res.locals.difficultyPeriodFirstBlockHeader = await coreApi.getBlockHeaderByHeight(h);
|
||||
}));
|
||||
|
||||
promises.push(utils.timePromise("snippet.index-halving-countdown.getBlocksByHeight", async () => {
|
||||
const latestBlocks = await coreApi.getBlocksByHeight(blockHeights);
|
||||
|
||||
res.locals.latestBlocks = latestBlocks;
|
||||
}));
|
||||
|
||||
await utils.awaitPromises(promises);
|
||||
|
||||
|
||||
let nextHalvingData = utils.nextHalvingEstimates(res.locals.difficultyPeriodFirstBlockHeader, res.locals.latestBlocks[0]);
|
||||
|
||||
res.locals.nextHalvingData = nextHalvingData;
|
||||
|
||||
await utils.timePromise("snippet.index-halving-countdown.render", async () => {
|
||||
res.render("snippets/index-halving-countdown");
|
||||
});
|
||||
|
||||
} catch (e) {
|
||||
res.locals.pageErrors.push(utils.logError("390wrgehburfuge", e));
|
||||
|
||||
await utils.timePromise("snippet.index-halving-countdown.render", async () => {
|
||||
res.render("snippets/index-halving-countdown");
|
||||
});
|
||||
}
|
||||
}));
|
||||
|
||||
router.get("/utxo-set", asyncHandler(async (req, res, next) => {
|
||||
const promises = [];
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,37 @@ if (exchangeRates || networkVolume)
|
|||
- var utxoCalculatingDesc = "At startup the app pulls a summary of the UTXO set. Until this summary is retrieved this data can't be displayed. Wait for the summary request to your node to return, then refresh this page.";
|
||||
|
||||
|
||||
- let halvingSoon = false;
|
||||
- let halvingVerySoon = false;
|
||||
- let halvingProgressPercent = 0;
|
||||
|
||||
if (nextHalvingData)
|
||||
- halvingProgressPercent = new Decimal(100).minus(new Decimal(nextHalvingData.blocksUntilNextHalving).dividedBy(nextHalvingData.halvingBlockInterval).times(100));
|
||||
|
||||
if (halvingProgressPercent > 65)
|
||||
- halvingSoon = true;
|
||||
|
||||
if (halvingProgressPercent > 98)
|
||||
-halvingVerySoon = true;
|
||||
|
||||
|
||||
if (halvingVerySoon)
|
||||
#index-halving-countdown-wrapper
|
||||
.d-flex.justify-content-start
|
||||
.text-success
|
||||
+sectionTitle("Halving Countdown 👀")
|
||||
|
||||
.ms-2
|
||||
span.spinner-border.spinner-border-sm
|
||||
|
||||
|
||||
.mb-section
|
||||
.card.mb-section.shadow-sm.border-2.border-success
|
||||
.card-body
|
||||
div#index-halving-countdown
|
||||
.text-center.text-reset
|
||||
.mt-2
|
||||
.spinner-border.spinner-border-sm
|
||||
|
||||
if (exchangeRates)
|
||||
+contentSection("Market")
|
||||
|
|
@ -80,13 +110,7 @@ if (exchangeRates)
|
|||
|
||||
|
||||
+contentSection
|
||||
- let halvingShown = false;
|
||||
- let halvingProgressPercent = new Decimal(100).minus(new Decimal(nextHalvingData.blocksUntilNextHalving).dividedBy(nextHalvingData.halvingBlockInterval).times(100));
|
||||
|
||||
if (nextHalvingData && halvingProgressPercent > 65)
|
||||
- halvingShown = true;
|
||||
|
||||
+summaryRow(2 + (halvingShown ? 1 : 0) + (hashrate7d ? 1 : 0) + (chainTxStats && chainTxStats[7 * targetBlocksPerDay] ? 1 : 0) + (difficultyAdjustmentData ? 1 : 0))
|
||||
+summaryRow(2 + (halvingSoon ? 1 : 0) + (hashrate7d ? 1 : 0) + (chainTxStats && chainTxStats[7 * targetBlocksPerDay] ? 1 : 0) + (difficultyAdjustmentData ? 1 : 0))
|
||||
if (hashrate7d)
|
||||
+summaryItem("7d Hashrate", "The average hashrate of the global mining network over the last 7 days. A comparison to the 30-day average is included to help gauge the rate of change.")
|
||||
- var hashrate7dayData = utils.formatLargeNumber(hashrate7d, 1);
|
||||
|
|
@ -110,7 +134,7 @@ if (exchangeRates)
|
|||
|
||||
| )
|
||||
|
||||
if (halvingShown)
|
||||
if (halvingSoon)
|
||||
if (false)
|
||||
pre #{JSON.stringify(nextHalvingData)}
|
||||
|
||||
|
|
|
|||
|
|
@ -618,7 +618,9 @@ mixin timestamp(timestamp, options={includeAgo:true, agoOptions:{}})
|
|||
|
||||
|
||||
|
||||
mixin timeAgo(timeAgoTime, options={oneElement:false, agoText:true})
|
||||
mixin timeAgo(timeAgoTime, options={oneElement:false, agoText:true, showPlus:true})
|
||||
- let showPlus = "showPlus" in options ? options.showPlus : true;
|
||||
|
||||
- let oneElement = false;
|
||||
if (options && "oneElement" in options)
|
||||
- oneElement = options.oneElement;
|
||||
|
|
@ -640,7 +642,7 @@ mixin timeAgo(timeAgoTime, options={oneElement:false, agoText:true})
|
|||
- timeAgo = moment.duration(moment.utc(new Date(parseInt(timeAgoTime) * 1000)).diff(moment.utc(new Date())));
|
||||
|
||||
|
||||
if (future)
|
||||
if (future && showPlus)
|
||||
span +
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -127,10 +127,44 @@ block content
|
|||
|
||||
block endOfBody
|
||||
script.
|
||||
var audio = new Audio('./audio/609335__kenneth_cooney__levelup.wav');
|
||||
var tipInfo = null;
|
||||
|
||||
function refreshHalvingCountdownUI() {
|
||||
$.get("./snippet/index-halving-countdown", function(data) {
|
||||
$("#index-halving-countdown").html(data);
|
||||
enableTooltipsAndPopovers();
|
||||
});
|
||||
}
|
||||
|
||||
function checkHalvingCountdown() {
|
||||
$.get("./api/blocks/tip", function(data) {
|
||||
if (data.height > tipInfo.height) {
|
||||
tipInfo = data;
|
||||
|
||||
audio.play();
|
||||
|
||||
refreshHalvingCountdownUI();
|
||||
}
|
||||
|
||||
console.log(tipInfo);
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$.get("./snippet/next-block", function(data) {
|
||||
$("#index-next-block").html(data);
|
||||
enableTooltipsAndPopovers();
|
||||
});
|
||||
|
||||
$.get("./api/blocks/tip", function(data) {
|
||||
tipInfo = data;
|
||||
});
|
||||
|
||||
if ($("#index-halving-countdown-wrapper").length) {
|
||||
refreshHalvingCountdownUI();
|
||||
|
||||
setInterval(checkHalvingCountdown, 3000);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
|||
26
views/snippets/index-halving-countdown.pug
Normal file
26
views/snippets/index-halving-countdown.pug
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
include ../includes/shared-mixins.pug
|
||||
|
||||
if (nextHalvingData.nextHalvingIndex > -1)
|
||||
+summaryRow(5)
|
||||
+summaryItem("Blocks Remaining")
|
||||
| #{nextHalvingData.blocksUntilNextHalving.toLocaleString()}
|
||||
|
||||
+summaryItem("Time Remaining", "The estimated time until halving, based on the number of blocks remaining and the current mining rate (up until the next difficulty adjustment).")
|
||||
+timeAgo(nextHalvingData.nextHalvingDate.getTime() / 1000, {showPlus:false})
|
||||
|
||||
+summaryItem("Estimated Date", "The date of halving, estimated based on the number of blocks remaining and the current mining rate (up until the next difficulty adjustment).")
|
||||
+timestamp(nextHalvingData.nextHalvingDate.getTime() / 1000, {includeAgo:false})
|
||||
|
||||
+summaryItem("Block Height", "The block height at which the new block subsidy will begin.")
|
||||
| #{nextHalvingData.nextHalvingBlock.toLocaleString()}
|
||||
|
||||
+summaryItem("New Subsidy", "The new supply that will be created (and rewarded to the winning miner) for each new block during the next halving's era.")
|
||||
- let subsidy = coinConfig.blockRewardFunction(nextHalvingData.nextHalvingBlock, global.activeBlockchain);
|
||||
+valueDisplay(subsidy)
|
||||
|
||||
- let progressPercent = new Decimal(nextHalvingData.halvingBlockInterval).minus(nextHalvingData.blocksUntilNextHalving).dividedBy(nextHalvingData.halvingBlockInterval).times(100);
|
||||
.progress.mt-5(role="progressbar", aria-label="Next halving progress", aria-valuenow=progressPercent.toDP(0), aria-valuemin="0", aria-valuemax="100")
|
||||
.progress-bar(style=`width: ${progressPercent.toDP(0)}%`)
|
||||
| #{progressPercent.toDP(4)}%
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue