diff --git a/README.md b/README.md index 7a4bde245ba0..35f026346b2b 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,20 @@ -[![polkadotjs](https://img.shields.io/badge/polkadot-js-orange?style=flat-square)](https://polkadot.js.org) -![license](https://img.shields.io/badge/License-Apache%202.0-blue?logo=apache&style=flat-square) -[![npm](https://img.shields.io/npm/v/@polkadot/apps?logo=npm&style=flat-square)](https://www.npmjs.com/package/@polkadot/apps) -[![beta](https://img.shields.io/npm/v/@polkadot/apps/beta?label=beta&logo=npm&style=flat-square)](https://www.npmjs.com/package/@polkadot/apps) -[![maintainability](https://img.shields.io/codeclimate/maintainability-percentage/polkadot-js/apps?logo=code-climate&style=flat-square)](https://codeclimate.com/github/polkadot-js/apps) +# Plasm-apps -# @polkadot/apps +forked by: [polkadot-js/apps](https://github.com/polkadot-js/apps) -A Portal into the Polkadot and Substrate networks. Provides a view and interaction layer from a browser. +## How to Run -This can be accessed as a hosted application via [https://polkadot.js.org/apps/](https://polkadot.js.org/apps/) to explorer any of the supported Polkadot and Substrate chains +``` +yarn install +yarn run start +``` + + +# @plasm/apps + +A Portal into the Plasm networks. Provides a view and interaction layer from a browser. + +This will be accessed as a hosted application via [Comming Soon]() to explorer any of the supported Plasm chains. ## overview @@ -17,7 +23,6 @@ The repo is split into a number of packages, each representing an application. T - [apps](packages/apps/) This is the main entry point. It handles the selection sidebar and routing to the specific application being displayed. - [app-accounts](packages/app-accounts/) A basic account management app. - [app-address-book](packages/app-address-book/) A basic address management app. -- [app-democracy](packages/app-democracy/) A basic voting app, allowing votes on activate proposals and referenda. - [app-explorer](packages/app-explorer/) A simple block explorer. It only shows the most recent blocks, updating as they become available. - [app-extrinsics](packages/app-extrinsics/) Submission of extrinsics to a node. - [app-js](packages/app-js/) An online code editor with [@polkadot-js/api](https://github.com/polkadot-js/api/tree/master/packages/api) access to the currently connected node. @@ -25,7 +30,7 @@ The repo is split into a number of packages, each representing an application. T - [app-staking](packages/app-staking/) A basic staking management app, allowing staking and nominations. - [app-storage](packages/app-storage/) A simple node storage query application. Multiple queries can be queued and updates as new values become available. - [app-toolbox](packages/app-toolbox/) Submission of raw data to RPC endpoints and utility hashing functions. -- [app-transfer](packages/app-transfer/) A basic account management app, allowing transfer of Units/DOTs between accounts. +- [app-transfer](packages/app-transfer/) A basic account management app, allowing transfer of PRMs between accounts. In addition the following libraries are also included in the repo. These are to be moved to the [@polkadot/ui](https://github.com/polkadot-js/ui/) repository once it reaches a base level of stability and usability. (At this point with the framework being tested on the apps above, it makes development easier having it close) @@ -41,7 +46,7 @@ To start off, this repo (along with others in the [@polkadot](https://github.com To get started - -1. Clone the repo locally, via `git clone https://github.com/polkadot-js/apps ` +1. Clone the repo locally, via `git clone https://github.com/stakedtechnologies/apps ` 2. Ensure that you have a recent LTS version of Node.js, for development purposes [Node >=10.13.0](https://nodejs.org/en/) is recommended. 3. Ensure that you have a recent version of Yarn, for development purposes [Yarn >=1.10.1](https://yarnpkg.com/docs/install) is required. 4. Install the dependencies by running `yarn` @@ -58,12 +63,4 @@ Be sure to follow the [app-123code/README.md](packages/app-123code/README.md) in ## Docker -You can run a docker container via - - - docker run --rm -it --name polkadot-ui -p 80:80 chevdor/polkadot-ui:latest - -To build a docker container containing local changes - - - docker build -t chevdor/polkadot-ui:latest . - -When using these Docker commands, you can access the UI via http://localhost:80 (or just http://localhost) +Comming soon. \ No newline at end of file diff --git a/lerna.json b/lerna.json index 7b2fb99ca1ed..a88c5b7ef089 100644 --- a/lerna.json +++ b/lerna.json @@ -10,5 +10,5 @@ "packages": [ "packages/*" ], - "version": "0.37.0-beta.65" + "version": "0.37.0-beta.72" } diff --git a/package.json b/package.json index 3c68c4e5c763..f3b92fce4a67 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "private": true, "engines": { "node": ">=10.13.0", diff --git a/packages/app-123code/package.json b/packages/app-123code/package.json index e5287e8eb2e2..67d850e19d71 100644 --- a/packages/app-123code/package.json +++ b/packages/app-123code/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-123code", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "A basic app that shows the ropes on customisation", "main": "index.js", "scripts": {}, @@ -11,6 +11,6 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72" } } diff --git a/packages/app-accounts/package.json b/packages/app-accounts/package.json index 6c436f56c601..a382a9dc4b47 100644 --- a/packages/app-accounts/package.json +++ b/packages/app-accounts/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-accounts", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65", + "@polkadot/react-components": "^0.37.0-beta.72", "@polkadot/react-qr": "^0.47.0-beta.5", "@types/file-saver": "^2.0.0", "@types/yargs": "^13.0.2", diff --git a/packages/app-accounts/src/Vanity/index.tsx b/packages/app-accounts/src/Vanity/index.tsx index 742d2a5d0b06..c55f4c739d12 100644 --- a/packages/app-accounts/src/Vanity/index.tsx +++ b/packages/app-accounts/src/Vanity/index.tsx @@ -10,7 +10,7 @@ import { ComponentProps } from '../types'; import React from 'react'; import styled from 'styled-components'; import { Button, Dropdown, Input, TxComponent } from '@polkadot/react-components'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; import CreateModal from '../modals/Create'; import generator from '../vanitygen'; @@ -237,7 +237,7 @@ class VanityApp extends TxComponent { return; } - setTimeout((): void => { + setImmediate((): void => { if (this._isActive) { if (this.results.length === 25) { this.checkMatches(); @@ -257,7 +257,7 @@ class VanityApp extends TxComponent { this.executeGeneration(); } - }, 0); + }); } private onCreateToggle = (createSeed: string): void => { diff --git a/packages/app-accounts/src/modals/Create.tsx b/packages/app-accounts/src/modals/Create.tsx index d8239e5127aa..b6f086ef9860 100644 --- a/packages/app-accounts/src/modals/Create.tsx +++ b/packages/app-accounts/src/modals/Create.tsx @@ -15,7 +15,7 @@ import { DEV_PHRASE } from '@polkadot/keyring/defaults'; import { ApiContext } from '@polkadot/react-api'; import { AddressRow, Button, Dropdown, Input, InputAddress, Modal, Password } from '@polkadot/react-components'; import keyring from '@polkadot/ui-keyring'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; import { isHex, u8aToHex } from '@polkadot/util'; import { keyExtractSuri, mnemonicGenerate, mnemonicValidate, randomAsU8a } from '@polkadot/util-crypto'; diff --git a/packages/app-accounts/src/modals/Transfer.tsx b/packages/app-accounts/src/modals/Transfer.tsx index b0ffc9bb4758..3ce8f8bc6111 100644 --- a/packages/app-accounts/src/modals/Transfer.tsx +++ b/packages/app-accounts/src/modals/Transfer.tsx @@ -84,7 +84,7 @@ function Transfer ({ className, onClose, recipientId: propRecipientId, senderId: } }, [amount, recipientId, senderId]); - const transferrable = {t('transferrable ')}; + const transferrable = {t('transferrable')}; return ( ", @@ -11,6 +11,6 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72" } } diff --git a/packages/app-claims/package.json b/packages/app-claims/package.json index 47bda462ca3f..187981455c40 100644 --- a/packages/app-claims/package.json +++ b/packages/app-claims/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-claims", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "An app for claiming Polkadot tokens", "main": "index.js", "scripts": {}, @@ -12,6 +12,6 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72" } } diff --git a/packages/app-claims/src/Claim.tsx b/packages/app-claims/src/Claim.tsx index 7e46c5fff9e3..f598d3425b45 100644 --- a/packages/app-claims/src/Claim.tsx +++ b/packages/app-claims/src/Claim.tsx @@ -10,7 +10,7 @@ import React, { useContext, useEffect, useState } from 'react'; import styled from 'styled-components'; import { ApiContext } from '@polkadot/react-api'; import { Button, Card } from '@polkadot/react-components'; -import { formatBalance } from '@polkadot/util'; +import { FormatBalance } from '@polkadot/react-query'; import translate from './translate'; import { addrToChecksum } from './util'; @@ -63,7 +63,7 @@ function Claim ({ button, className, ethereumAddress, t }: Props): React.ReactEl ? ( <> {t('has a valid claim for')} -

{formatBalance(claimValue)}

+

{button} ) diff --git a/packages/app-claims/src/index.tsx b/packages/app-claims/src/index.tsx index ff0789278463..6d4fa9c6c070 100644 --- a/packages/app-claims/src/index.tsx +++ b/packages/app-claims/src/index.tsx @@ -14,7 +14,7 @@ import styled from 'styled-components'; import CopyToClipboard from 'react-copy-to-clipboard'; import { withApi, withMulti } from '@polkadot/react-api'; import { Button, Card, Columar, Column, InputAddress, Tooltip } from '@polkadot/react-components'; -import { InputNumber } from '@polkadot/react-components/InputNumber'; +import { TokenUnit } from '@polkadot/react-components/InputNumber'; import TxModal, { TxModalState, TxModalProps } from '@polkadot/react-components/TxModal'; import { u8aToHex, u8aToString } from '@polkadot/util'; import { decodeAddress } from '@polkadot/util-crypto'; @@ -112,7 +112,7 @@ class App extends TxModal {

- claim your {InputNumber.units} tokens + claim your {TokenUnit.abbr} tokens

diff --git a/packages/app-contracts/package.json b/packages/app-contracts/package.json index f23ba539c573..8efabf400591 100644 --- a/packages/app-contracts/package.json +++ b/packages/app-contracts/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-contracts", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "Deployment and management of substrate contracts", "main": "index.js", "scripts": {}, @@ -12,6 +12,6 @@ "dependencies": { "@babel/runtime": "^7.7.1", "@polkadot/api-contract": "^0.97.0-beta.2", - "@polkadot/react-components": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72" } } diff --git a/packages/app-contracts/src/Contracts/Call.tsx b/packages/app-contracts/src/Contracts/Call.tsx index 09fe72e10e0d..794320e40835 100644 --- a/packages/app-contracts/src/Contracts/Call.tsx +++ b/packages/app-contracts/src/Contracts/Call.tsx @@ -167,6 +167,7 @@ function Call (props: Props): React.ReactElement | null { help={t('The allotted value for this contract, i.e. the amount transferred to the contract as part of this call.')} isDisabled={isBusy} isError={!isEndowmentValid} + isZeroable label={t('value')} onChange={_onChangeEndowment} value={endowment} diff --git a/packages/app-contracts/src/Deploy.tsx b/packages/app-contracts/src/Deploy.tsx index 7ec70be5f200..bbee4ff42c8f 100644 --- a/packages/app-contracts/src/Deploy.tsx +++ b/packages/app-contracts/src/Deploy.tsx @@ -21,7 +21,7 @@ import ContractModal, { ContractModalProps, ContractModalState } from './Modal'; import Params from './Params'; import store from './store'; import translate from './translate'; -import { GAS_LIMIT } from './constants'; +import { ENDOWMENT, GAS_LIMIT } from './constants'; type ConstructOptions = { key: string; text: React.ReactNode; value: string }[]; @@ -51,7 +51,7 @@ class Deploy extends ContractModal { ...this.defaultState, constructorIndex: -1, constructOptions: [], - endowment: new BN(0), + endowment: new BN(ENDOWMENT), gasLimit: new BN(GAS_LIMIT), isHashValid: false, params: [], @@ -182,7 +182,7 @@ class Deploy extends ContractModal { } + isTooltip + type='runnerup' + /> + )} value={address} withIndexOrAddress > diff --git a/packages/app-council/src/Overview/Member.tsx b/packages/app-council/src/Overview/Member.tsx index a4e19eb5f9ca..e75d822fd77f 100644 --- a/packages/app-council/src/Overview/Member.tsx +++ b/packages/app-council/src/Overview/Member.tsx @@ -6,7 +6,7 @@ import { I18nProps } from '@polkadot/react-components/types'; import { AccountId } from '@polkadot/types/interfaces'; import React from 'react'; -import { AddressCard } from '@polkadot/react-components'; +import { AddressCard, Badge, Icon } from '@polkadot/react-components'; import translate from '../translate'; import Voters from './Voters'; @@ -20,6 +20,14 @@ function Member ({ address, t, voters }: Props): React.ReactElement { return ( } + isTooltip + type='selected' + /> + } value={address} withIndexOrAddress > diff --git a/packages/app-council/src/Overview/Summary.tsx b/packages/app-council/src/Overview/Summary.tsx index b47cc67797df..c9a63aec4989 100644 --- a/packages/app-council/src/Overview/Summary.tsx +++ b/packages/app-council/src/Overview/Summary.tsx @@ -24,8 +24,11 @@ function Summary ({ bestNumber, electionsInfo: { members, candidateCount, desire {formatNumber(members.length)}/{formatNumber(desiredSeats)} + + {formatNumber(runnersUp.length)} + - {formatNumber(candidateCount.addn(runnersUp.length))} + {formatNumber(candidateCount)} {voteCount && ( diff --git a/packages/app-council/src/Overview/Vote.tsx b/packages/app-council/src/Overview/Vote.tsx index f6916a41092d..4abe55b82ebe 100644 --- a/packages/app-council/src/Overview/Vote.tsx +++ b/packages/app-council/src/Overview/Vote.tsx @@ -13,12 +13,14 @@ import React from 'react'; import styled from 'styled-components'; import { createType } from '@polkadot/types'; import { withCalls, withMulti } from '@polkadot/react-api'; -import { AddressRow, Button, Toggle } from '@polkadot/react-components'; +import { AddressMini, Button, Toggle } from '@polkadot/react-components'; import TxModal, { TxModalState, TxModalProps } from '@polkadot/react-components/TxModal'; import translate from '../translate'; import VoteValue from './VoteValue'; +type VoteType = 'member' | 'runnerup' | 'candidate'; + interface Props extends ApiProps, ComponentProps, TxModalProps { voterPositions?: DerivedVoterPositions; } @@ -29,6 +31,8 @@ interface State extends TxModalState { // voterPositions: DerivedVoterPositions; } +// const MAX_VOTES = 16; + // const AlreadyVoted = styled.article` // display: flex; // align-items: center; @@ -46,37 +50,47 @@ interface State extends TxModalState { const Candidates = styled.div` display: flex; flex-wrap: wrap; -`; + justify-content: center; + + .candidate { + border: 1px solid #eee; + border-radius: 0.25rem; + margin: 0.25rem; + padding-bottom: 0.25rem; + padding-right: 0.5rem; + position: relative; + + &::after { + content: ''; + position: absolute; + top: 0; + right: 0; + border-color: transparent; + border-style: solid; + border-radius: 0.25em; + border-width: 0.25em; + } -const Candidate = styled.div` - cursor: pointer; - width: 25rem; - min-width: calc(50% - 1rem); - border-radius: 0.5rem; - border: 1px solid #eee; - padding: 0.75rem 0.5rem 0.25rem; - margin: 0.25rem; - transition: all 0.2s; - - b { - min-width: 5rem; - } + &.isAye { + background: #fff; + border-color: #ccc; + } - &.aye { - background-color: rgba(0, 255, 0, 0.05); + &.member::after { + border-color: green; + } - b { - color: green; + &.runnerup::after { + border-color: steelblue; } - } - &.nay { - background-color: rgba(0, 0, 0, 0.05); - } + .ui--AddressMini-icon { + z-index: 1; + } - .ui--Row-children { - text-align: right; - width: 100%; + .candidate-right { + text-align: right; + } } `; @@ -164,11 +178,11 @@ class Vote extends TxModal { protected renderContent = (): React.ReactNode => { const { api, electionsInfo: { candidates, members, runnersUp }, t } = this.props; const { accountId, votes } = this.state; - const _candidates = candidates.map((accountId): [AccountId, boolean] => [accountId, false]); + const _candidates = candidates.map((accountId): [AccountId, VoteType] => [accountId, 'candidate']); const available = api.tx.electionsPhragmen ? members - .map(([accountId]): [AccountId, boolean] => [accountId, true]) - .concat(runnersUp.map(([accountId]): [AccountId, boolean] => [accountId, false])) + .map(([accountId]): [AccountId, VoteType] => [accountId, 'member']) + .concat(runnersUp.map(([accountId]): [AccountId, VoteType] => [accountId, 'runnerup'])) .concat(_candidates) : _candidates; @@ -200,21 +214,17 @@ class Vote extends TxModal { )} */} - {available.map(([accountId, isMember]): React.ReactNode => { + {available.map(([accountId, type]): React.ReactNode => { const key = accountId.toString(); const isAye = votes[key] || false; return ( - - +
{ onChange={this.onChangeVote(key)} value={isAye} /> - - +
+ ); })}
diff --git a/packages/app-council/src/Overview/VoteValue.tsx b/packages/app-council/src/Overview/VoteValue.tsx index ddb8d19e6183..031450de0c99 100644 --- a/packages/app-council/src/Overview/VoteValue.tsx +++ b/packages/app-council/src/Overview/VoteValue.tsx @@ -29,7 +29,7 @@ function VoteValue ({ accountId, onChange, t }: Props): React.ReactElement} + labelExtra={{t('voting balance')}} params={accountId} />} onChange={_setVoteValue} /> ); diff --git a/packages/app-dashboard/package.json b/packages/app-dashboard/package.json index 57e86a04f143..7ef0aaf596b6 100644 --- a/packages/app-dashboard/package.json +++ b/packages/app-dashboard/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-dashboard", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "Dashboard for all apps, allowing for an overview and quick navigation", "main": "index.js", "scripts": {}, @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/apps-routing": "^0.37.0-beta.65", - "@polkadot/react-components": "^0.37.0-beta.65" + "@polkadot/apps-routing": "^0.37.0-beta.72", + "@polkadot/react-components": "^0.37.0-beta.72" } } diff --git a/packages/app-democracy/package.json b/packages/app-democracy/package.json index 8c5e72bec559..20d41b5c8a84 100644 --- a/packages/app-democracy/package.json +++ b/packages/app-democracy/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-democracy", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "A referendum & proposal app", "main": "index.js", "scripts": {}, @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65", - "@polkadot/react-query": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72", + "@polkadot/react-query": "^0.37.0-beta.72" } } diff --git a/packages/app-democracy/src/Overview/Proposal.tsx b/packages/app-democracy/src/Overview/Proposal.tsx index 22196daf8ab4..b40d6a2f4d70 100644 --- a/packages/app-democracy/src/Overview/Proposal.tsx +++ b/packages/app-democracy/src/Overview/Proposal.tsx @@ -11,7 +11,7 @@ import React from 'react'; import { Option, Tuple, Vec } from '@polkadot/types'; import { ActionItem, InputAddress, Labelled, Static } from '@polkadot/react-components'; import { withCalls, withMulti } from '@polkadot/react-api'; -import { formatBalance } from '@polkadot/util'; +import { FormatBalance } from '@polkadot/react-query'; import translate from '../translate'; import Seconding from './Seconding'; @@ -42,7 +42,7 @@ function renderProposal ({ democracy_depositOf, t }: Props): React.ReactNode { ))} - {formatBalance(balance)} + ); diff --git a/packages/app-democracy/src/Overview/Referendum.tsx b/packages/app-democracy/src/Overview/Referendum.tsx index 4150c6ad6151..bb07af767474 100644 --- a/packages/app-democracy/src/Overview/Referendum.tsx +++ b/packages/app-democracy/src/Overview/Referendum.tsx @@ -104,12 +104,12 @@ function Referendum ({ chain_bestNumber, className, democracy_enactmentPeriod, d values={[ { colors: COLORS_AYE, - label: `Aye, ${formatBalance(votedAye)} (${formatNumber(voteCountAye)})`, + label: `Aye, ${formatBalance(votedAye, { forceUnit: '-' })} (${formatNumber(voteCountAye)})`, value: votedAye.muln(10000).div(votedTotal).toNumber() / 100 }, { colors: COLORS_NAY, - label: `Nay, ${formatBalance(votedNay)} (${formatNumber(voteCountNay)})`, + label: `Nay, ${formatBalance(votedNay, { forceUnit: '-' })} (${formatNumber(voteCountNay)})`, value: votedNay.muln(10000).div(votedTotal).toNumber() / 100 } ]} diff --git a/packages/app-democracy/src/index.tsx b/packages/app-democracy/src/index.tsx index 7b74bdfc3ea1..b0da497aa169 100644 --- a/packages/app-democracy/src/index.tsx +++ b/packages/app-democracy/src/index.tsx @@ -7,7 +7,7 @@ import { AppProps, BareProps, I18nProps } from '@polkadot/react-components/types import React from 'react'; import { Route, Switch } from 'react-router'; import { HelpOverlay, Tabs } from '@polkadot/react-components'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; import basicMd from './md/basic.md'; import Overview from './Overview'; diff --git a/packages/app-explorer/package.json b/packages/app-explorer/package.json index e168c86556f2..50af4fd276c4 100644 --- a/packages/app-explorer/package.json +++ b/packages/app-explorer/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-explorer", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,6 +11,6 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72" } } diff --git a/packages/app-explorer/src/index.tsx b/packages/app-explorer/src/index.tsx index efae407204a8..3c1c3355b64f 100644 --- a/packages/app-explorer/src/index.tsx +++ b/packages/app-explorer/src/index.tsx @@ -11,7 +11,7 @@ import styled from 'styled-components'; import { ApiContext } from '@polkadot/react-api'; import Tabs from '@polkadot/react-components/Tabs'; import { BlockAuthorsContext, EventsContext } from '@polkadot/react-query'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; import BlockInfo from './BlockInfo'; import Forks from './Forks'; diff --git a/packages/app-extrinsics/package.json b/packages/app-extrinsics/package.json index 73f13f9cc3e6..d500db240606 100644 --- a/packages/app-extrinsics/package.json +++ b/packages/app-extrinsics/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-extrinsics", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,8 +11,8 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65", - "@polkadot/react-params": "^0.37.0-beta.65", - "@polkadot/react-signer": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72", + "@polkadot/react-params": "^0.37.0-beta.72", + "@polkadot/react-signer": "^0.37.0-beta.72" } } diff --git a/packages/app-generic-asset/package.json b/packages/app-generic-asset/package.json index a029ccfb05f0..24fb495d457d 100644 --- a/packages/app-generic-asset/package.json +++ b/packages/app-generic-asset/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-generic-asset", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "A basic GenericAsset transfer app", "main": "index.js", "scripts": {}, @@ -11,6 +11,6 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72" } } diff --git a/packages/app-generic-asset/src/Transfer.tsx b/packages/app-generic-asset/src/Transfer.tsx index b67653a018b5..5c171d90a215 100644 --- a/packages/app-generic-asset/src/Transfer.tsx +++ b/packages/app-generic-asset/src/Transfer.tsx @@ -63,7 +63,7 @@ function Transfer ({ assets, className, onClose, recipientId: propRecipientId, s } }; - const transferrable = {t('transferrable ')}; + const transferrable = {t('transferrable')}; return (
diff --git a/packages/app-js/package.json b/packages/app-js/package.json index 2d0844c368c2..d6224f6c224a 100644 --- a/packages/app-js/package.json +++ b/packages/app-js/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-js", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "A simple JavaScript console for playing with the API", "main": "index.js", "scripts": {}, @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65", + "@polkadot/react-components": "^0.37.0-beta.72", "snappyjs": "^0.6.0" } } diff --git a/packages/app-parachains/package.json b/packages/app-parachains/package.json index 7b8bf11d099a..7189aae83fec 100644 --- a/packages/app-parachains/package.json +++ b/packages/app-parachains/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-parachains", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "Parachains", "main": "index.js", "scripts": {}, @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65", - "@polkadot/react-query": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72", + "@polkadot/react-query": "^0.37.0-beta.72" } } diff --git a/packages/app-settings/package.json b/packages/app-settings/package.json index d46d92f1125a..cc4e5ac0c983 100644 --- a/packages/app-settings/package.json +++ b/packages/app-settings/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-settings", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "Settings management", "main": "index.js", "scripts": {}, @@ -11,8 +11,8 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65", - "@polkadot/react-query": "^0.37.0-beta.65", + "@polkadot/react-components": "^0.37.0-beta.72", + "@polkadot/react-query": "^0.37.0-beta.72", "query-string": "^6.8.3" } } diff --git a/packages/app-settings/src/General.tsx b/packages/app-settings/src/General.tsx index 7dfd9b4f36e3..25224a6e14f9 100644 --- a/packages/app-settings/src/General.tsx +++ b/packages/app-settings/src/General.tsx @@ -8,7 +8,7 @@ import { Option } from './types'; import React, { useEffect, useState } from 'react'; import { isLedgerCapable } from '@polkadot/react-api'; import { Button, Dropdown } from '@polkadot/react-components'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; import translate from './translate'; import { createIdenticon, createOption, save, saveAndReload } from './util'; diff --git a/packages/app-settings/src/SelectUrl.tsx b/packages/app-settings/src/SelectUrl.tsx index 1dc92970adb7..5f1413705109 100644 --- a/packages/app-settings/src/SelectUrl.tsx +++ b/packages/app-settings/src/SelectUrl.tsx @@ -8,7 +8,7 @@ import { Option } from './types'; import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { Dropdown, Input, Toggle } from '@polkadot/react-components'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; import translate from './translate'; import { createOption } from './util'; diff --git a/packages/app-settings/src/index.tsx b/packages/app-settings/src/index.tsx index 6a0c3992f24f..994d4b7a82e0 100644 --- a/packages/app-settings/src/index.tsx +++ b/packages/app-settings/src/index.tsx @@ -8,7 +8,7 @@ import React from 'react'; import { Route, Switch } from 'react-router'; import { HelpOverlay, Tabs } from '@polkadot/react-components'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; import md from './md/basics.md'; import translate from './translate'; diff --git a/packages/app-settings/src/util.tsx b/packages/app-settings/src/util.tsx index 32372a9cbb59..8dc49f09c0db 100644 --- a/packages/app-settings/src/util.tsx +++ b/packages/app-settings/src/util.tsx @@ -2,12 +2,12 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { SettingsStruct } from '@polkadot/ui-settings/types'; +import { SettingsStruct } from '@plasm/ui-settings/types'; import { Option, SetOption } from './types'; import React from 'react'; import { ChainImg, IdentityIcon } from '@polkadot/react-components'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; export function createOption ({ info, text, value }: SetOption, overrides: string[] = [], override = 'empty'): Option { return { diff --git a/packages/app-staking/package.json b/packages/app-staking/package.json index e6882df5aaba..9bcc56daaec7 100644 --- a/packages/app-staking/package.json +++ b/packages/app-staking/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-staking", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "A basic staking app", "main": "index.js", "scripts": {}, @@ -11,8 +11,8 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/app-explorer": "^0.37.0-beta.65", - "@polkadot/react-components": "^0.37.0-beta.65", - "@polkadot/react-query": "^0.37.0-beta.65" + "@polkadot/app-explorer": "^0.37.0-beta.72", + "@polkadot/react-components": "^0.37.0-beta.72", + "@polkadot/react-query": "^0.37.0-beta.72" } } diff --git a/packages/app-staking/src/Actions/Account/BondExtra.tsx b/packages/app-staking/src/Actions/Account/BondExtra.tsx index 31e5e4622822..55b24ea57629 100644 --- a/packages/app-staking/src/Actions/Account/BondExtra.tsx +++ b/packages/app-staking/src/Actions/Account/BondExtra.tsx @@ -100,7 +100,7 @@ class BondExtra extends TxComponent { private renderContent (): React.ReactNode { const { stashId, systemChain, t } = this.props; const { amountError, maxAdditional, maxBalance } = this.state; - const transferrable = {t('transferrable ')}; + const transferrable = {t('transferrable')}; const isUnsafeChain = detectUnsafe(systemChain); return ( diff --git a/packages/app-staking/src/Actions/Account/Nominate.tsx b/packages/app-staking/src/Actions/Account/Nominate.tsx index fdbc81790ad1..f7669bf62a1f 100644 --- a/packages/app-staking/src/Actions/Account/Nominate.tsx +++ b/packages/app-staking/src/Actions/Account/Nominate.tsx @@ -5,14 +5,16 @@ import { I18nProps } from '@polkadot/react-components/types'; import { KeyringSectionOption } from '@polkadot/ui-keyring/options/types'; -import React, { useState } from 'react'; -import { Button, InputAddress, Modal, TxButton } from '@polkadot/react-components'; +import React, { useEffect, useState } from 'react'; +import store from 'store'; +import styled from 'styled-components'; +import { AddressMini, Button, InputAddress, Modal, Toggle, TxButton } from '@polkadot/react-components'; +import { STORE_FAVS } from '../../constants'; import translate from '../../translate'; interface Props extends I18nProps { controllerId: string; - isOpen: boolean; nominees?: string[]; onClose: () => void; stashId: string; @@ -22,27 +24,52 @@ interface Props extends I18nProps { // We only allow a maximum of 16 nominees, negative to slice const MAX_NOMINEES = -16; -function Nominate ({ controllerId, isOpen, onClose, stashId, stashOptions, t }: Props): React.ReactElement | null { - const [nominees, setNominees] = useState([]); +function Nominate ({ className, controllerId, nominees, onClose, stashId, stashOptions, t }: Props): React.ReactElement | null { + const [favorites] = useState(store.get(STORE_FAVS, [])); + const [next, setNext] = useState(); + const [{ options, shortlist }, setShortlist] = useState<{ options: KeyringSectionOption[]; shortlist: string[] }>({ options: [], shortlist: [] }); - if (!isOpen) { - return null; - } + useEffect((): void => { + if (!next && nominees) { + setNext(nominees); + } + }, [next, nominees]); + + useEffect((): void => { + if (nominees) { + const shortlist = [ + // ensure that the favorite is included in the list of stashes + ...favorites.filter((accountId): boolean => stashOptions.some(({ value }): boolean => value === accountId)), + // make sure the nominee is not in our favorites already + ...nominees.filter((accountId): boolean => !favorites.includes(accountId)) + ]; + + setShortlist({ + options: stashOptions.filter(({ value }): boolean => !shortlist.includes(value as string)), + shortlist + }); + } + }, [favorites, nominees, stashOptions]); const _onChangeNominees = (_nominees: string[]): void => { const newNominees = _nominees.slice(MAX_NOMINEES); if (JSON.stringify(newNominees) !== JSON.stringify(nominees)) { - setNominees(newNominees); + setNext(newNominees); } }; + const _onToggleNominee = (nominee: string): void => + setNext( + (next || []).includes(nominee) + ? (next || []).filter((accountId): boolean => accountId !== nominee) + : [...(next || []), nominee].slice(MAX_NOMINEES) + ); return ( {t('Nominate Validators')} @@ -67,11 +94,39 @@ function Nominate ({ controllerId, isOpen, onClose, stashId, stashOptions, t }: isMultiple label={t('nominate the following addresses')} onChangeMulti={_onChangeNominees} - options={stashOptions} + options={options} placeholder={t('select accounts(s) nominate')} type='account' - value={nominees} + value={next || []} /> + {shortlist.length !== 0 && ( +
+ {shortlist.map((address): React.ReactNode => { + const isAye = next?.includes(address); + const _onChange = (): void => _onToggleNominee(address); + + return ( + +
+ +
+
+ ); + })} +
+ )} @@ -84,10 +139,10 @@ function Nominate ({ controllerId, isOpen, onClose, stashId, stashOptions, t }: { const { stashOptions } = this.props; const { controllerId, isNominateOpen, nominees, stashId } = this.state; - if (!stashId || !controllerId) { + if (!isNominateOpen || !stashId || !controllerId) { return null; } return ( void; points?: Points; recentlyOnline?: DerivedHeartbeats; stakingInfo?: DerivedStaking; @@ -44,7 +46,7 @@ interface StakingState { const WITH_VALIDATOR_PREFS = { validatorPayment: true }; -function Address ({ address, authorsMap, className, defaultName, filter, isElected, lastAuthors, myAccounts, points, recentlyOnline, stakingInfo, t, withNominations = true }: Props): React.ReactElement | null { +function Address ({ address, authorsMap, className, defaultName, filter, isElected, isFavorite, lastAuthors, myAccounts, onFavorite, points, recentlyOnline, stakingInfo, t, withNominations = true }: Props): React.ReactElement | null { const { isSubstrateV2 } = useContext(ApiContext); const [extraInfo, setExtraInfo] = useState<[React.ReactNode, React.ReactNode][] | undefined>(); const [hasActivity, setHasActivity] = useState(true); @@ -120,13 +122,23 @@ function Address ({ address, authorsMap, className, defaultName, filter, isElect const lastBlockNumber = authorsMap[stashId]; const isAuthor = lastAuthors && lastAuthors.includes(stashId); + const _onFavorite = (): void => onFavorite(stashId); return ( - {lastBlockNumber && ( -
#{lastBlockNumber}
+ {isSubstrateV2 && ( +
+ {lastBlockNumber && ( +
#{lastBlockNumber}
+ )} + +
)} {controllerId && (
@@ -200,6 +212,22 @@ function Address ({ address, authorsMap, className, defaultName, filter, isElect export default withMulti( styled(Address)` + .extras { + display: inline-block; + margin-bottom: 0.75rem; + + .favorite { + cursor: pointer; + display: inline-block; + margin-left: 0.5rem; + margin-right: -0.25rem; + + &.isSelected { + color: darkorange; + } + } + } + .blockNumberV1, .blockNumberV2 { border-radius: 0.25rem; @@ -220,7 +248,6 @@ export default withMulti( .blockNumberV2 { display: inline-block; - margin-bottom: 0.75rem; padding: 0.25rem 0; &.isCurrent { @@ -246,7 +273,7 @@ export default withMulti( } .staking--label.controllerSpacer { - margin-top: 2.75rem; + margin-top: 0.5rem; } `, translate, diff --git a/packages/app-staking/src/Overview/CurrentList.tsx b/packages/app-staking/src/Overview/CurrentList.tsx index 1836ae9fbd16..37e3097afb13 100644 --- a/packages/app-staking/src/Overview/CurrentList.tsx +++ b/packages/app-staking/src/Overview/CurrentList.tsx @@ -2,16 +2,18 @@ // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. -import { AccountId } from '@polkadot/types/interfaces'; import { DerivedHeartbeats, DerivedStakingOverview } from '@polkadot/api-derive/types'; import { I18nProps } from '@polkadot/react-components/types'; +import { AccountId, EraPoints, Points } from '@polkadot/types/interfaces'; import { ValidatorFilter } from '../types'; import React, { useContext, useEffect, useState } from 'react'; import { ApiContext } from '@polkadot/react-api'; import { Columar, Column, Dropdown, FilterOverlay } from '@polkadot/react-components'; +import store from 'store'; import keyring from '@polkadot/ui-keyring'; +import { STORE_FAVS } from '../constants'; import translate from '../translate'; import Address from './Address'; @@ -23,53 +25,90 @@ interface Props extends I18nProps { stakingOverview?: DerivedStakingOverview; } -function renderColumn (myAccounts: string[], addresses: AccountId[] | string[], defaultName: string, withOnline: boolean, filter: string, { authorsMap, lastAuthors, recentlyOnline, stakingOverview }: Props, pointIndexes?: number[]): React.ReactNode { - return (addresses as AccountId[]).map((address, index): React.ReactNode => ( -
accountId.eq(address))} - lastAuthors={lastAuthors} - key={address.toString()} - myAccounts={myAccounts} - points={ - stakingOverview && pointIndexes && pointIndexes[index] !== -1 - ? stakingOverview.eraPoints.individual[pointIndexes[index]] - : undefined - } - recentlyOnline={ - withOnline - ? recentlyOnline +type AccountExtend = [string, boolean, boolean, Points?]; + +function filterAccounts (accounts: string[] = [], elected: string[], favorites: string[], without: string[], eraPoints?: EraPoints): AccountExtend[] { + return accounts + .filter((accountId): boolean => !without.includes(accountId as any)) + .sort((a, b): number => { + const isFavA = favorites.includes(a); + const isFavB = favorites.includes(b); + + return isFavA === isFavB + ? 0 + : (isFavA ? -1 : 1); + }) + .map((accountId): AccountExtend => { + const electedIdx = elected.indexOf(accountId); + + return [ + accountId, + elected.includes(accountId), + favorites.includes(accountId), + electedIdx !== -1 + ? eraPoints?.individual[electedIdx] : undefined - } - /> - )); + ]; + }); } -function filterAccounts (list: string[] = [], without: AccountId[] | string[]): string[] { - return list.filter((accountId): boolean => !without.includes(accountId as any)); +function accountsToString (accounts: AccountId[]): string[] { + return accounts.map((accountId): string => accountId.toString()); } -function CurrentList (props: Props): React.ReactElement { +function CurrentList ({ authorsMap, lastAuthors, next, recentlyOnline, stakingOverview, t }: Props): React.ReactElement { const { isSubstrateV2 } = useContext(ApiContext); + const [favorites, setFavorites] = useState(store.get(STORE_FAVS, [])); const [filter, setFilter] = useState('all'); const [myAccounts] = useState(keyring.getAccounts().map(({ address }): string => address)); - const [{ electedFiltered, nextFiltered, pointIndexes }, setFiltered] = useState<{ electedFiltered: string[]; nextFiltered: string[]; pointIndexes: number[] }>({ electedFiltered: [], nextFiltered: [], pointIndexes: [] }); - const { next, stakingOverview, t } = props; + const [{ elected, validators, waiting }, setFiltered] = useState<{ elected: AccountExtend[]; validators: AccountExtend[]; waiting: AccountExtend[] }>({ elected: [], validators: [], waiting: [] }); useEffect((): void => { if (stakingOverview) { - const elected = stakingOverview.currentElected.map((accountId): string => accountId.toString()); + const _elected = accountsToString(stakingOverview.currentElected); + const _validators = accountsToString(stakingOverview.validators); + const validators = filterAccounts(_validators, _elected, favorites, [], stakingOverview.eraPoints); + const elected = isSubstrateV2 ? filterAccounts(_elected, _elected, favorites, _validators) : []; setFiltered({ - electedFiltered: isSubstrateV2 ? filterAccounts(elected, stakingOverview.validators) : [], - nextFiltered: filterAccounts(next, elected), - pointIndexes: stakingOverview.validators.map((validator): number => elected.indexOf(validator.toString())) + elected, + validators, + waiting: filterAccounts(next, [], favorites, _elected) }); } - }, [next, stakingOverview]); + }, [favorites, next, stakingOverview]); + + const _onFavorite = (accountId: string): void => + setFavorites( + store.set( + STORE_FAVS, + favorites.includes(accountId) + ? favorites.filter((thisOne): boolean => thisOne !== accountId) + : [...favorites, accountId] + ) + ); + + const _renderColumn = (addresses: AccountExtend[], defaultName: string, withOnline: boolean): React.ReactNode => + addresses.map(([address, isElected, isFavorite, points]): React.ReactNode => ( +
+ )); return (
@@ -94,16 +133,16 @@ function CurrentList (props: Props): React.ReactElement { emptyText={t('No addresses found')} headerText={t('validators')} > - {stakingOverview && renderColumn(myAccounts, stakingOverview.validators, t('validator'), true, filter, props, pointIndexes)} + {validators.length !== 0 && _renderColumn(validators, t('validator'), true)} - {(electedFiltered.length !== 0 || nextFiltered.length !== 0) && ( + {(elected.length !== 0 || waiting.length !== 0) && ( <> - {renderColumn(myAccounts, electedFiltered, t('intention'), false, filter, props)} - {renderColumn(myAccounts, nextFiltered, t('intention'), false, filter, props)} + {_renderColumn(elected, t('intention'), false)} + {_renderColumn(waiting, t('intention'), false)} )} diff --git a/packages/app-staking/src/Query/Validator.tsx b/packages/app-staking/src/Query/Validator.tsx new file mode 100644 index 000000000000..77a1cf6dd041 --- /dev/null +++ b/packages/app-staking/src/Query/Validator.tsx @@ -0,0 +1,79 @@ +// Copyright 2017-2019 @polkadot/app-staking authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { I18nProps } from '@polkadot/react-components/types'; +import { SessionIndex } from '@polkadot/types/interfaces'; + +import BN from 'bn.js'; +import React, { useEffect, useState } from 'react'; +import { Chart } from '@polkadot/react-components'; +import { withCalls } from '@polkadot/react-api'; +import { formatNumber } from '@polkadot/util'; + +import translate from '../translate'; + +interface Props extends I18nProps { + blockCounts?: BN[]; + className?: string; + currentIndex: SessionIndex; + validatorId: string; +} + +interface Value { + label: string; + value: BN; +} + +function getIndexRange (currentIndex: SessionIndex): BN[] { + const range: BN[] = []; + let thisIndex: BN = currentIndex; + + while (thisIndex.gtn(0) && range.length < 50) { + range.push(thisIndex); + + thisIndex = thisIndex.subn(1); + } + + return range.reverse(); +} + +function Validator ({ blockCounts, className, currentIndex, t }: Props): React.ReactElement { + const [labels, setLabels] = useState([]); + const [values, setValues] = useState([]); + + useEffect((): void => { + setLabels( + getIndexRange(currentIndex).map((index): string => formatNumber(index)) + ); + }, [currentIndex]); + + useEffect((): void => { + if (blockCounts) { + setValues( + blockCounts.map((value, index): Value => ({ + label: labels[index], + value + })) + ); + } + }, [blockCounts, labels]); + + return ( +
+

{t('blocks per session')}

+ +
+ ); +} + +export default translate( + withCalls( + ['query.imOnline.authoredBlocks', { + isMulti: true, + propName: 'blockCounts', + paramPick: ({ currentIndex, validatorId }: Props): [BN, string][] => + getIndexRange(currentIndex).map((index): [BN, string] => [index, validatorId]) + }] + )(Validator) +); diff --git a/packages/app-staking/src/Query/index.tsx b/packages/app-staking/src/Query/index.tsx new file mode 100644 index 000000000000..10436c07eba5 --- /dev/null +++ b/packages/app-staking/src/Query/index.tsx @@ -0,0 +1,37 @@ +// Copyright 2017-2019 @polkadot/app-staking authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { BareProps } from '@polkadot/react-components/types'; +import { ComponentProps } from '../types'; + +import React from 'react'; +import { withRouter, RouteComponentProps } from 'react-router-dom'; + +import Validator from './Validator'; + +interface Props extends BareProps, ComponentProps, RouteComponentProps<{}> { + match: { + isExact: boolean; + params: { + value: string; + }; + path: string; + url: string; + }; +} + +function Query ({ stakingOverview, match: { params: { value } } }: Props): React.ReactElement { + if (!stakingOverview) { + return
loading
; + } + + return ( + + ); +} + +export default withRouter(Query); diff --git a/packages/app-staking/src/constants.ts b/packages/app-staking/src/constants.ts new file mode 100644 index 000000000000..29ddae5e77fd --- /dev/null +++ b/packages/app-staking/src/constants.ts @@ -0,0 +1,5 @@ +// Copyright 2017-2019 @polkadot/app-staking authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +export const STORE_FAVS = 'staking:favorites'; diff --git a/packages/app-staking/src/index.tsx b/packages/app-staking/src/index.tsx index bc4c2f6f430f..3276835a165c 100644 --- a/packages/app-staking/src/index.tsx +++ b/packages/app-staking/src/index.tsx @@ -21,6 +21,7 @@ import accountObservable from '@polkadot/ui-keyring/observable/accounts'; import Accounts from './Actions/Accounts'; import basicMd from './md/basic.md'; import Overview from './Overview'; +import Query from './Query'; import translate from './translate'; interface Props extends AppProps, ApiProps, I18nProps { @@ -80,6 +81,7 @@ function App ({ allAccounts, allStashesAndControllers: [allStashes, allControlle
+
diff --git a/packages/app-staking/src/types.ts b/packages/app-staking/src/types.ts index a98590ab8238..2cf6cf7af7f4 100644 --- a/packages/app-staking/src/types.ts +++ b/packages/app-staking/src/types.ts @@ -4,17 +4,9 @@ import { DerivedFees, DerivedBalances, DerivedHeartbeats, DerivedStakingOverview } from '@polkadot/api-derive/types'; import { SubjectInfo } from '@polkadot/ui-keyring/observable/types'; -import { EraPoints } from '@polkadot/types/interfaces'; -import { u32 } from '@polkadot/types'; export type Nominators = Record; -export interface DerivedStakingOverviewExt { - currentElected: string[]; - eraPointsEarned: EraPoints; - validatorCount: u32; -} - export interface ComponentProps { allAccounts?: SubjectInfo; allControllers: string[]; diff --git a/packages/app-storage/package.json b/packages/app-storage/package.json index 463667621aea..904b96b72191 100644 --- a/packages/app-storage/package.json +++ b/packages/app-storage/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-storage", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65", - "@polkadot/react-params": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72", + "@polkadot/react-params": "^0.37.0-beta.72" } } diff --git a/packages/app-sudo/package.json b/packages/app-sudo/package.json index 97542b6fbfa2..fe8c4823dd60 100644 --- a/packages/app-sudo/package.json +++ b/packages/app-sudo/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-sudo", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "A basic app that shows the ropes on customisation", "main": "index.js", "scripts": {}, @@ -12,6 +12,6 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72" } } diff --git a/packages/app-toolbox/package.json b/packages/app-toolbox/package.json index 8fa896e325ac..068934c612b2 100644 --- a/packages/app-toolbox/package.json +++ b/packages/app-toolbox/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-toolbox", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -11,6 +11,6 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72" } } diff --git a/packages/app-toolbox/src/Verify.tsx b/packages/app-toolbox/src/Verify.tsx index 9d889537e46c..7d3bb4622b58 100644 --- a/packages/app-toolbox/src/Verify.tsx +++ b/packages/app-toolbox/src/Verify.tsx @@ -8,7 +8,7 @@ import { KeypairType } from '@polkadot/util-crypto/types'; import React, { useEffect, useState } from 'react'; import { Dropdown, Icon, Input, InputAddress, Static } from '@polkadot/react-components'; import keyring from '@polkadot/ui-keyring'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; import { isHex } from '@polkadot/util'; import { naclVerify, schnorrkelVerify } from '@polkadot/util-crypto'; import styled from 'styled-components'; diff --git a/packages/app-transfer/package.json b/packages/app-transfer/package.json index e78f52362767..630b6a964256 100644 --- a/packages/app-transfer/package.json +++ b/packages/app-transfer/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-transfer", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "A basic transfer app", "main": "index.js", "scripts": {}, @@ -11,7 +11,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65", - "@polkadot/react-query": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72", + "@polkadot/react-query": "^0.37.0-beta.72" } } diff --git a/packages/app-treasury/package.json b/packages/app-treasury/package.json index 6ca0aa6514c1..7f6241497558 100644 --- a/packages/app-treasury/package.json +++ b/packages/app-treasury/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/app-treasury", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "A referendum & proposal app", "main": "index.js", "scripts": {}, @@ -12,7 +12,7 @@ "license": "Apache-2.0", "dependencies": { "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65", - "@polkadot/react-query": "^0.37.0-beta.65" + "@polkadot/react-components": "^0.37.0-beta.72", + "@polkadot/react-query": "^0.37.0-beta.72" } } diff --git a/packages/app-treasury/src/Overview/Summary.tsx b/packages/app-treasury/src/Overview/Summary.tsx index c218993d4412..392dfa30f8f2 100644 --- a/packages/app-treasury/src/Overview/Summary.tsx +++ b/packages/app-treasury/src/Overview/Summary.tsx @@ -1,4 +1,3 @@ -/* eslint-disable @typescript-eslint/camelcase */ // Copyright 2017-2019 @polkadot/app-democracy authors & contributors // This software may be modified and distributed under the terms // of the Apache-2.0 license. See the LICENSE file for details. @@ -9,34 +8,39 @@ import BN from 'bn.js'; import React from 'react'; import { SummaryBox, CardSummary } from '@polkadot/react-components'; import { withCalls } from '@polkadot/react-api'; -import { formatBalance, formatNumber } from '@polkadot/util'; +import { formatBalance, formatNumber, stringToU8a } from '@polkadot/util'; import translate from '../translate'; +const TREASURY_ACCOUNT = stringToU8a('modlpy/trsry'.padEnd(32, '\0')); + interface Props extends I18nProps { - treasury_proposalCount?: BN; - treasury_approvals?: BN[]; - treasury_pot?: BN; + treasuryBalance?: BN; + approvals?: BN[]; + proposalCount?: BN; + pot?: BN; } -function Summary ({ treasury_proposalCount, treasury_approvals, treasury_pot, t }: Props): React.ReactElement { - const value = treasury_pot && treasury_pot.gtn(0) - ? treasury_pot.toString() - : null; +function Summary ({ treasuryBalance, approvals, proposalCount, pot, t }: Props): React.ReactElement { + const value = treasuryBalance?.gtn(0) + ? treasuryBalance.toString() + : pot?.gtn(0) + ? pot.toString() + : null; return (
- {formatNumber(treasury_proposalCount)} + {formatNumber(proposalCount)} - {treasury_approvals ? treasury_approvals.length : '0'} + {formatNumber(approvals?.length)}
{value && ( - + {formatBalance(value, false)}{formatBalance.calcSi(value).value} )} @@ -47,8 +51,12 @@ function Summary ({ treasury_proposalCount, treasury_approvals, treasury_pot, t export default translate( withCalls( - 'query.treasury.proposalCount', - 'query.treasury.approvals', - 'query.treasury.pot' + ['query.balances.freeBalance', { + params: [TREASURY_ACCOUNT], + propName: 'treasuryBalance' + }], + ['query.treasury.approvals', { propName: 'approvals' }], + ['query.treasury.proposalCount', { propName: 'proposalCount' }], + ['query.treasury.pot', { propName: 'pot' }] )(Summary) ); diff --git a/packages/apps-routing/package.json b/packages/apps-routing/package.json index 78f4cdea30ad..1252b035ca89 100644 --- a/packages/apps-routing/package.json +++ b/packages/apps-routing/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/apps-routing", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", diff --git a/packages/apps-routing/src/index.ts b/packages/apps-routing/src/index.ts index 428775c3ae5d..891263e915c8 100644 --- a/packages/apps-routing/src/index.ts +++ b/packages/apps-routing/src/index.ts @@ -4,7 +4,7 @@ import { Routing, Routes } from './types'; -import appSettings from '@polkadot/ui-settings'; +import appSettings from '@plasm/ui-settings'; import template from './123code'; import accounts from './accounts'; diff --git a/packages/apps/package.json b/packages/apps/package.json index c44e1cff1f12..2a59426d9ba2 100644 --- a/packages/apps/package.json +++ b/packages/apps/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/apps", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "An Apps portal into the Polkadot network", "main": "index.js", "homepage": ".", @@ -14,9 +14,9 @@ "dependencies": { "@babel/polyfill": "^7.7.0", "@babel/runtime": "^7.7.1", - "@polkadot/react-components": "^0.37.0-beta.65", - "@polkadot/react-signer": "^0.37.0-beta.65", - "@polkadot/ui-assets": "^0.47.0-beta.5", + "@polkadot/react-components": "^0.37.0-beta.72", + "@polkadot/react-signer": "^0.37.0-beta.72", + "@plasm/ui-assets": "^0.47.0-beta.5", "query-string": "^6.8.3" } } diff --git a/packages/apps/public/locales/en/app-accounts.json b/packages/apps/public/locales/en/app-accounts.json index 91b5e4b549a7..85f419e644c5 100644 --- a/packages/apps/public/locales/en/app-accounts.json +++ b/packages/apps/public/locales/en/app-accounts.json @@ -90,5 +90,6 @@ "The password to unlock the selected account.": "The password to unlock the selected account.", "derivation path": "derivation path", "//hard/soft": "//hard/soft", - "Unlock": "Unlock" + "Unlock": "Unlock", + "transferrable": "transferrable" } diff --git a/packages/apps/public/locales/en/app-council.json b/packages/apps/public/locales/en/app-council.json index 1692537d0694..fba8f27b313f 100644 --- a/packages/apps/public/locales/en/app-council.json +++ b/packages/apps/public/locales/en/app-council.json @@ -39,5 +39,9 @@ "The amount that is associated with this vote. This value is is locked for the duration of the vote.": "The amount that is associated with this vote. This value is is locked for the duration of the vote.", "vote value": "vote value", "voting balance ": "voting balance ", - "runner up": "runner up" + "runner up": "runner up", + "Runner up": "Runner up", + "Current member": "Current member", + "runners up": "runners up", + "voting balance": "voting balance" } diff --git a/packages/apps/public/locales/en/app-generic-asset.json b/packages/apps/public/locales/en/app-generic-asset.json index 48d9c0ce7825..73d3caecfaff 100644 --- a/packages/apps/public/locales/en/app-generic-asset.json +++ b/packages/apps/public/locales/en/app-generic-asset.json @@ -21,5 +21,6 @@ "Type the amount you want to transfer. Note that you can select the unit on the right e.g sending 1 milli is equivalent to sending 0.001.": "Type the amount you want to transfer. Note that you can select the unit on the right e.g sending 1 milli is equivalent to sending 0.001.", "amount": "amount", "Make Transfer": "Make Transfer", - "transferrable ": "transferrable " + "transferrable ": "transferrable ", + "transferrable": "transferrable" } diff --git a/packages/apps/public/locales/en/app-staking.json b/packages/apps/public/locales/en/app-staking.json index 96811497fe14..78ba90d9e965 100644 --- a/packages/apps/public/locales/en/app-staking.json +++ b/packages/apps/public/locales/en/app-staking.json @@ -94,5 +94,9 @@ "Active with {{blocks}} blocks authored{{hasMessage}} heartbeat message": "Active with {{blocks}} blocks authored{{hasMessage}} heartbeat message", "transferrable ": "transferrable ", "The specified value is greater than your free balance. The node will bond the maximum amount available.": "The specified value is greater than your free balance. The node will bond the maximum amount available.", - "Change session keys": "Change session keys" + "Change session keys": "Change session keys", + "Aye": "Aye", + "Nay": "Nay", + "blocks per session": "blocks per session", + "transferrable": "transferrable" } diff --git a/packages/apps/public/locales/en/app-treasury.json b/packages/apps/public/locales/en/app-treasury.json index f2ddb40dcaa1..1d6d48ab9e43 100644 --- a/packages/apps/public/locales/en/app-treasury.json +++ b/packages/apps/public/locales/en/app-treasury.json @@ -32,5 +32,6 @@ "burn percentage": "burn percentage", "Submit": "Submit", "Pot": "Pot", - "pot size": "pot size" + "pot size": "pot size", + "available": "available" } diff --git a/packages/apps/public/locales/en/ui.json b/packages/apps/public/locales/en/ui.json index 2b2812be299e..ab988bfa08ee 100644 --- a/packages/apps/public/locales/en/ui.json +++ b/packages/apps/public/locales/en/ui.json @@ -609,5 +609,11 @@ "The password to unlock the selected account.": "", "derivation path": "", "//hard/soft": "", - "runner up": "" + "runner up": "", + "Runner up": "", + "Current member": "", + "runners up": "", + "blocks per session": "", + "voting balance": "", + "Max": "" } diff --git a/packages/apps/src/index.tsx b/packages/apps/src/index.tsx index 9c184bfe07a0..cbd79d4979ce 100644 --- a/packages/apps/src/index.tsx +++ b/packages/apps/src/index.tsx @@ -3,7 +3,7 @@ // of the Apache-2.0 license. See the LICENSE file for details. // import first, get the load done -import settings from '@polkadot/ui-settings'; +import settings from '@plasm/ui-settings'; import 'semantic-ui-css/semantic.min.css'; import '@polkadot/react-components/i18n'; diff --git a/packages/apps/src/overlays/Connecting.tsx b/packages/apps/src/overlays/Connecting.tsx index bf27e04846ab..6c4810c0c013 100644 --- a/packages/apps/src/overlays/Connecting.tsx +++ b/packages/apps/src/overlays/Connecting.tsx @@ -8,7 +8,7 @@ import { I18nProps as Props } from '@polkadot/react-components/types'; import React, { useContext } from 'react'; import styled from 'styled-components'; import { ApiContext } from '@polkadot/react-api'; -import settings from '@polkadot/ui-settings'; +import settings from '@plasm/ui-settings'; import translate from '../translate'; import BaseOverlay from './Base'; diff --git a/packages/react-api/package.json b/packages/react-api/package.json index bac3f2b510b6..27bd44d90bc9 100644 --- a/packages/react-api/package.json +++ b/packages/react-api/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/react-api", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "description": "A collection of RxJs React components the Polkadot JS API", "main": "index.js", "keywords": [ diff --git a/packages/react-api/src/Api.tsx b/packages/react-api/src/Api.tsx index 3a9045872a1a..56e770d97630 100644 --- a/packages/react-api/src/Api.tsx +++ b/packages/react-api/src/Api.tsx @@ -11,9 +11,9 @@ import ApiPromise from '@polkadot/api/promise'; import { isWeb3Injected, web3Accounts, web3Enable } from '@polkadot/extension-dapp'; import defaults from '@polkadot/rpc-provider/defaults'; import { WsProvider } from '@polkadot/rpc-provider'; -import { InputNumber } from '@polkadot/react-components/InputNumber'; +import { TokenUnit } from '@polkadot/react-components/InputNumber'; import keyring from '@polkadot/ui-keyring'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; import ApiSigner from '@polkadot/react-signer/ApiSigner'; import { u32 as U32 } from '@polkadot/types'; import { formatBalance, isTestChain } from '@polkadot/util'; @@ -152,7 +152,7 @@ export default class Api extends React.PureComponent { decimals: tokenDecimals, unit: tokenSymbol }); - InputNumber.setUnit(tokenSymbol); + TokenUnit.setAbbr(tokenSymbol); // finally load the keyring keyring.loadAll({ diff --git a/packages/react-api/src/ledger.ts b/packages/react-api/src/ledger.ts index 8553e3d4e213..c29e3c63089b 100644 --- a/packages/react-api/src/ledger.ts +++ b/packages/react-api/src/ledger.ts @@ -3,7 +3,7 @@ // of the Apache-2.0 license. See the LICENSE file for details. import { Ledger } from '@polkadot/ui-keyring'; -import uiSettings from '@polkadot/ui-settings'; +import uiSettings from '@plasm/ui-settings'; import { api } from './Api'; diff --git a/packages/react-api/src/with/call.tsx b/packages/react-api/src/with/call.tsx index bd7ac1a4ba1c..cc7ecba90e24 100644 --- a/packages/react-api/src/with/call.tsx +++ b/packages/react-api/src/with/call.tsx @@ -98,12 +98,12 @@ export default function withCall

(endpoint: string, { // The attachment takes time when a lot is available, set a timeout // to first handle the current queue before subscribing - setTimeout((): void => { + setImmediate((): void => { this .subscribe(this.getParams(this.props)) .then(NOOP) .catch(NOOP); - }, 0); + }); } public componentWillUnmount (): void { diff --git a/packages/react-components/package.json b/packages/react-components/package.json index 1a0596e2d4a3..994b0a23e59e 100644 --- a/packages/react-components/package.json +++ b/packages/react-components/package.json @@ -1,6 +1,6 @@ { "name": "@polkadot/react-components", - "version": "0.37.0-beta.65", + "version": "0.37.0-beta.72", "main": "index.js", "repository": "https://github.com/polkadot-js/apps.git", "author": "Jaco Greeff ", @@ -12,11 +12,11 @@ "dependencies": { "@babel/runtime": "^7.7.1", "@polkadot/keyring": "^1.7.0-beta.6", - "@polkadot/react-api": "^0.37.0-beta.65", + "@polkadot/react-api": "^0.37.0-beta.72", "@polkadot/react-identicon": "^0.47.0-beta.5", - "@polkadot/react-query": "^0.37.0-beta.65", + "@polkadot/react-query": "^0.37.0-beta.72", "@polkadot/ui-keyring": "^0.47.0-beta.5", - "@polkadot/ui-settings": "^0.47.0-beta.5", + "@plasm/ui-settings": "^0.47.0-beta.5", "@types/chart.js": "^2.8.10", "@types/i18next": "^13.0.0", "@types/react-copy-to-clipboard": "^4.3.0", diff --git a/packages/react-components/src/AddressInfo.tsx b/packages/react-components/src/AddressInfo.tsx index 137e42d2668e..fa7e1def5f2a 100644 --- a/packages/react-components/src/AddressInfo.tsx +++ b/packages/react-components/src/AddressInfo.tsx @@ -12,6 +12,7 @@ import styled from 'styled-components'; import { formatBalance, formatNumber, isObject } from '@polkadot/util'; import { Icon, Tooltip, TxButton } from '@polkadot/react-components'; import { withCalls, withMulti } from '@polkadot/react-api'; +import { FormatBalance } from '@polkadot/react-query'; import CryptoType from './CryptoType'; import Label from './Label'; @@ -165,7 +166,7 @@ function renderUnlocking ({ stakingInfo, t }: Props): React.ReactNode { return (

- {formatBalance(total)} + @@ -211,9 +212,10 @@ function renderValidatorPrefs ({ stakingInfo, t, withValidatorPrefs = false }: P {validatorPrefsDisplay.validatorPayment && stakingInfo.validatorPrefs.validatorPayment && ( <>
@@ -73,7 +73,7 @@ export function Proposal ({ deposit, democracy_minimumDeposit = ZERO, onChange, {t('The deposit of {{deposit}} will be reserved until the proposal is completed', { replace: { - deposit: formatBalance(extraAmount) + deposit: formatBalance(extraAmount, { forceUnit: '-' }) } })} diff --git a/packages/react-signer/src/Modal.tsx b/packages/react-signer/src/Modal.tsx index a2b1b2566775..7a70c257820b 100644 --- a/packages/react-signer/src/Modal.tsx +++ b/packages/react-signer/src/Modal.tsx @@ -294,6 +294,7 @@ class Signer extends React.PureComponent { diff --git a/packages/ui-assets/.nodoc b/packages/ui-assets/.nodoc new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/packages/ui-assets/LICENSE b/packages/ui-assets/LICENSE new file mode 100644 index 000000000000..0d381b2e97dc --- /dev/null +++ b/packages/ui-assets/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/packages/ui-assets/README.md b/packages/ui-assets/README.md new file mode 100644 index 000000000000..99dc4580be77 --- /dev/null +++ b/packages/ui-assets/README.md @@ -0,0 +1,5 @@ +# @plasm/ui-assets + +ref: [polkadot-js/ui-settings](https://github.com/polkadot-js/ui/packages/ui-settings) + +Static assets including images shared across projects diff --git a/packages/ui-assets/package.json b/packages/ui-assets/package.json new file mode 100644 index 000000000000..c20679ba7489 --- /dev/null +++ b/packages/ui-assets/package.json @@ -0,0 +1,15 @@ +{ + "name": "@plasm/ui-assets", + "version": "0.47.0-beta.5", + "description": "Static assets shared accross projects", + "main": "index.js", + "author": "Jaco Greeff , Takumi Yamashita ", + "maintainers": [ + "Jaco Greeff ", + "Takumi Yamashita " + ], + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.7.1" + } +} diff --git a/packages/ui-assets/src/chains/kusama-128.gif b/packages/ui-assets/src/chains/kusama-128.gif new file mode 100644 index 000000000000..5d800a287fe4 Binary files /dev/null and b/packages/ui-assets/src/chains/kusama-128.gif differ diff --git a/packages/ui-assets/src/edgeware-circle.svg b/packages/ui-assets/src/edgeware-circle.svg new file mode 100644 index 000000000000..cda424ab815a --- /dev/null +++ b/packages/ui-assets/src/edgeware-circle.svg @@ -0,0 +1 @@ +logo-white-with-bgCreated with Sketch. \ No newline at end of file diff --git a/packages/ui-assets/src/edgeware.svg b/packages/ui-assets/src/edgeware.svg new file mode 100644 index 000000000000..9735fcba6010 --- /dev/null +++ b/packages/ui-assets/src/edgeware.svg @@ -0,0 +1 @@ +logo-white-with-bgCreated with Sketch. \ No newline at end of file diff --git a/packages/ui-assets/src/empty.svg b/packages/ui-assets/src/empty.svg new file mode 100644 index 000000000000..554e3dfe9b60 --- /dev/null +++ b/packages/ui-assets/src/empty.svg @@ -0,0 +1,7 @@ + + + + + diff --git a/packages/ui-assets/src/plasm.svg b/packages/ui-assets/src/plasm.svg new file mode 100644 index 000000000000..74b8adb94836 --- /dev/null +++ b/packages/ui-assets/src/plasm.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/ui-assets/src/polkadot-circle.svg b/packages/ui-assets/src/polkadot-circle.svg new file mode 100644 index 000000000000..561ca97d1812 --- /dev/null +++ b/packages/ui-assets/src/polkadot-circle.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + diff --git a/packages/ui-assets/src/polkadot-dots.svg b/packages/ui-assets/src/polkadot-dots.svg new file mode 100644 index 000000000000..ff6d17f0081c --- /dev/null +++ b/packages/ui-assets/src/polkadot-dots.svg @@ -0,0 +1 @@ +Polkadot dot logo \ No newline at end of file diff --git a/packages/ui-assets/src/polkadot-js.svg b/packages/ui-assets/src/polkadot-js.svg new file mode 100644 index 000000000000..7b60266ace1c --- /dev/null +++ b/packages/ui-assets/src/polkadot-js.svg @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/packages/ui-assets/src/polkadot-white.svg b/packages/ui-assets/src/polkadot-white.svg new file mode 100644 index 000000000000..94b215b99128 --- /dev/null +++ b/packages/ui-assets/src/polkadot-white.svg @@ -0,0 +1,13 @@ + + + + + + + + + + diff --git a/packages/ui-assets/src/substrate-circle.svg b/packages/ui-assets/src/substrate-circle.svg new file mode 100644 index 000000000000..eec7d998a49b --- /dev/null +++ b/packages/ui-assets/src/substrate-circle.svg @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + diff --git a/packages/ui-assets/src/substrate-hexagon.svg b/packages/ui-assets/src/substrate-hexagon.svg new file mode 100644 index 000000000000..45357eb5f4a2 --- /dev/null +++ b/packages/ui-assets/src/substrate-hexagon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/packages/ui-assets/src/substrate-white.svg b/packages/ui-assets/src/substrate-white.svg new file mode 100644 index 000000000000..63c70e83eefd --- /dev/null +++ b/packages/ui-assets/src/substrate-white.svg @@ -0,0 +1,15 @@ + + + + + + + + + + + + + diff --git a/packages/ui-assets/src/types.d.ts b/packages/ui-assets/src/types.d.ts new file mode 100644 index 000000000000..e4302211f063 --- /dev/null +++ b/packages/ui-assets/src/types.d.ts @@ -0,0 +1,9 @@ +// Copyright 2017-2019 @plasm/ui-assets authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +declare module '*.svg' { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const content: any; + export default content; +} diff --git a/packages/ui-settings/LICENSE b/packages/ui-settings/LICENSE new file mode 100644 index 000000000000..0d381b2e97dc --- /dev/null +++ b/packages/ui-settings/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/packages/ui-settings/README.md b/packages/ui-settings/README.md new file mode 100644 index 000000000000..02bac702e47a --- /dev/null +++ b/packages/ui-settings/README.md @@ -0,0 +1,41 @@ +# @plasm/ui-settings + +ref: [polkadot-js/ui-settings](https://github.com/polkadot-js/ui/packages/ui-settings) + +Manages app settings including endpoints, themes and prefixes + +## Usage Examples + +User preferences are set as a settings object in the browser's local storage. + +```js +import settings from '@plasm/ui-settings'; + +render () { + // get api endpoint for the selected chain + const WS_URL = settings.apiUrl(); + + // get the selected il8n language + const language = settings.il8nLang(); + + // get all available il8n languages + const languages = settings.availableLanguages(); + + // update settings + const updatedSettings = { + ...settings, + i18nLang: 'Arabic' + } + settings.set(updatedSettings); + + // NOTE: API currently does not handle hot reconnecting properly, + so you need to manually reload the page after updating settings. + window.location.reload(); +} +``` + +## Used by + +Apps that currently use the settings package + +* [stakedtechnologies/apps](https://www.github.com/stakedtechnologies/apps) diff --git a/packages/ui-settings/package.json b/packages/ui-settings/package.json new file mode 100644 index 000000000000..82073506fee9 --- /dev/null +++ b/packages/ui-settings/package.json @@ -0,0 +1,23 @@ +{ + "name": "@plasm/ui-settings", + "version": "0.47.0-beta.5", + "description": "Manages app settings", + "main": "index.js", + "author": "Jaco Greeff , Takumi Yamashita ", + "maintainers": [ + "Jaco Greeff ", + "Takumu Yamashita " + ], + "license": "Apache-2.0", + "dependencies": { + "@babel/runtime": "^7.7.1", + "@types/store": "^2.0.2", + "store": "^2.0.12" + }, + "devDependencies": { + "@polkadot/util": "^1.7.0-beta.5" + }, + "peerDependencies": { + "@polkadot/util": "*" + } +} diff --git a/packages/ui-settings/src/Settings.ts b/packages/ui-settings/src/Settings.ts new file mode 100644 index 000000000000..c8ec6cb070b2 --- /dev/null +++ b/packages/ui-settings/src/Settings.ts @@ -0,0 +1,166 @@ +// Copyright 2017-2019 @plasm/ui-settings authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import EventEmitter from 'eventemitter3'; +import store from 'store'; +import { isUndefined } from '@polkadot/util'; + +import { CAMERA_DEFAULT, CAMERA, CRYPTOS, ENDPOINT_DEFAULT, ENDPOINTS, ICON_DEFAULT, ICONS, LANGUAGE_DEFAULT, LANGUAGES, LEDGER_CONN, LEDGER_CONN_DEFAULT, LOCKING_DEFAULT, LOCKING, PREFIX_DEFAULT, PREFIXES, UIMODE_DEFAULT, UIMODES, UITHEME_DEFAULT, UITHEMES } from './defaults'; +import { Option, SettingsStruct } from './types'; + +type ChangeCallback = (settings: SettingsStruct) => void; +type OnTypes = 'change'; + +export class Settings implements SettingsStruct { + private _apiUrl: string; + + private _camera: string; + + private _emitter: EventEmitter; + + private _i18nLang: string; + + private _icon: string; + + private _ledgerConn: string; + + private _locking: string; + + private _prefix: number; + + private _uiMode: string; + + private _uiTheme: string; + + constructor () { + const settings = store.get('settings') || {}; + + this._emitter = new EventEmitter(); + + this._apiUrl = settings.apiUrl || process.env.WS_URL || ENDPOINT_DEFAULT; + this._camera = settings.camera || CAMERA_DEFAULT; + this._ledgerConn = settings.ledgerConn || LEDGER_CONN_DEFAULT; + this._i18nLang = settings.i18nLang || LANGUAGE_DEFAULT; + this._icon = settings.icon || ICON_DEFAULT; + this._locking = settings.locking || LOCKING_DEFAULT; + this._prefix = isUndefined(settings.prefix) ? PREFIX_DEFAULT : settings.prefix; + this._uiMode = settings.uiMode || UIMODE_DEFAULT; + this._uiTheme = settings.uiTheme || UITHEME_DEFAULT; + } + + public get camera (): string { + return this._camera; + } + + public get apiUrl (): string { + return this._apiUrl; + } + + public get i18nLang (): string { + return this._i18nLang; + } + + public get icon (): string { + return this._icon; + } + + public get ledgerConn (): string { + return this._ledgerConn; + } + + public get locking (): string { + return this._locking; + } + + public get prefix (): number { + return this._prefix; + } + + public get uiMode (): string { + return this._uiMode; + } + + public get uiTheme (): string { + return this._uiTheme; + } + + public get availableCamera (): Option[] { + return CAMERA; + } + + public get availableCryptos (): Option[] { + return CRYPTOS; + } + + public get availableIcons (): Option[] { + return ICONS; + } + + public get availableLanguages (): Option[] { + return LANGUAGES; + } + + public get availableLedgerConn (): Option[] { + return LEDGER_CONN; + } + + public get availableLocking (): Option[] { + return LOCKING; + } + + public get availableNodes (): Option[] { + return ENDPOINTS; + } + + public get availablePrefixes (): Option[] { + return PREFIXES; + } + + public get availableUIModes (): Option[] { + return UIMODES; + } + + public get availableUIThemes (): Option[] { + return UITHEMES; + } + + public get (): SettingsStruct { + return { + apiUrl: this._apiUrl, + camera: this._camera, + i18nLang: this._i18nLang, + icon: this._icon, + ledgerConn: this._ledgerConn, + locking: this._locking, + prefix: this._prefix, + uiMode: this._uiMode, + uiTheme: this._uiTheme + }; + } + + public set (settings: Partial): void { + this._apiUrl = settings.apiUrl || this._apiUrl; + this._camera = settings.camera || this._camera; + this._ledgerConn = settings.ledgerConn || this._ledgerConn; + this._i18nLang = settings.i18nLang || this._i18nLang; + this._icon = settings.icon || this._icon; + this._locking = settings.locking || this._locking; + this._prefix = isUndefined(settings.prefix) ? this._prefix : settings.prefix; + this._uiMode = settings.uiMode || this._uiMode; + this._uiTheme = settings.uiTheme || this._uiTheme; + + const newValues = this.get(); + + store.set('settings', newValues); + this._emitter.emit('change', newValues); + } + + public on (type: OnTypes, cb: ChangeCallback): void { + this._emitter.on(type, cb); + } +} + +const settings = new Settings(); + +export default settings; diff --git a/packages/ui-settings/src/defaults/crypto.ts b/packages/ui-settings/src/defaults/crypto.ts new file mode 100644 index 000000000000..158484b29de2 --- /dev/null +++ b/packages/ui-settings/src/defaults/crypto.ts @@ -0,0 +1,18 @@ +// Copyright 2017-2019 @plasm/ui-settings authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { Option } from '../types'; + +export const CRYPTOS: Option[] = [ + { + info: 'ed25519', + text: 'Edwards (ed25519)', + value: 'ed25519' + }, + { + info: 'sr25519', + text: 'Schnorrkel (sr25519)', + value: 'sr25519' + } +]; diff --git a/packages/ui-settings/src/defaults/endpoints.ts b/packages/ui-settings/src/defaults/endpoints.ts new file mode 100644 index 000000000000..ab7ff41f3707 --- /dev/null +++ b/packages/ui-settings/src/defaults/endpoints.ts @@ -0,0 +1,76 @@ +import { Option } from '../types'; + +import { isPlasm } from './type'; + +type ChainName = 'plasmTest'; + +interface ChainData { + chainDisplay: string; + logo: 'plasm' | 'substrate'; + type: string; +} + +type ProviderName = 'stake_1' | 'stake_2' | 'stake_3' | 'stake_4'; + +interface PoviderData { + providerDisplay: string; + nodes: Partial>; +} + +// we use this to give an ordering to the chains available +const ORDER_CHAINS: ChainName[] = ['plasmTest']; + +// we use this to order the providers inside the chains +const ORDER_PROVIDERS: ProviderName[] = ['stake_1', 'stake_2', 'stake_3', 'stake_4']; + +// some suplementary info on a per-chain basis +const CHAIN_INFO: Record = { + plasmTest: { + chainDisplay: 'Plasm Testnet v1', + logo: 'plasm', + type: 'Plasm Testnet' + } +}; + +const HOSTS: String[] = ['3.114.90.94:443', '3.114.81.104:443', '3.115.175.152:443', '54.64.145.3:443']; + +// the actual providers with all the nodes they provide +const PROVIDERS: Record = ORDER_PROVIDERS.reduce((map, p, i) => { + map[p] = { + providerDisplay: 'Stake technologies node' + i, + nodes: { + plasmTest: 'ws://' + HOSTS[i] + } + }; + return map; +}, {}); + +export const ENDPOINT_DEFAULT = isPlasm + ? PROVIDERS.stake_1.nodes.plasmTest + : PROVIDERS.stake_2.nodes.plasmTest; + +export const ENDPOINTS: Option[] = ORDER_CHAINS.reduce((endpoints: Option[], chainName): Option[] => { + const { chainDisplay, logo, type } = CHAIN_INFO[chainName]; + + return ORDER_PROVIDERS.reduce((endpoints: Option[], providerName): Option[] => { + const { providerDisplay, nodes } = PROVIDERS[providerName]; + const wssUrl = nodes[chainName]; + + if (wssUrl) { + endpoints.push({ + info: logo, + text: `${chainDisplay} (${type}, hosted by ${providerDisplay})`, + value: wssUrl + }); + } + + return endpoints; + }, endpoints); +}, []); + +// add a local node right at the end +ENDPOINTS.push({ + info: 'local', + text: 'Local Node (Own, 127.0.0.1:9944)', + value: 'ws://127.0.0.1:9944/' +}); diff --git a/packages/ui-settings/src/defaults/index.ts b/packages/ui-settings/src/defaults/index.ts new file mode 100644 index 000000000000..e041b651af7e --- /dev/null +++ b/packages/ui-settings/src/defaults/index.ts @@ -0,0 +1,74 @@ +// Copyright 2017-2019 @plasm/ui-settings authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { Option } from '../types'; + +import { CRYPTOS } from './crypto'; +import { ENDPOINTS, ENDPOINT_DEFAULT } from './endpoints'; +import { LEDGER_CONN, LEDGER_CONN_DEFAULT } from './ledger'; +import { PREFIXES, PREFIX_DEFAULT } from './ss58'; +import { ICON_DEFAULT, ICON_DEFAULT_HOST, ICONS, UIMODE_DEFAULT, UIMODES, UITHEME_DEFAULT, UITHEMES } from './ui'; + +const CAMERA_DEFAULT = 'off'; + +const CAMERA: Option[] = [ + { + info: 'on', + text: 'Allow camera access', + value: 'on' + }, + { + info: 'off', + text: 'Do not allow camera access', + value: 'off' + } +]; + +const LANGUAGE_DEFAULT = 'default'; + +const LANGUAGES: Option[] = [ + { + info: 'detect', + text: 'Default browser language (auto-detect)', + value: LANGUAGE_DEFAULT + } +]; + +const LOCKING_DEFAULT = 'session'; + +const LOCKING: Option[] = [ + { + info: 'session', + text: 'Once per session', + value: 'session' + }, + { + info: 'tx', + text: 'On each transaction', + value: 'tx' + } +]; + +export { + CAMERA_DEFAULT, + CAMERA, + CRYPTOS, + ENDPOINT_DEFAULT, + ENDPOINTS, + ICON_DEFAULT, + ICON_DEFAULT_HOST, + ICONS, + LANGUAGE_DEFAULT, + LANGUAGES, + LEDGER_CONN_DEFAULT, + LEDGER_CONN, + LOCKING_DEFAULT, + LOCKING, + PREFIX_DEFAULT, + PREFIXES, + UIMODE_DEFAULT, + UIMODES, + UITHEME_DEFAULT, + UITHEMES +}; diff --git a/packages/ui-settings/src/defaults/ledger.ts b/packages/ui-settings/src/defaults/ledger.ts new file mode 100644 index 000000000000..df526bc17bfa --- /dev/null +++ b/packages/ui-settings/src/defaults/ledger.ts @@ -0,0 +1,25 @@ +// Copyright 2017-2019 @plasm/ui-settings authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { Option } from '../types'; + +export const LEDGER_CONN_DEFAULT = 'none'; + +export const LEDGER_CONN: Option[] = [ + { + info: 'none', + text: 'Do not attach Ledger devices', + value: 'none' + }, + { + info: 'u2f', + text: 'Attach Ledger via U2F', + value: 'u2f' + }, + { + info: 'webusb', + text: 'Attach Ledger via WebUSB', + value: 'webusb' + } +]; diff --git a/packages/ui-settings/src/defaults/ss58.ts b/packages/ui-settings/src/defaults/ss58.ts new file mode 100644 index 000000000000..675926098c1f --- /dev/null +++ b/packages/ui-settings/src/defaults/ss58.ts @@ -0,0 +1,35 @@ +// Copyright 2017-2019 @plasm/ui-settings authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { Option } from '../types'; + +export const PREFIX_DEFAULT = -1; + +export const PREFIXES: Option[] = [ + { + info: 'default', + text: 'Default for the connected node', + value: -1 + }, + { + info: 'substrate', + text: 'Substrate (development)', + value: 42 + }, + { + info: 'kusama', + text: 'Kusama (canary)', + value: 2 + }, + { + info: 'polkadot', + text: 'Polkadot (live)', + value: 0 + }, + { + info: 'plasm', + text: 'Plasm Testnet v1 (test net)', + value: 3 + } +]; diff --git a/packages/ui-settings/src/defaults/type.ts b/packages/ui-settings/src/defaults/type.ts new file mode 100644 index 000000000000..769e46761641 --- /dev/null +++ b/packages/ui-settings/src/defaults/type.ts @@ -0,0 +1,7 @@ +// Copyright 2017-2019 @plasm/ui-settings authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +// matches https://polkadot.js.org & https://*.polkadot.io +export const isPolkadot = typeof window !== 'undefined' && window.location.host.includes('polkadot'); +export const isPlasm = typeof window !== 'undefined' && window.location.host.includes('plasm'); \ No newline at end of file diff --git a/packages/ui-settings/src/defaults/ui.ts b/packages/ui-settings/src/defaults/ui.ts new file mode 100644 index 000000000000..1c06046359dd --- /dev/null +++ b/packages/ui-settings/src/defaults/ui.ts @@ -0,0 +1,93 @@ +// Copyright 2017-2019 @plasm/ui-settings authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import { Option } from '../types'; + +import { isPlasm } from './type'; + +const LANGUAGE_DEFAULT = 'default'; + +const UIMODE_DEFAULT = !isPlasm && typeof window !== 'undefined' && window.location.host.includes('ui-light') + ? 'light' + : 'full'; + +const UIMODES: Option[] = [ + { + info: 'full', + text: 'Fully featured', + value: 'full' + }, + { + info: 'light', + text: 'Basic features only', + value: 'light' + } +]; + +const UITHEME_DEFAULT = isPlasm + ? 'plasm' + : 'substrate'; + +const UITHEMES: Option[] = [ + { + info: 'polkadot', + text: 'Polkadot', + value: 'polkadot' + }, + { + info: 'substrate', + text: 'Substrate', + value: 'substrate' + }, + { + info: 'plasm', + text: 'Plasm', + value: 'plasm' + } +]; + +const ICON_DEFAULT = 'default'; + +const ICON_DEFAULT_HOST = isPlasm + ? 'plasm' + : 'substrate'; + +const ICONS: Option[] = [ + { + info: 'default', + text: 'Default for the connected node', + value: 'default' + }, + { + info: 'plasm', + text: 'Plasm', + value: 'plasm' + }, + { + info: 'polkadot', + text: 'Polkadot', + value: 'polkadot' + }, + { + info: 'substrate', + text: 'Substrate', + value: 'substrate' + }, + { + info: 'beachball', + text: 'Beachball', + value: 'beachball' + } +]; + +export { + ICON_DEFAULT, + ICON_DEFAULT_HOST, + ICONS, + LANGUAGE_DEFAULT, + UIMODE_DEFAULT, + UIMODES, + UITHEME_DEFAULT, + UITHEMES +}; diff --git a/packages/ui-settings/src/index.ts b/packages/ui-settings/src/index.ts new file mode 100644 index 000000000000..3b552c12479f --- /dev/null +++ b/packages/ui-settings/src/index.ts @@ -0,0 +1,12 @@ +// Copyright 2017-2019 @plasm/ui-settings authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +import settings, { Settings } from './Settings'; +export { ENDPOINT_DEFAULT, ICON_DEFAULT, ICON_DEFAULT_HOST, LANGUAGE_DEFAULT, LOCKING_DEFAULT, PREFIX_DEFAULT, UIMODE_DEFAULT, UITHEME_DEFAULT } from './defaults'; + +export default settings; + +export { + Settings +}; diff --git a/packages/ui-settings/src/types.ts b/packages/ui-settings/src/types.ts new file mode 100644 index 000000000000..cef3bfba4d56 --- /dev/null +++ b/packages/ui-settings/src/types.ts @@ -0,0 +1,22 @@ +// Copyright 2017-2019 @plasm/ui-settings authors & contributors +// This software may be modified and distributed under the terms +// of the Apache-2.0 license. See the LICENSE file for details. + +export type Option = { + disabled?: boolean; + info: string; + text: string; + value: string | number; +} + +export interface SettingsStruct { + apiUrl: string; + camera: string; + i18nLang: string; + icon: string; + ledgerConn: string; + locking: string; + prefix: number; + uiMode: string; + uiTheme: string; +} diff --git a/tsconfig.json b/tsconfig.json index 49443fd44d9a..acea49f25f77 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -58,7 +58,9 @@ "@polkadot/react-query": [ "packages/react-query/src" ], "@polkadot/react-query/*": [ "packages/react-query/src/*" ], "@polkadot/react-signer": [ "packages/react-signer/src" ], - "@polkadot/react-signer/*": [ "packages/react-signer/src/*" ] + "@polkadot/react-signer/*": [ "packages/react-signer/src/*" ], + "@plasm/ui-settings/*": [ "packages/ui-settings/src/*" ], + "@plasm/ui-assets/*": [ "packages/ui-assets/src/*" ] }, "skipLibCheck": true, "typeRoots": [ diff --git a/yarn.lock b/yarn.lock index 4025be584c42..a76d893e4acc 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2255,13 +2255,6 @@ "@types/memoizee" "^0.4.3" memoizee "^0.4.14" -"@polkadot/ui-assets@^0.47.0-beta.5": - version "0.47.0-beta.5" - resolved "https://registry.yarnpkg.com/@polkadot/ui-assets/-/ui-assets-0.47.0-beta.5.tgz#57daba00e887cdd3cb9bdec4661cb49d6a9f33a8" - integrity sha512-ThE6Y+22pEKKxcs+iuagFIl+xnHn2IVUsw/1Wa7MnfNGAJXhYd9UzRbsOFBxXxhuLOUKjVm+tbPuZQwm/d68Bg== - dependencies: - "@babel/runtime" "^7.7.1" - "@polkadot/ui-keyring@^0.47.0-beta.5": version "0.47.0-beta.5" resolved "https://registry.yarnpkg.com/@polkadot/ui-keyring/-/ui-keyring-0.47.0-beta.5.tgz#30a660657239071115f22fbfcaee248950531f72" @@ -2321,7 +2314,7 @@ tweetnacl "^1.0.1" xxhashjs "^0.2.2" -"@polkadot/util@^1.7.0-beta.6": +"@polkadot/util@^1.7.0-beta.5", "@polkadot/util@^1.7.0-beta.6": version "1.7.0-beta.6" resolved "https://registry.yarnpkg.com/@polkadot/util/-/util-1.7.0-beta.6.tgz#82712376f2b999f079f4021c5ec08d4a8f0a57cd" integrity sha512-QyOz5a0DaK7FMN+GtE7nOHO1JgOmPf5RcPcA3pXsEQgpIFlx8pctU18kXI2uY/Q+124rV8OECM7IVMaypJeNnA==