explorer: add temporary unlock alert box (#14457)

* Add token unlock banner

* make cluster time dynamic

* remove seconds display since it differs slightly from cluster stats

Co-authored-by: rmshea <8948187+rmshea@users.noreply.github.com>
This commit is contained in:
Josh 2021-01-05 21:00:36 -08:00 committed by GitHub
parent c282586753
commit 0767ea174e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 96 additions and 1 deletions

View File

@ -12,6 +12,7 @@ import { ClusterStatsPage } from "pages/ClusterStatsPage";
import { SupplyPage } from "pages/SupplyPage";
import { TransactionDetailsPage } from "pages/TransactionDetailsPage";
import { BlockDetailsPage } from "pages/BlockDetailsPage";
import { UnlockAlert } from "components/UnlockAlert";
const ADDRESS_ALIASES = ["account", "accounts", "addresses"];
const TX_ALIASES = ["txs", "txn", "txns", "transaction", "transactions"];
@ -20,6 +21,7 @@ function App() {
return (
<>
<ClusterModal />
<UnlockAlert />
<div className="main-content">
<Navbar />
<MessageBanner />

View File

@ -0,0 +1,93 @@
import React from "react";
import { Connection } from "@solana/web3.js";
import { useCluster, Cluster } from "providers/cluster";
const CLUSTER_SYNC_INTERVAL = 30000;
export function displayTimestamp(unixTimestamp: number): string {
const expireDate = new Date(unixTimestamp);
const dateString = new Intl.DateTimeFormat("en-US", {
year: "numeric",
month: "long",
day: "numeric",
}).format(expireDate);
const timeString = new Intl.DateTimeFormat("en-US", {
hour: "numeric",
minute: "numeric",
hour12: false,
timeZoneName: "long",
}).format(expireDate);
return `${dateString} at ${timeString}`;
}
export function UnlockAlert() {
const { cluster, url } = useCluster();
const [active, setActive] = React.useState(false);
const [blockTime, setBlockTime] = React.useState<number | null>(null);
React.useEffect(() => {
if (!active || !url) {
return;
}
const connection = new Connection(url);
const getBlockTime = async () => {
try {
const epochInfo = await connection.getEpochInfo();
const blockTime = await connection.getBlockTime(epochInfo.absoluteSlot);
if (blockTime !== null) {
setBlockTime(blockTime);
}
} catch (error) {}
};
getBlockTime();
const blockTimeInterval = setInterval(getBlockTime, CLUSTER_SYNC_INTERVAL);
const secondInterval = setInterval(() => {
setBlockTime((time) => (time !== null ? time + 1 : null));
}, 1000);
return () => {
clearInterval(blockTimeInterval);
clearInterval(secondInterval);
};
}, [active, url]);
React.useEffect(() => {
if (cluster !== Cluster.MainnetBeta) {
return;
}
setActive(true);
return () => {
setActive(false);
};
}, [setActive, cluster]);
if (cluster !== Cluster.MainnetBeta || blockTime === null) {
return null;
}
return (
<div className="alert alert-secondary text-center">
<p>An unlock event is timed for midnight January 7th UTC cluster time.</p>
<p>
Cluster time is currently {displayTimestamp(blockTime * 1000)} and may
differ from actual UTC time.
</p>
<p className="mb-0">
More information can be found{" "}
<a
href="https://solana.com/transparency"
className="text-white font-weight-bold"
rel="noopener noreferrer"
>
here
</a>
.
</p>
</div>
);
}

View File

@ -88,7 +88,7 @@ function StatsCardBody() {
)}
{blockTime && (
<tr>
<td className="w-100">Block time</td>
<td className="w-100">Cluster time</td>
<td className="text-lg-right text-monospace">
{displayTimestamp(blockTime)}
</td>