From e1001af89d6f9d85db04e15e8aaad160a726b180 Mon Sep 17 00:00:00 2001 From: Dean Sallinen <7519573+deansallinen@users.noreply.github.com> Date: Fri, 6 Dec 2024 10:44:40 -0800 Subject: [PATCH 01/58] refactor(button): allow overriding button classes --- src/lib/components/button/button.svelte | 42 ++++++++++++------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/lib/components/button/button.svelte b/src/lib/components/button/button.svelte index 243588d9..c554fa4c 100644 --- a/src/lib/components/button/button.svelte +++ b/src/lib/components/button/button.svelte @@ -1,4 +1,5 @@ - {@render props.children()} + {@render props.children()} - - From a0918c0ce9ae68fea0edddca98a9d5b943614027 Mon Sep 17 00:00:00 2001 From: Aaron Cox Date: Fri, 6 Dec 2024 10:55:04 -0800 Subject: [PATCH 02/58] Added robots.txt --- static/robots.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 static/robots.txt diff --git a/static/robots.txt b/static/robots.txt new file mode 100644 index 00000000..14267e90 --- /dev/null +++ b/static/robots.txt @@ -0,0 +1,2 @@ +User-agent: * +Allow: / \ No newline at end of file From cc736a7772c2b6c43399c8ba6eb0148e7bb975f7 Mon Sep 17 00:00:00 2001 From: Aaron Cox Date: Fri, 6 Dec 2024 14:26:58 -0800 Subject: [PATCH 03/58] Use Big.js to safely wrap asset quantities --- src/lib/components/elements/asset.svelte | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/lib/components/elements/asset.svelte b/src/lib/components/elements/asset.svelte index 9be07b61..8cc22316 100644 --- a/src/lib/components/elements/asset.svelte +++ b/src/lib/components/elements/asset.svelte @@ -6,6 +6,7 @@ import { cn } from '$lib/utils'; import type { UnicoveContext } from '$lib/state/client.svelte'; import { getContext } from 'svelte'; + import Big from 'big.js'; const context = getContext('state'); @@ -34,7 +35,10 @@ }; function formatAssetValue() { - return Intl.NumberFormat(locale, assetOptions).format(asset?.value || fallback); + // Use Big.js to accurately convert the string into a usable number + // Some precision may be lost in extreme circumstances + const number = Number(new Big(asset?.quantity || fallback)); + return Intl.NumberFormat(locale, assetOptions).format(number); } function formatCurrencyValue() { From 281cc4904d3b2820d95af573a71e9bbb18c41e9d Mon Sep 17 00:00:00 2001 From: Aaron Cox Date: Fri, 6 Dec 2024 14:27:10 -0800 Subject: [PATCH 04/58] Link to token page from account balances --- .../(explorer)/account/[name]/balances/+page.svelte | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/routes/[network]/(explorer)/account/[name]/balances/+page.svelte b/src/routes/[network]/(explorer)/account/[name]/balances/+page.svelte index e15a14b3..19a3a1df 100644 --- a/src/routes/[network]/(explorer)/account/[name]/balances/+page.svelte +++ b/src/routes/[network]/(explorer)/account/[name]/balances/+page.svelte @@ -48,7 +48,11 @@ LOGO {/if} - {balance.asset.symbol.name} + + {balance.asset.symbol.name} + From 41afe8f18a81542e8fb7fc626500d79a03b886da Mon Sep 17 00:00:00 2001 From: Dean Sallinen <7519573+deansallinen@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:45:33 -0800 Subject: [PATCH 05/58] refactor: description list component --- src/lib/components/descriptionlist.svelte | 25 -------- src/lib/components/descriptionlist/dd.svelte | 5 ++ src/lib/components/descriptionlist/dl.svelte | 10 ++- .../components/descriptionlist/dlrow.svelte | 21 +++++-- src/lib/components/descriptionlist/dt.svelte | 5 ++ src/lib/components/descriptionlist/index.ts | 2 + .../(account)/ram/(forms)/buy/+page.svelte | 62 +++++++++--------- .../(account)/ram/(forms)/sell/+page.svelte | 63 ++++++++++--------- .../staking/(staking)/stake/+page.svelte | 16 +++-- .../staking/(staking)/unstake/+page.svelte | 6 +- .../debug/components/sections/tables.svelte | 48 +++++++++++--- .../(explorer)/block/[number]/+page.svelte | 26 +++++--- 12 files changed, 170 insertions(+), 119 deletions(-) delete mode 100644 src/lib/components/descriptionlist.svelte create mode 100644 src/lib/components/descriptionlist/dd.svelte create mode 100644 src/lib/components/descriptionlist/dt.svelte diff --git a/src/lib/components/descriptionlist.svelte b/src/lib/components/descriptionlist.svelte deleted file mode 100644 index d8d06255..00000000 --- a/src/lib/components/descriptionlist.svelte +++ /dev/null @@ -1,25 +0,0 @@ - - -
- {#each props.items as item} -
-
{item.key}
-
{item.value}
-
- {/each} -
diff --git a/src/lib/components/descriptionlist/dd.svelte b/src/lib/components/descriptionlist/dd.svelte new file mode 100644 index 00000000..5a6a5af2 --- /dev/null +++ b/src/lib/components/descriptionlist/dd.svelte @@ -0,0 +1,5 @@ + + +
{@render props.children()}
diff --git a/src/lib/components/descriptionlist/dl.svelte b/src/lib/components/descriptionlist/dl.svelte index ef7e1cdc..f184044b 100644 --- a/src/lib/components/descriptionlist/dl.svelte +++ b/src/lib/components/descriptionlist/dl.svelte @@ -3,8 +3,8 @@ import Dlrow from './dlrow.svelte'; type DescriptionItem = { - key: string; - value: string; + title: string; + description: string; }; interface Props { @@ -17,10 +17,8 @@
{#if props.items} - {#each props.items as item} - - {item.value} - + {#each props.items as { title, description }} + {/each} {:else if props.children} {@render props.children()} diff --git a/src/lib/components/descriptionlist/dlrow.svelte b/src/lib/components/descriptionlist/dlrow.svelte index 70128fda..6bea9b8f 100644 --- a/src/lib/components/descriptionlist/dlrow.svelte +++ b/src/lib/components/descriptionlist/dlrow.svelte @@ -1,16 +1,29 @@
-
{title}
-
{@render children()}
+
{title}
+
+ {#if description} +
{description}
+ {/if} + {#if children} + {@render children()} + {/if} +
diff --git a/src/lib/components/descriptionlist/dt.svelte b/src/lib/components/descriptionlist/dt.svelte new file mode 100644 index 00000000..852406c2 --- /dev/null +++ b/src/lib/components/descriptionlist/dt.svelte @@ -0,0 +1,5 @@ + + +
{@render props.children()}
diff --git a/src/lib/components/descriptionlist/index.ts b/src/lib/components/descriptionlist/index.ts index 8947140a..6f2b22ec 100644 --- a/src/lib/components/descriptionlist/index.ts +++ b/src/lib/components/descriptionlist/index.ts @@ -1,2 +1,4 @@ export { default as DL } from './dl.svelte'; export { default as DLRow } from './dlrow.svelte'; +export { default as DD } from './dd.svelte'; +export { default as DT } from './dt.svelte'; diff --git a/src/routes/[network]/(account)/ram/(forms)/buy/+page.svelte b/src/routes/[network]/(account)/ram/(forms)/buy/+page.svelte index 6fd898ce..e8b835d1 100644 --- a/src/routes/[network]/(account)/ram/(forms)/buy/+page.svelte +++ b/src/routes/[network]/(account)/ram/(forms)/buy/+page.svelte @@ -20,6 +20,7 @@ import { BuyRAMState } from './state.svelte'; import { calAvailableSize, preventDefault } from '$lib/utils'; + import { DD, DL, DLRow } from '$lib/components/descriptionlist'; let bytesInput: BytesInput | undefined = $state(); let assetInput: AssetInput | undefined = $state(); @@ -139,34 +140,39 @@ -
-

- {m.common_labeled_unit_price({ - unit: `${context.network.chain.systemToken?.symbol.name}/RAM` - })} (KB) -

- - -
- -

{m.ram_to_purchase()}

- - -
- -

{m.ram_purchase_value()}

- - -
- -

{m.common_network_fees()} (0.5%)

- - -
- -

{m.common_total_cost()}

- -
+
+ +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+
{#if buyRamState.valid} {#if buyRamState.format === 'asset'} diff --git a/src/routes/[network]/(account)/ram/(forms)/sell/+page.svelte b/src/routes/[network]/(account)/ram/(forms)/sell/+page.svelte index f6d7ab8a..bb958358 100644 --- a/src/routes/[network]/(account)/ram/(forms)/sell/+page.svelte +++ b/src/routes/[network]/(account)/ram/(forms)/sell/+page.svelte @@ -19,6 +19,7 @@ import { SellRAMState } from './state.svelte'; import { calAvailableSize, preventDefault } from '$lib/utils'; + import { DD, DL, DLRow } from '$lib/components/descriptionlist'; let bytesInput: BytesInput | undefined = $state(); let assetInput: AssetInput | undefined = $state(); @@ -125,36 +126,40 @@ {m.common_unit_sell({ unit: 'RAM' })} - -
-

- {m.common_labeled_unit_price({ - unit: `${context.network.chain.systemToken?.symbol.name}/RAM` - })} (KB) -

- - -
- -

{m.ram_to_sell()}

- - -
- -

{m.total_proceeds()}

- - -
- -

{m.common_network_fees()} (0.5%)

- - -
- -

{m.common_expected_receive()}

- -
+
+ +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+ + +
+ +
+
+
{#if sellRamState.valid}
- +
{/if} diff --git a/src/routes/[network]/(account)/staking/(staking)/unstake/+page.svelte b/src/routes/[network]/(account)/staking/(staking)/unstake/+page.svelte index 924cf90d..c8837028 100644 --- a/src/routes/[network]/(account)/staking/(staking)/unstake/+page.svelte +++ b/src/routes/[network]/(account)/staking/(staking)/unstake/+page.svelte @@ -6,7 +6,7 @@ import Button from '$lib/components/button/button.svelte'; import Label from '$lib/components/input/label.svelte'; import TransactionSummary from '$lib/components/transactionSummary.svelte'; - import Descriptionlist from '$lib/components/descriptionlist.svelte'; + import { DL } from '$lib/components/descriptionlist'; import type { UnicoveContext } from '$lib/state/client.svelte'; import { getContext } from 'svelte'; import { UnstakeManager } from './manager.svelte'; @@ -18,7 +18,7 @@ let manager: UnstakeManager = $state(new UnstakeManager(data.network)); let hints = $derived([ - { key: m.staking_withdraw_timeframe(), value: manager.assetValue.toString() } + { title: m.staking_withdraw_timeframe(), description: manager.assetValue.toString() } ]); $effect(() => { @@ -78,6 +78,6 @@ - +
{/if} diff --git a/src/routes/[network]/(dev)/debug/components/sections/tables.svelte b/src/routes/[network]/(dev)/debug/components/sections/tables.svelte index a5f02107..51d297d0 100644 --- a/src/routes/[network]/(dev)/debug/components/sections/tables.svelte +++ b/src/routes/[network]/(dev)/debug/components/sections/tables.svelte @@ -1,6 +1,7 @@ @@ -50,8 +51,39 @@ row striping here.

+ +
+ + +

+ For displaying a component in the description, or multiple values under a single key, you can + use the components declaratively. +

+ +

+ Note: You need to wrap the child component correctly or you'll get a warning. There are CSS + rules that'll visually yell at you to fix it :) +

+
- +
+ +
+ +
+
+ +
+ +
+
+ +
+
+ + + +
diff --git a/src/routes/[network]/(explorer)/block/[number]/+page.svelte b/src/routes/[network]/(explorer)/block/[number]/+page.svelte index 1443c0e8..1091aeb7 100644 --- a/src/routes/[network]/(explorer)/block/[number]/+page.svelte +++ b/src/routes/[network]/(explorer)/block/[number]/+page.svelte @@ -4,7 +4,7 @@ import AccountText from '$lib/components/elements/account.svelte'; import Button from '$lib/components/button/button.svelte'; import { ArrowLeftRight, ArrowRight, ArrowLeft } from 'lucide-svelte'; - import { DL, DLRow } from '$lib/components/descriptionlist/index.js'; + import { DD, DL, DLRow } from '$lib/components/descriptionlist/index.js'; import { goto } from '$lib/utils'; let { data } = $props(); @@ -78,22 +78,34 @@
- {data.details.blockNumber} +
+ {data.details.blockNumber} +
- +
+ +
- {data.details.totalCpu} μs +
+ {data.details.totalCpu} μs +
- {data.details.totalNet * 8} Bytes +
+ {data.details.totalNet * 8} Bytes +
- {data.details.totalActions} +
+ {data.details.totalActions} +
- {data.details.blockId} +
+ {data.details.blockId} +
From 71ce477cc6f805b51e989f0dfae4096c6c233a04 Mon Sep 17 00:00:00 2001 From: Dean Sallinen <7519573+deansallinen@users.noreply.github.com> Date: Fri, 6 Dec 2024 10:44:40 -0800 Subject: [PATCH 06/58] refactor(button): allow overriding button classes --- src/lib/components/button/button.svelte | 42 ++++++++++++------------- 1 file changed, 20 insertions(+), 22 deletions(-) diff --git a/src/lib/components/button/button.svelte b/src/lib/components/button/button.svelte index 243588d9..c554fa4c 100644 --- a/src/lib/components/button/button.svelte +++ b/src/lib/components/button/button.svelte @@ -1,4 +1,5 @@ - {@render props.children()} + {@render props.children()} - - From 7a361f8b7a251c6ff111237059b649d2f1cd36f2 Mon Sep 17 00:00:00 2001 From: Dean Sallinen <7519573+deansallinen@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:07:45 -0800 Subject: [PATCH 07/58] style: actions --- src/lib/components/elements/action.svelte | 47 +++++++++++++++++-- .../msig/[proposer]/[proposal]/+layout.ts | 24 +++++----- 2 files changed, 55 insertions(+), 16 deletions(-) diff --git a/src/lib/components/elements/action.svelte b/src/lib/components/elements/action.svelte index 7648c34f..69ae7377 100644 --- a/src/lib/components/elements/action.svelte +++ b/src/lib/components/elements/action.svelte @@ -1,13 +1,52 @@ -{#if props.data} - {JSON.stringify(props.data, null, 2)} +{#if action} +
+ {JSON.stringify(humanReadable, null, 2)} + +

{String(action.name)}

+
+ +
+ +
+
+ + {#each action.authorization as auth} +
+ {auth} +
+ {/each} +
+
+
+
{/if} diff --git a/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+layout.ts b/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+layout.ts index fbb84cd9..48ac2f7d 100644 --- a/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+layout.ts +++ b/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+layout.ts @@ -33,16 +33,16 @@ export const load: LayoutLoad = async ({ fetch, params, parent }) => { ); // TODO: Use ABICache here to prevent duplicate calls - const actions = await Promise.all( - transaction.actions.map(async (a) => { - const { abi } = await network.client.v1.chain.get_abi(String(a.account)); - if (abi) { - const decoded = a.decodeData(abi); - return Serializer.objectify(decoded) as Record; - } - return {}; - }) - ); + // const actions = await Promise.all( + // transaction.actions.map(async (a) => { + // const { abi } = await network.client.v1.chain.get_abi(String(a.account)); + // if (abi) { + // const decoded = a.decodeData(abi); + // return Serializer.objectify(decoded) as Record; + // } + // return {}; + // }) + // ); return { title: `${params.proposal}`, @@ -53,8 +53,8 @@ export const load: LayoutLoad = async ({ fetch, params, parent }) => { name: params.proposal, hash: transaction.id, packed, - transaction, - actions + transaction + // actions } }; }; From 09acc18cfea7c358cf2f34fab5bfd0c340c1e08f Mon Sep 17 00:00:00 2001 From: Dean Sallinen <7519573+deansallinen@users.noreply.github.com> Date: Fri, 6 Dec 2024 14:59:57 -0800 Subject: [PATCH 08/58] refactor: use new dl and button styles --- .../msig/[proposer]/[proposal]/+layout.ts | 13 -- .../msig/[proposer]/[proposal]/+page.svelte | 201 ++++++++++-------- 2 files changed, 108 insertions(+), 106 deletions(-) diff --git a/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+layout.ts b/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+layout.ts index 48ac2f7d..aba475d4 100644 --- a/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+layout.ts +++ b/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+layout.ts @@ -32,18 +32,6 @@ export const load: LayoutLoad = async ({ fetch, params, parent }) => { ({ level }: { level?: PermissionLevel }) => (level ? PermissionLevel.from(level) : undefined) ); - // TODO: Use ABICache here to prevent duplicate calls - // const actions = await Promise.all( - // transaction.actions.map(async (a) => { - // const { abi } = await network.client.v1.chain.get_abi(String(a.account)); - // if (abi) { - // const decoded = a.decodeData(abi); - // return Serializer.objectify(decoded) as Record; - // } - // return {}; - // }) - // ); - return { title: `${params.proposal}`, subtitle: `An MSIG proposed by ${params.proposer} on the ${network.chain.name} Network`, @@ -54,7 +42,6 @@ export const load: LayoutLoad = async ({ fetch, params, parent }) => { hash: transaction.id, packed, transaction - // actions } }; }; diff --git a/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+page.svelte b/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+page.svelte index cfaa99b1..4eeb9828 100644 --- a/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+page.svelte +++ b/src/routes/[network]/(explorer)/msig/[proposer]/[proposal]/+page.svelte @@ -1,14 +1,14 @@ - - -

Requested Approvals

- -
-
-
- - - - {totalApproved} - - Approved -
- -
- - - - {totalRequested} - - Requested + + + +

Requested Approvals

+ +
+
+
+ + + + {totalApproved} + + Approved +
+ +
+ + + + {totalRequested} + + Requested +
-
- - - - - - - - - - {#each total_approvals as requested} - - - - +
ActorPermissionStatus
{requested.permission} - {#if accountHasApproved(requested)} - Approved - {:else} - Requested - {/if} -
+ + + + + - {/each} - -
ActorPermissionStatus
- - - -

Multisig Details

- -
- - - - - {proposal.name} - - - {proposal.transaction.expiration} ({relativeTimeToExpiry}) - - - {proposal.hash} - -
- - {#if userIsApprover} - {#if userHasApproved} - - {:else} - + + + {#each total_approvals as requested} + + + {requested.permission} + + {#if accountHasApproved(requested)} + Approved + {:else} + Requested + {/if} + + + {/each} + + +
+ + +

Multisig Details

+ +
+ +
+ +
+
+ +
+ {proposal.name} +
+
+ +
+ {proposal.transaction.expiration} ({relativeTimeToExpiry}) +
+
+ +
+ {proposal.hash} +
+
+
+ + {#if userIsApprover} + {#if userHasApproved} + + {:else} + + {/if} {/if} - {/if} - {#if userIsProposer} - - {/if} + {#if userIsProposer} + + {/if} - -
+ + + - +

Proposed Actions

- {#each proposal.actions as action} - + {#each proposal.transaction.actions as action} + {/each}
- +