Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion client/src/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -547,6 +547,7 @@ export default function main({ DOM, HTTP, route, storage, scanner: scan$, search
})

on('.table-copy-button', 'click', { preventDefault: true }).subscribe(e => e.stopPropagation())
on('.tooltip', 'click', { preventDefault: true }).subscribe(e => e.stopPropagation())

on('.toggle-container', 'click').subscribe(({ ownerTarget: burgerMenu }) => {
burgerMenu.classList.toggle('open-menu');
Expand All @@ -569,12 +570,19 @@ export default function main({ DOM, HTTP, route, storage, scanner: scan$, search
})

document.addEventListener('click', e => {
const activeTooltip = document.activeElement
if (activeTooltip && activeTooltip.classList.contains('tooltip') && !e.target.closest('.tooltip')) {
activeTooltip.blur()
}
if (e.target.closest('.main-nav-container')) return
closeNetworkMenus()
})

document.addEventListener('keydown', e => {
if (e.key == 'Escape') closeNetworkMenus()
if (e.key == 'Escape') {
closeNetworkMenus()
document.activeElement && document.activeElement.classList.contains('tooltip') && document.activeElement.blur()
}

const hasModifier = e.metaKey || e.ctrlKey
, noExtraModifiers = !e.altKey && !e.shiftKey
Expand Down
9 changes: 3 additions & 6 deletions client/src/components/info-card.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { Tooltip } from "./tooltip";

export const InfoCard = ({
title,
tooltip,
Expand All @@ -16,12 +18,7 @@ export const InfoCard = ({
<div className="info-card-header">
{iconSrc ? <img className="menu-logo" alt="" src={iconSrc} /> : null}
<p className="info-card-title">{title}</p>
{tooltip ? (
<div className="tooltip">
<img alt="" src={tooltip.iconSrc} />
<div className="tooltip-dialogue">{tooltip.text}</div>
</div>
) : null}
{tooltip ? <Tooltip iconSrc={tooltip.iconSrc} text={tooltip.text} /> : null}
{headerValue !== undefined ? (
<p className="info-card-header-value">{headerValue}</p>
) : null}
Expand Down
14 changes: 14 additions & 0 deletions client/src/components/status-badge.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const StatusBadge = (
{ variant, className } = {},
children,
) => (
<span
className={["status-badge", variant, className].filter(Boolean).join(" ")}
>
{children}
</span>
);

export const ConfidentialBadge = ({ t }) => (
<StatusBadge variant="success">{t`Confidential`}</StatusBadge>
);
10 changes: 10 additions & 0 deletions client/src/components/tooltip.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const Tooltip = ({ iconSrc, text }) => (
<button
type="button"
className="tooltip"
aria-label={`More information: ${text}`}
>
<img alt="" src={iconSrc} />
<span className="tooltip-dialogue" role="tooltip">{text}</span>
</button>
);
3 changes: 2 additions & 1 deletion client/src/lib/elements.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {formatAssetAmount} from "../views/util";
import { ConfidentialBadge } from "../components/status-badge";

export const getSupply = (asset, t) => {
let { chain_stats = {}, mempool_stats = {} } = asset
Expand All @@ -19,7 +20,7 @@ export const getSupply = (asset, t) => {
chain_stats.burned_amount -
mempool_stats.burned_amount;

let totalSupply = circulating == null ? t`Confidential`
let totalSupply = circulating == null ? <ConfidentialBadge t={t} />
: formatAssetAmount(circulating, asset.precision, t)
return totalSupply
}
Expand Down
8 changes: 4 additions & 4 deletions client/src/views/asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import search from './search'
import { txBox } from './tx'
import { maxMempoolTxs, assetTxsPerPage as perPage, nativeAssetLabel, nativeAssetName } from '../const'
import loader from '../components/loading'
import { ConfidentialBadge } from '../components/status-badge'

const staticRoot = process.env.STATIC_ROOT || ''

Expand Down Expand Up @@ -172,7 +173,7 @@ export default ({ t, asset, assetTxs, goAsset, openTx, spends, tipHeight, loadin

, <div>
<div>{t`Issued amount`}</div>
<div>{chain_stats.has_blinded_issuances ? t`Confidential`
<div>{chain_stats.has_blinded_issuances ? <ConfidentialBadge t={t} />
: formatAssetAmount(chain_stats.issued_amount, asset.precision, t) }</div>
</div>

Expand All @@ -193,7 +194,7 @@ export default ({ t, asset, assetTxs, goAsset, openTx, spends, tipHeight, loadin

, <div>
<div>{t`Reissuance tokens created`}</div>
<div>{chain_stats.reissuance_tokens == null ? t`Confidential`
<div>{chain_stats.reissuance_tokens == null ? <ConfidentialBadge t={t} />
: chain_stats.reissuance_tokens === 0 ? t`None`
: formatNumber(chain_stats.reissuance_tokens) }</div>
</div>
Expand All @@ -210,7 +211,7 @@ export default ({ t, asset, assetTxs, goAsset, openTx, spends, tipHeight, loadin

, <div>
<div>{t`Circulating amount`}</div>
<div className="mono">{ circulating == null ? t`Confidential`
<div className="mono">{ circulating == null ? <ConfidentialBadge t={t} />
: formatAssetAmount(circulating, asset.precision, t) }</div>
</div>

Expand Down Expand Up @@ -284,4 +285,3 @@ const pagingNav = (asset, last_seen_txid, est_curr_chain_seen_count, prev_paging
<div><img alt="" src={`${staticRoot}img/icons/arrow_right_blu.png`} /></div>
</a>
]

5 changes: 2 additions & 3 deletions client/src/views/block-details-card.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { BlockGrid } from "../components/block-grid";
import { InfoStat } from "../components/info-stat";
import { StatusBadge } from "../components/status-badge";
import { ElapsedTime } from "../components/elapsed-time";
import {
formatTime,
Expand Down Expand Up @@ -46,9 +47,7 @@ const BlockDetailsCard = ({ className, block, confirmed }) => {
</p>

{confirmed ? (
<div className="confirmation-status-badge success">
<p>Confirmed</p>
</div>
<StatusBadge variant="success">Confirmed</StatusBadge>
) : null}
</div>

Expand Down
4 changes: 2 additions & 2 deletions client/src/views/block.js
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ export default ({ t, block: b, blockStatus: status, blockTxs, openTx, spends, op

<div className="load-more-container">
<div>
{ loading ? <div className="load-more g-btn font-btn-2 disabled"><span>{t`Loading...`}</span><div>{loader("small")}</div></div>
{ loading ? <div className="load-more load-more-loading g-btn primary-btn font-btn-2 disabled"><span>{t`Loading...`}</span><div>{loader("small")}</div></div>
: pagingNav(b, { ...S, t }) }
</div>
</div>
Expand Down Expand Up @@ -176,5 +176,5 @@ const btnDetails = (blockhash, isOpen, query, t) => process.browser
const btnDetailsContent = (isOpen, t) =>
<div role="button" tabindex="0">
<p>{t`Details`}</p>
<div>{isOpen ? <MinusIcon /> : <PlusIcon />}</div>
{isOpen ? <MinusIcon /> : <PlusIcon />}
</div>
11 changes: 5 additions & 6 deletions client/src/views/blocks.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import loader from "../components/loading";
import { BlockIcon, ClockIcon, CopyIcon } from "../components/icons";
import { InfoStat } from "../components/info-stat";
import { Tooltip } from "../components/tooltip";

const staticRoot = process.env.STATIC_ROOT || "";

Expand Down Expand Up @@ -80,12 +81,10 @@ export const blks = (blocks, viewMore, { t, ...S }) => (
<p className="usage-number">
{getBlockPercentageUsed(b.weight)}%
</p>
<div className="tooltip">
<img src={`${staticRoot}img/icons/tooltip.svg`} />
<div className="tooltip-dialogue">
How full this block is.
</div>
</div>
<Tooltip
iconSrc={`${staticRoot}img/icons/tooltip.svg`}
text="How full this block is."
/>
</div>
<div className="usage-bar">
<div
Expand Down
15 changes: 8 additions & 7 deletions client/src/views/difficulty-adjustment.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { ArrowsInSimpleIcon } from "../components/icons";
import { InfoCard } from "../components/info-card";
import { Tooltip } from "../components/tooltip";
import { difficultyPeriod } from "../const";

const staticRoot = process.env.STATIC_ROOT || "";
Expand Down Expand Up @@ -198,8 +199,8 @@ const adjustmentStat = (title, value, className = "") => (
</div>
);

const statDivider = () => (
<div className="difficulty-adjustment-stat-divider"></div>
const statDivider = (className) => (
<div className={["difficulty-adjustment-stat-divider", className || ""].join(" ")}></div>
);

export default ({
Expand Down Expand Up @@ -236,10 +237,10 @@ export default ({
<ArrowsInSimpleIcon />
</div>
<h1 className="table-header-title">Difficulty Adjustment</h1>
<div className="tooltip">
<img alt="" src={`${staticRoot}img/icons/tooltip.svg`} />
<div className="tooltip-dialogue">How hard it is to mine new blocks. Bitcoin retargets mining difficulty every 2,016 blocks to keep blocks near 10 minutes. Current is the projected next change; Previous was the last change.</div>
</div>
<Tooltip
iconSrc={`${staticRoot}img/icons/tooltip.svg`}
text="How hard it is to mine new blocks. Bitcoin retargets mining difficulty every 2,016 blocks to keep blocks near 10 minutes. Current is the projected next change; Previous was the last change."
/>
</div>
<div className="difficulty-adjustment-stats">
{adjustmentStat("AVERAGE BLOCK TIME", averageBlockTime)}
Expand All @@ -251,7 +252,7 @@ export default ({
adjustmentClass(expected),
)}

{statDivider()}
{statDivider("difficulty-adjustment-stat-divider-middle")}
{adjustmentStat(
"PREVIOUS ADJ",
formatAdjustment(previous),
Expand Down
43 changes: 28 additions & 15 deletions client/src/views/transactions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { formatSat, formatNumber, truncateTxid } from "./util";
import loader from "../components/loading";
import { CopyIcon, TxArrowsIcon } from "../components/icons";
import { ConfidentialBadge } from "../components/status-badge";

const staticRoot = process.env.STATIC_ROOT || "";

Expand Down Expand Up @@ -45,24 +46,36 @@ export const transactions = (txs, viewMore, { t, ...S }) => (
return (
<a href={`tx/${txOverview.txid}`}>
<div className={`transaction-table-row ${S.newTxEntries && S.newTxEntries[txOverview.txid] ? "new-table-entry" : ""}`}>
<div className="transaction-table-transaction-id">
<p>{truncateTxid(txOverview.txid)}</p>
<div
className="table-copy-button code-button-btn"
role="button"
tabindex="0"
data-clipboardCopy={txOverview.txid}
aria-label={`Copy transaction id ${txOverview.txid}`}
>
<CopyIcon />
<div className="transaction-table-field transaction-table-transaction-id">
<div className="transaction-table-field-label">{t`TX ID`}</div>
<div className="transaction-table-field-value">
<p>{truncateTxid(txOverview.txid)}</p>
<div
className="table-copy-button code-button-btn"
role="button"
tabindex="0"
data-clipboardCopy={txOverview.txid}
aria-label={`Copy transaction id ${txOverview.txid}`}
>
<CopyIcon />
</div>
</div>
</div>
<div className="transaction-table-transaction-value">
{txOverview.value ?
formatSat(txOverview.value) : "Confidential"}
<div className="transaction-table-field transaction-table-transaction-value">
<div className="transaction-table-field-label">{t`VALUE`}</div>
<div className="transaction-table-field-value">
{txOverview.value != null ?
formatSat(txOverview.value) : <ConfidentialBadge t={t} />}
</div>
</div>
<div className="transaction-table-field transaction-table-transaction-size">
<div className="transaction-table-field-label">{t`SIZE`}</div>
<div className="transaction-table-field-value">{`${formatNumber(txOverview.vsize)} vB`}</div>
</div>
<div className={`transaction-table-field transaction-table-transaction-fee ${feeClass}`}>
<div className="transaction-table-field-label">{t`FEE`}</div>
<div className="transaction-table-field-value">{`${feerate.toFixed(2)} sat/vB`}</div>
</div>
<div className="transaction-table-transaction-size">{`${formatNumber(txOverview.vsize)} vB`}</div>
<div className={`transaction-table-transaction-fee ${feeClass}`}>{`${feerate.toFixed(2)} sat/vB`}</div>
</div>
</a>
);
Expand Down
21 changes: 10 additions & 11 deletions client/src/views/tx.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
TxArrowsIcon,
} from "../components/icons";
import { InfoStat } from "../components/info-stat";
import { StatusBadge } from "../components/status-badge";
import BlockDetailsCard from "./block-details-card";

// Require behind env conditional so it gets removed by `envify` on non-elements builds
Expand Down Expand Up @@ -208,7 +209,7 @@ const btnDetails = (txid, isOpen, query, t) =>
const btnDetailsContent = (isOpen, t) => (
<div role="button" tabindex="0">
<p>{t`Details`}</p>
<div>{isOpen ? <MinusIcon /> : <PlusIcon />}</div>
{isOpen ? <MinusIcon /> : <PlusIcon />}
</div>
);

Expand Down Expand Up @@ -263,18 +264,16 @@ const txHeader = (
>
<CopyIcon />
</div>
<div
className={`confirmation-status-badge ${isConfirmed ? "success" : "warning"}`}
>
<StatusBadge variant={isConfirmed ? "success" : "warning"}>
{!isConfirmed ? (
<div className="confirmation-status-dot" aria-hidden="true">
<div className="confirmation-status-dot-back"></div>
<div className="confirmation-status-dot-middle"></div>
<div className="confirmation-status-dot-front"></div>
</div>
<span className="confirmation-status-dot" aria-hidden="true">
<span className="confirmation-status-dot-back"></span>
<span className="confirmation-status-dot-middle"></span>
<span className="confirmation-status-dot-front"></span>
</span>
) : null}
<p>{confirmationText(tx.status, tipHeight, t)}</p>
</div>
<span>{confirmationText(tx.status, tipHeight, t)}</span>
</StatusBadge>
</div>
<div className="info-stats-row">
<InfoStat title="SIZE" value={`${formatNumber(tx.size)} B`} />
Expand Down
3 changes: 2 additions & 1 deletion client/src/views/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import moveDec from 'move-decimal-point'
import { sat2btc } from 'fmtbtc'
import { maxBlockWeight, nativeAssetLabel } from '../const'
import { isNativeOut } from '../util'
import { ConfidentialBadge } from '../components/status-badge'

const DEFAULT_ISSUED_PRECISION = 0
, NATIVE_PRECISION = 8
Expand Down Expand Up @@ -29,7 +30,7 @@ export const formatAssetAmount = (value, precision=0, t) =>
</span>

export const formatOutAmount = (vout, { t, assetMap }, shortDisplay=false) => {
if (vout.value == null) return t`Confidential`
if (vout.value == null) return <ConfidentialBadge t={t} />

if (isNativeOut(vout)) {
return <span>
Expand Down
Loading