Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Styling and UX improvements. #43

Merged
merged 8 commits into from
Aug 15, 2023
Merged
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
5,427 changes: 0 additions & 5,427 deletions last-good.diff

This file was deleted.

1,363 changes: 1,200 additions & 163 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 6 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,22 +24,27 @@
"@sveltejs/adapter-static": "^2.0.2",
"@sveltejs/kit": "1.20.4",
"@sveltejs/vite-plugin-svelte": "^2.4.3",
"@testing-library/svelte": "^4.0.3",
"@tailwindcss/forms": "^0.5.4",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/svelte": "^4.0.3",
"@typescript-eslint/eslint-plugin": "^6.2.1",
"@typescript-eslint/parser": "^6.2.1",
"@vitest/coverage-v8": "^0.34.1",
"@vitest/ui": "^0.34.1",
"@testing-library/user-event": "^14.4.3",
"autoprefixer": "^10.4.14",
"eslint": "^8.46.0",
"eslint-plugin-svelte": "^2.32.4",
"jest": "^29.6.1",
"jest-environment-jsdom": "^29.6.1",
"jsdom": "^22.1.0",
"postcss": "^8.4.27",
"prettier": "^3.0.0",
"prettier-plugin-svelte": "^3.0.3",
"sass": "^1.65.1",
"svelte": "^4.1.1",
"svelte-check": "^3.4.3",
"tailwindcss": "^3.3.3",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.4.8",
Expand Down
6 changes: 6 additions & 0 deletions postcss.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
74 changes: 32 additions & 42 deletions src/components/AddControlKey.svelte
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
<script lang="ts">
import {dotApi, storeConnected, storeCurrentAction, transactionSigningAddress} from '$lib/stores';
import type {ApiPromise} from '@polkadot/api';
import {submitAddControlKey} from '$lib/connections';
import {ActionForms, defaultDotApi} from '$lib/storeTypes';
import { dotApi, storeConnected, storeCurrentAction, transactionSigningAddress } from '$lib/stores';
import type { ApiPromise } from '@polkadot/api';
import { submitAddControlKey } from '$lib/connections';
import { ActionForms, defaultDotApi } from '$lib/storeTypes';
import KeySelection from './KeySelection.svelte';
import {onMount} from 'svelte';
import {isFunction} from '@polkadot/util';
import {isLocalhost} from '$lib/utils';
import { onMount } from 'svelte';
import { isFunction } from '@polkadot/util';
import { isLocalhost } from '$lib/utils';
import TransactionStatus from './TransactionStatus.svelte';

let connected = false;
Expand All @@ -17,8 +17,7 @@
let web3FromSource;
let web3Enable;
let showTransactionStatus = false;
let txnFinished = () => {
};
let txnFinished = () => {};
export let txnStatuses: Array<string> = [];
export let cancelAction;

Expand Down Expand Up @@ -49,6 +48,7 @@
let endpointURI: string = thisDotApi.selectedEndpoint || '';
if (selectedKeyToAdd === '') {
alert('Please choose a key to add.');
} else {
let newKeys = validAccounts[selectedKeyToAdd];
let signingKeys = validAccounts[signingAddress];
showTransactionStatus = true;
Expand Down Expand Up @@ -91,45 +91,35 @@
};
</script>

<div id="add-control-key" class:hidden={!(connected && showSelf)}>
<h3>Add a Control Key to Provider Id {providerId}</h3>
<div class="directions">
<p><strong>Directions</strong></p>
<ol>
<li>
Ensure the new control key has a FRQCY balance if you intend to use it for submitting FRQCY or Capacity
transactions.
</li>
<li>If using a wallet, ensure the new control key is imported into your wallet.</li>
<li>Select the new control key from the dropdown list below.</li>
<li>Click 'Add It.'</li>
<li>This will require 3 signatures: two for the authorization payload, and one to send the transaction.</li>
<ul>
<li>Sign with the new control key</li>
<li>Sign with the current control key</li>
<li>Sign the transaction with the current control key</li>
</ul>
</ol>
</div>
<div id="add-control-key" class:hidden={!(connected && showSelf)} class="action-card basis-40">
<h3 class="font-semibold text-lg">
Add a Control Key to Provider Id {providerId}
</h3>
<ol class="list-decimal ml-8">
<li>
Ensure the new control key has a FRQCY balance if you intend to use it for submitting FRQCY or Capacity
transactions.
</li>
<li>If using a wallet, ensure the new control key is imported into your wallet.</li>
<li>Select the new control key from the dropdown list below.</li>
<li>Click 'Add It.'</li>
<li>This will require 3 signatures: two for the authorization payload, and one to send the transaction.</li>
<ul>
<li>Sign with the new control key</li>
<li>Sign with the current control key</li>
<li>Sign the transaction with the current control key</li>
</ul>
</ol>
<form>
<KeySelection
component="AddControlKey"
selectLabel="Key to Add"
bind:selectedOption={selectedKeyToAdd}
{validAccounts}
classOverrides="border-silver border-2 rounded-lg"
/>
<button on:click|preventDefault={addControlKey}>Add It</button>
<button on:click|preventDefault={cancelAction}>Cancel Add</button>
<TransactionStatus bind:showSelf={showTransactionStatus} statuses={txnStatuses}/>
<button on:click|preventDefault={addControlKey} class="btn-primary text-black"> Add It </button>
<button on:click|preventDefault={cancelAction} class="btn-cancel text-black"> Cancel Add </button>
</form>
</div>

<style>
.directions {
font-size: small;
}

.directions li {
line-height: 1.1em;
}
</style>
<TransactionStatus bind:showSelf={showTransactionStatus} statuses={txnStatuses} />
46 changes: 31 additions & 15 deletions src/components/Capacity.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@
import type { ApiPromise } from '@polkadot/api';
import type { MsaInfo } from '$lib/storeTypes';
import { getMsaEpochAndCapacityInfo } from '$lib/polkadotApi';
import { providerNameToHuman } from '$lib/utils';
import { balanceToHuman } from '$lib/utils.js';

let signingAddress = ''; // eslint-disable-line no-unused-vars
let epochNumber = 0n;
let connected;
storeConnected.subscribe((val) => (connected = val));

let msaInfo: MsaInfo = { isProvider: false, msaId: 0, providerName: '' };
storeMsaInfo.subscribe((info: MsaInfo) => (msaInfo = info));
storeMsaInfo.subscribe((info: MsaInfo) => {
msaInfo = info;
});

storeConnected.subscribe((val) => (connected = val));
let apiPromise: ApiPromise | undefined;
Expand All @@ -18,6 +24,10 @@
apiPromise = api.api;
}
});
let blockNumber = 0n;
storeBlockNumber.subscribe((val) => (blockNumber = val));

export let token;

type CapacityDetails = {
remainingCapacity: bigint;
Expand All @@ -34,11 +44,6 @@

let capacityDetails: CapacityDetails = defaultDetails;

let signingAddress = ''; // eslint-disable-line no-unused-vars
let epochNumber = 0n;
let blockNumber = 0n;
storeBlockNumber.subscribe((val) => (blockNumber = val));

transactionSigningAddress.subscribe(async (addr) => {
// first set/reset all our local values.
signingAddress = addr;
Expand All @@ -49,20 +54,31 @@
}
if (connected && apiPromise?.query && addr) {
let info = await getMsaEpochAndCapacityInfo(apiPromise, addr);
msaInfo = { ...msaInfo, ...info.msaInfo };
if (info?.msaInfo) {
msaInfo.providerName = providerNameToHuman(info.msaInfo.providerName);
}
msaInfo.msaId = info?.msaInfo?.msaId || 0;
msaInfo.isProvider = info?.msaInfo?.isProvider || false;
capacityDetails = { ...defaultDetails, ...info.capacityDetails };
epochNumber = info.epochNumber;
storeMsaInfo.set(msaInfo);
}
});
export let token;
</script>

<div class:hidden={!msaInfo.isProvider}>
<h3>Capacity at Block {blockNumber}, Epoch {epochNumber}</h3>
<p>Provider name: {msaInfo.providerName}</p>
<p><strong>Remaining:</strong> {capacityDetails?.remainingCapacity}</p>
<p><strong>Total Issued:</strong> {capacityDetails?.totalCapacityIssued}</p>
<p><strong>Last replenished:</strong> Epoch {capacityDetails?.lastReplenishedEpoch}</p>
<p><strong>Staked Token:</strong> {capacityDetails?.totalCapacityIssued} {token}</p>
<div class="pl-6 ml-6 border-l-8 border-aqua">
<h3 class="text-aqua font-bold">Capacity</h3>
{#if !connected}
<p>Not connected</p>
Copy link
Collaborator Author

@shannonwells shannonwells Aug 14, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All the "status" items at the top now display more or less the same information until you are connected and we know if you are a Provider or you just have an MSA.

{:else if msaInfo.isProvider}
<h3 class="text-aqua font-bold">As of Block {blockNumber}, Epoch {epochNumber}</h3>
<p>Remaining: {balanceToHuman(capacityDetails?.remainingCapacity, 'CAP')}</p>
<p>Total Issued: {balanceToHuman(capacityDetails?.totalCapacityIssued, 'CAP')}</p>
<p>Last Replenished: Epoch {capacityDetails?.lastReplenishedEpoch}</p>
<p>Staked Token: {balanceToHuman(capacityDetails?.totalCapacityIssued, token)}</p>
{:else if signingAddress == ''}
<p>No transaction signing address selected</p>
{:else}
<p>Not a provider</p>
{/if}
</div>
99 changes: 55 additions & 44 deletions src/components/Connect.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -70,72 +70,83 @@
}
return;
}
let networkQuestion = "What's the difference between Mainnet and Testnet (Rococo)?";
</script>

<a
id="here"
href="#here"
on:click|preventDefault={toggleExplain}
on:keydown|preventDefault={toggleExplain}
class:hidden={showExplainer}
class="explainer-text">{networkQuestion}</a
>
<div class:hidden={!showExplainer}>
<p>The main purpose of the Mainnet is to run the actual blockchain network.</p>
<h3 class="text-lg pt-8 underline cursor-pointer font-bold">
<a id="here" href="#here" on:click|preventDefault={toggleExplain} on:keydown|preventDefault={toggleExplain}
>What's the difference between Mainnet and Testnet (Rococo)?</a
>
</h3>
<div class:hidden={!showExplainer} class="pt-4">
<p>The Frequency Mainnet is the production Frequency blockchain network.</p>
<p>
The Testnet, which works with the Rococo Polkadot Testnet, is designed for developers to test and debug their
The Frequency Rococo Testnet, which works with the Polkadot Rococo Testnet, is for developers to test and debug
applications without risking real assets.
</p>
<p><strong>What about the other options?</strong></p>
<p>If you need to connect a node running development code locally, choose Localhost.</p>
<h3 class="text-lg pt-4 pb-2">
<strong>What about the other options?</strong>
</h3>
<p>To connect to a node running on your desktop, choose <span class="font-bold text-aqua">Localhost.</span></p>
<p>
If you need to connect to a node that is not in the list, choose Other, then type the WebSocket address in the text
field.
To connect to a node that is not in the list, choose <span class="font-bold text-aqua">Other</span>, then type the
desired WebSocket address in the text field.
</p>
<button on:click={toggleExplain} on:keydown={toggleExplain}>Thanks.</button>
<button on:click={toggleExplain} on:keydown={toggleExplain} class="btn-secondary">Okay</button>
</div>
<label for="provider-list">1. Select a Network</label>
<select id="provider-list" required bind:value={selectedProvider}>
{#each Object.keys(ProviderMap) as providerName}
<option value={providerName}>{providerName}: {ProviderMap[providerName]}</option>
{/each}
</select>

<input
type="text"
id="other-endpoint-url"
placeholder="wss://some.frequency.node"
bind:value={otherProvider}
disabled={selectedProvider.toString() != 'Other'}
/>
<div class={connected ? '' : 'hidden'}>
<div class="pt-8">
<h3 class="text-lg"><label for="provider-list">Select a Network</label></h3>
<select
id="provider-list"
required
bind:value={selectedProvider}
class="text-left bg-green5 pr-8 pl-4 py-2 rounded-md border-0"
>
{#each Object.keys(ProviderMap) as providerName}
<option value={providerName} class="bg-base">{providerName}: {ProviderMap[providerName]}</option>
{/each}
</select>
<input
type="text"
id="other-endpoint-url"
placeholder="wss://some.frequency.node"
bind:value={otherProvider}
disabled={selectedProvider.toString() != 'Other'}
class:hidden={selectedProvider.toString() != 'Other'}
class="w-80 rounded-md"
/>
<button
on:click|preventDefault={async () => await connect()}
id="connect-button"
hidden={!canConnect}
class="btn-primary"
>
Connect to {selectedProvider}
</button>
</div>
<div class:hidden={connected} class="pt-8 color-inherit">
<div hidden={selectedProvider !== 'Rococo' || !showFaucetInstructions}>
<p>
<p class="pl-8 color-inherit">
To transact on Frequency as a provider you will need frequency utility tokens. On Frequency testnet, you can get
tokens from the Testnet Faucet. To do that:
</p>
<ol>
<ol class="list-disc pl-12">
<li>
Go to <a href="https://faucet.rococo.frequency.xyz/" target="_blank">
to get XRQCY tokens for Frequency Testnet (Rococo)
<a href="https://faucet.rococo.frequency.xyz/" target="_blank" class="underline">
Get XRQCY tokens for Frequency Testnet (Rococo)
</a> and follow the instructions using your desired wallet address to get XRQCY tokens.
</li>
<li>
Once that succeeds, verify the tokens have made it to your wallet by selecting or re-selecting the address
above. You may need to wait a minute.
</li>
<li>
For more information, you can also visit the <a href="https://cloudflare-ipfs.com/ipns/dotapps.io/#/accounts"
>Rococo Accounts page via the Polkadot UI</a
>.
For more information, you can also visit the
<a href="https://cloudflare-ipfs.com/ipns/dotapps.io/#/accounts" class="underline">
Rococo Accounts page via the Polkadot UI.
</a>
</li>
</ol>
<button on:click|preventDefault={toggleFaucetInstructions}>I have token</button>
<button on:click|preventDefault={toggleFaucetInstructions} class="btn-secondary ml-8"> I have token</button>
</div>
</div>
<div>
<button on:click|preventDefault={async () => await connect()} id="connect-button" hidden={!canConnect}>
Connect to {selectedProvider}
</button>
</div>
12 changes: 12 additions & 0 deletions src/components/ConnectionStatus.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<script lang="ts">
export let connected = false;
export let token = '';
export let blockNumber = 0n;
</script>

<div id="connection-status" class="pr-4 border-aqua">
<h3 class="text-aqua font-bold">Connection status</h3>
<p>{connected ? 'Connected' : 'Not connected'}</p>
<p class:hidden={!connected}>Token: <span id="unit">{token}</span></p>
<p class:hidden={!connected}>Current block number: <span id="current-block">{blockNumber}</span></p>
</div>
15 changes: 8 additions & 7 deletions src/components/CreateProvider.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -83,21 +83,22 @@
const clearTxnStatuses = () => (txnStatuses = new Array<string>());
</script>

<div id="create-provider">
<h2>Become a Provider</h2>
<p>
<div id="create-provider" class="action-card">
<p class="text-black">
For developer and testing convenience, on Testnet, anyone with an MSA who wishes to become a Provider may simply
submit a <code>createProvider</code> transaction.
</p>
<p>
<p class="text-black">
This action will register the MSA Id that is controlled by the selected Transaction Signing Address above. Any
control key for the MSA Id can submit the transaction.
</p>
<form>
<label for="providerNameCB">Provider name</label>
<input id="providerNameCB" required placeholder="Short name" maxlength="" bind:value={newProviderName} />
<button id="create-provider-btn" on:click|preventDefault={doCreateProvider}>Create Provider</button>
<button on:click|preventDefault={cancelAction}>Cancel</button>
<button id="create-provider-btn" on:click|preventDefault={doCreateProvider} class="btn-primary text-black">
Create Provider
</button>
<button on:click|preventDefault={cancelAction} class="btn-cancel text-black">Cancel</button>
</form>
<TransactionStatus bind:showSelf={showTransactionStatus} statuses={txnStatuses} />
</div>
<TransactionStatus bind:showSelf={showTransactionStatus} statuses={txnStatuses} />
Loading