-
BLOCK FILLING
+
{block ? `${percentage}%` : "N/A"}
diff --git a/client/src/components/block-signatures.js b/client/src/components/block-signatures.js
new file mode 100644
index 00000000..8995c947
--- /dev/null
+++ b/client/src/components/block-signatures.js
@@ -0,0 +1,37 @@
+import { parseBlockSignatures } from "../lib/block-signatures";
+
+let lastWarningKey;
+
+const warnOnce = (block, error) => {
+ if (!process.browser) return;
+
+ const source = error.source || "challenge";
+ const warningKey = `${block && block.id}:${source}`;
+ if (warningKey === lastWarningKey) return;
+
+ lastWarningKey = warningKey;
+ console.warn(`Failed to parse ${source} script`, error);
+};
+
+const BlockSignatures = ({ block }) => {
+ const result = parseBlockSignatures(block);
+
+ if (result && result.error) {
+ warnOnce(block, result.error);
+ }
+
+ const signatures = result && !result.error ? result : null;
+
+ return signatures ? (
+
+
{`${signatures.signatureCount} of ${signatures.totalSigners}`}
+
+ {`${signatures.requiredSignatures} required`}
+
+
+ ) : (
+
N/A
+ );
+};
+
+export default BlockSignatures;
diff --git a/client/src/components/elapsed-time.js b/client/src/components/elapsed-time.js
index 407fca9e..df6a0df7 100644
--- a/client/src/components/elapsed-time.js
+++ b/client/src/components/elapsed-time.js
@@ -3,7 +3,7 @@ const MINUTES_PER_DAY = 24 * 60;
const MINUTES_PER_YEAR = 365 * MINUTES_PER_DAY;
const MINUTES_PER_MONTH = MINUTES_PER_YEAR / 12;
-const formatElapsedTime = (timestamp) => {
+const formatElapsedTime = (timestamp, compact) => {
const fromDate =
timestamp < 1e12 ? new Date(timestamp * 1000) : new Date(timestamp);
const diffMinutes = Math.max(
@@ -17,26 +17,41 @@ const formatElapsedTime = (timestamp) => {
minutesAfterYears - months * MINUTES_PER_MONTH,
);
const units = [
- ["y", years],
- ["mo", months],
- ["d", Math.floor(minutesAfterMonths / MINUTES_PER_DAY)],
- ["h", Math.floor((minutesAfterMonths % MINUTES_PER_DAY) / 60)],
- ["m", minutesAfterMonths % 60],
+ ["YEAR", "YEARS", "y", years],
+ ["MONTH", "MONTHS", "mo", months],
+ ["DAY", "DAYS", "d", Math.floor(minutesAfterMonths / MINUTES_PER_DAY)],
+ [
+ "HOUR",
+ "HOURS",
+ "h",
+ Math.floor((minutesAfterMonths % MINUTES_PER_DAY) / 60),
+ ],
+ ["MINUTE", "MINUTES", "m", minutesAfterMonths % 60],
];
const parts = units
- .filter(([_, value]) => value > 0)
+ .filter((unit) => unit[3] > 0)
.slice(0, 2)
- .map(([unit, value]) => `${value}${unit}`);
+ .map(([singular, plural, abbreviation, value]) =>
+ compact
+ ? `${value}${abbreviation}`
+ : `${value} ${value === 1 ? singular : plural}`,
+ );
- return parts.length ? parts.join(" ") : "< 1m";
+ if (compact) return parts.length ? parts.join(" ") : "< 1m";
+
+ return parts.length ? `${parts.join(" ")} AGO` : "< 1 MINUTE AGO";
};
const updateElapsedTime = (element) => {
- element.textContent = formatElapsedTime(element.elapsedTimeTimestamp);
+ element.textContent = formatElapsedTime(
+ element.elapsedTimeTimestamp,
+ element.elapsedTimeCompact,
+ );
};
-const startElapsedTime = (vnode, timestamp) => {
+const startElapsedTime = (vnode, timestamp, compact) => {
vnode.elm.elapsedTimeTimestamp = timestamp;
+ vnode.elm.elapsedTimeCompact = compact;
updateElapsedTime(vnode.elm);
vnode.elm.elapsedTimeInterval = window.setInterval(
() => updateElapsedTime(vnode.elm),
@@ -44,8 +59,9 @@ const startElapsedTime = (vnode, timestamp) => {
);
};
-const patchElapsedTime = (_, vnode, timestamp) => {
+const patchElapsedTime = (_, vnode, timestamp, compact) => {
vnode.elm.elapsedTimeTimestamp = timestamp;
+ vnode.elm.elapsedTimeCompact = compact;
updateElapsedTime(vnode.elm);
};
@@ -53,14 +69,14 @@ const stopElapsedTime = (vnode) => {
window.clearInterval(vnode.elm.elapsedTimeInterval);
};
-export const ElapsedTime = ({ timestamp } = {}) => (
+export const ElapsedTime = ({ timestamp, compact = false } = {}) => (
startElapsedTime(vnode, timestamp)}
+ hook-insert={(vnode) => startElapsedTime(vnode, timestamp, compact)}
hook-postpatch={(oldVnode, vnode) =>
- patchElapsedTime(oldVnode, vnode, timestamp)
+ patchElapsedTime(oldVnode, vnode, timestamp, compact)
}
hook-destroy={stopElapsedTime}
>
- {formatElapsedTime(timestamp)}
+ {formatElapsedTime(timestamp, compact)}
);
diff --git a/client/src/components/icons.js b/client/src/components/icons.js
index d5486491..2589c034 100644
--- a/client/src/components/icons.js
+++ b/client/src/components/icons.js
@@ -59,6 +59,18 @@ export const ChevronRightIcon = ({ className } = {}) =>
+export const CaretCircleLeftIcon = ({ className } = {}) =>
+
+
+export const CaretCircleRightIcon = ({ className } = {}) =>
+
+
export const ChevronDownIcon = ({ className } = {}) =>