Add Westend, externalize endpoints (#2171)

* Add Westend, externalize endpoints

* Update scanner with all current namespaces

* WebEnd type overrides

* Westend link to Polkascan
This commit is contained in:
Jaco Greeff 2020-01-24 11:14:45 +01:00 committed by GitHub
parent 2594dfdb58
commit d0ed2897cb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 179 additions and 102 deletions

View File

@ -46,7 +46,7 @@ module.exports = {
debug: true,
func: {
list: ['t', 'i18next.t', 'i18n.t'],
extensions: ['.tsx']
extensions: ['.tsx', '.ts']
},
trans: {
component: 'Trans'

View File

@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AppProps, I18nProps } from '@polkadot/react-components/types';
import { AppProps as Props } from '@polkadot/react-components/types';
import React, { useEffect, useState } from 'react';
import store from 'store';
@ -11,14 +11,13 @@ import { registry } from '@polkadot/react-api';
import { Button, Editor, InputFile } from '@polkadot/react-components';
import { isJsonObject, stringToU8a, u8aToString } from '@polkadot/util';
import translate from './translate';
interface Props extends AppProps, I18nProps {}
import { useTranslation } from './translate';
const EMPTY_CODE = '{\n\n}';
const EMPTY_TYPES = {};
function Developer ({ className, onStatusChange, t }: Props): React.ReactElement<Props> {
function Developer ({ className, onStatusChange }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [code, setCode] = useState(EMPTY_CODE);
const [isJsonValid, setIsJsonValid] = useState(true);
const [isTypesValid, setIsTypesValid] = useState(true);
@ -160,12 +159,10 @@ function Developer ({ className, onStatusChange, t }: Props): React.ReactElement
);
}
export default translate(
styled(Developer)`
.editor {
height: 21rem;
margin-left: 2rem;
position: relative;
}
`
);
export default styled(Developer)`
.editor {
height: 21rem;
margin-left: 2rem;
position: relative;
}
`;

View File

@ -2,49 +2,43 @@
// 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 { Option, SetOption } from './types';
import { Option } from './types';
import React, { useEffect, useState, useMemo } from 'react';
import { isLedgerCapable } from '@polkadot/react-api';
import { Button, ButtonCancel, Dropdown } from '@polkadot/react-components';
import uiSettings, { SettingsStruct } from '@polkadot/ui-settings';
import translate from './translate';
import { availableLanguages } from './available';
import { useTranslation } from './translate';
import { createIdenticon, createOption, save, saveAndReload } from './util';
import SelectUrl from './SelectUrl';
interface Props extends I18nProps{
interface Props {
className?: string;
isModalContent?: boolean;
onClose: () => void;
}
const prefixOptions = uiSettings.availablePrefixes.map((o): Option => createOption(o, ['default']));
const iconOptions = uiSettings.availableIcons.map((o): Option => createIdenticon(o, ['default']));
const ledgerConnOptions = uiSettings.availableLedgerConn;
const availableLanguages: SetOption[] = [
{
text: 'Default browser language (auto-detect)',
value: 'default'
},
{
text: 'English',
value: 'en'
},
{
text: '汉语',
value: 'zh'
},
{
text: '日本語',
value: 'ja'
}
];
function General ({ className, isModalContent, onClose, t }: Props): React.ReactElement<Props> {
export default function General ({ className, isModalContent, onClose }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
// tri-state: null = nothing changed, false = no reload, true = reload required
const [changed, setChanged] = useState<boolean | null>(null);
const [settings, setSettings] = useState(uiSettings.get());
const iconOptions = useMemo((): Option[] => {
return uiSettings.availableIcons.map((o): Option => createIdenticon(t, o, ['default']));
}, [t]);
const prefixOptions = useMemo((): Option[] => {
return uiSettings.availablePrefixes.map((o): Option => createOption(t, o, ['default']));
}, [t]);
const translateLanguages = useMemo((): Option[] => {
return availableLanguages.map(({ text, value, withI18n }) => ({
value,
text: withI18n ? t(text as string) : text
}));
}, [t]);
useEffect((): void => {
const prev = uiSettings.get();
@ -67,13 +61,6 @@ function General ({ className, isModalContent, onClose, t }: Props): React.React
setChanged(null);
};
const translatedAvailableLanguages = useMemo(() =>
availableLanguages.map(option => ({
...option,
text: t(option.text)
}))
, [t]);
const { icon, i18nLang, ledgerConn, prefix, uiMode } = settings;
return (
@ -124,7 +111,7 @@ function General ({ className, isModalContent, onClose, t }: Props): React.React
defaultValue={i18nLang}
label={t('default interface language')}
onChange={_handleChange('i18nLang')}
options={translatedAvailableLanguages}
options={translateLanguages}
/>
</div>
</>
@ -155,5 +142,3 @@ function General ({ className, isModalContent, onClose, t }: Props): React.React
</div>
);
}
export default translate(General);

View File

@ -2,18 +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 { I18nProps } from '@polkadot/react-components/types';
import { Option } from './types';
import React, { useEffect, useState } from 'react';
import React, { useEffect, useMemo, useState } from 'react';
import styled from 'styled-components';
import { Dropdown, Input, Toggle } from '@polkadot/react-components';
import uiSettings from '@polkadot/ui-settings';
import translate from './translate';
import { availableEndpoints } from './available';
import { useTranslation } from './translate';
import { createOption } from './util';
interface Props extends I18nProps {
interface Props {
className?: string;
onChange: (url: string) => void;
}
@ -27,8 +27,6 @@ interface State extends StateUrl {
isCustom: boolean;
}
const endpointOptions = uiSettings.availableNodes.map((o): Option => createOption(o, ['local']));
// check the validity of the url
function isValidUrl (url: string): boolean {
return (
@ -59,11 +57,22 @@ function getInitialState (): State {
return { isCustom, isValid, url };
}
function SelectUrl ({ className, onChange, t }: Props): React.ReactElement<Props> {
function SelectUrl ({ className, onChange }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
const [info, setInfo] = useState(getInitialState());
const { isCustom, isValid, url } = info;
const help = t('Select the remote endpoint, either from the dropdown on manual entered via the custom toggle');
const label = t('remote node/endpoint to connect to');
const translatedEndpoints = useMemo(() => {
return availableEndpoints.map((option): Option => createOption(t, option, ['local']));
}, [t]);
useEffect((): void => {
if (onChange && info.isValid) {
onChange(info.url);
}
}, [info]);
const _onChangeUrl = (url: string): void => setInfo({ ...info, ...makeUrl(url) });
const _onChangeCustom = (isCustom: boolean): void =>
setInfo({
@ -75,12 +84,6 @@ function SelectUrl ({ className, onChange, t }: Props): React.ReactElement<Props
isCustom
});
useEffect((): void => {
if (onChange && info.isValid) {
onChange(info.url);
}
}, [info]);
return (
<div className={className}>
<div className='ui--row'>{
@ -97,7 +100,7 @@ function SelectUrl ({ className, onChange, t }: Props): React.ReactElement<Props
help={help}
label={label}
onChange={_onChangeUrl}
options={endpointOptions}
options={translatedEndpoints}
/>
}</div>
<Toggle
@ -110,14 +113,12 @@ function SelectUrl ({ className, onChange, t }: Props): React.ReactElement<Props
);
}
export default translate(
styled(SelectUrl)`
position: relative;
export default styled(SelectUrl)`
position: relative;
.settings--customToggle {
position: absolute;
top: .5rem;
right: 3.5rem;
}
`
);
.settings--customToggle {
position: absolute;
top: .5rem;
right: 3.5rem;
}
`;

View File

@ -0,0 +1,50 @@
// Copyright 2017-2020 @polkadot/app-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 default [
{
info: 'kusama',
text: 'Kusama (Polkadot Canary, hosted by Parity)',
value: 'wss://kusama-rpc.polkadot.io/',
withI18n: true
},
{
info: 'kusama',
text: 'Kusama (Polkadot Canary, hosted by Web3 Foundation)',
value: 'wss://cc3-5.kusama.network/',
withI18n: true
},
{
info: 'westend',
text: 'Westend (Polkadot Testnet, hosted by Parity)',
value: 'wss://westend-rpc.polkadot.io',
withI18n: true
},
{
info: 'edgeware',
text: 'Edgeware Testnet (Edgeware Testnet, hosted by Commonwealth Labs)',
value: 'wss://testnet4.edgewa.re',
withI18n: true
},
{
info: 'substrate',
text: 'Flaming Fir (Substrate Testnet, hosted by Parity)',
value: 'wss://substrate-rpc.parity.io/',
withI18n: true
},
{
info: 'substrate',
text: 'Kulupu (Kulupu Mainnet, hosted by Kulupu)',
value: 'wss://rpc.kulupu.network/ws',
withI18n: true
},
{
info: 'local',
text: 'Local Node (Own, 127.0.0.1:9944)',
value: 'ws://127.0.0.1:9944/',
withI18n: true
}
] as Option[];

View File

@ -0,0 +1,11 @@
// Copyright 2017-2020 @polkadot/app-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 availableLanguages from './languages';
import availableEndpoints from './endpoints';
export {
availableEndpoints,
availableLanguages
};

View File

@ -0,0 +1,25 @@
// Copyright 2017-2020 @polkadot/app-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 default [
{
text: 'Default browser language (auto-detect)',
value: 'default',
withI18n: true
},
{
text: 'English',
value: 'en'
},
{
text: '汉语',
value: 'zh'
},
{
text: '日本語',
value: 'ja'
}
] as Option[];

View File

@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { AppProps, I18nProps } from '@polkadot/react-components/types';
import { AppProps as Props } from '@polkadot/react-components/types';
import React from 'react';
import { Route, Switch } from 'react-router';
@ -11,23 +11,16 @@ import { HelpOverlay, Tabs } from '@polkadot/react-components';
import uiSettings from '@polkadot/ui-settings';
import md from './md/basics.md';
import translate from './translate';
import { useTranslation } from './translate';
import Developer from './Developer';
import General from './General';
interface Props extends AppProps, I18nProps {}
const hidden = uiSettings.uiMode === 'full'
? []
: ['developer'];
function SettingsApp (props: Props): React.ReactElement<Props> {
const _renderDeveloper = (): React.ReactNode => {
return (
<Developer {...props} />
);
};
const { basePath, t } = props;
export default function SettingsApp ({ basePath, onStatusChange }: Props): React.ReactElement<Props> {
const { t } = useTranslation();
return (
<main className='settings--App'>
@ -50,11 +43,14 @@ function SettingsApp (props: Props): React.ReactElement<Props> {
/>
</header>
<Switch>
<Route path={`${basePath}/developer`} render={_renderDeveloper} />
<Route path={`${basePath}/developer`}>
<Developer
basePath={basePath}
onStatusChange={onStatusChange}
/>
</Route>
<Route component={General} />
</Switch>
</main>
);
}
export default translate(SettingsApp);

View File

@ -3,12 +3,8 @@
// of the Apache-2.0 license. See the LICENSE file for details.
export interface Option {
info?: string;
text: React.ReactNode;
value: string | number;
}
export interface SetOption {
info?: string;
text: string;
value: string | number;
withI18n?: boolean;
}

View File

@ -3,13 +3,13 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { SettingsStruct } from '@polkadot/ui-settings/types';
import { Option, SetOption } from './types';
import { Option } from './types';
import React from 'react';
import { ChainImg, IdentityIcon } from '@polkadot/react-components';
import uiSettings from '@polkadot/ui-settings';
export function createOption ({ info, text, value }: SetOption, overrides: string[] = [], override = 'empty'): Option {
export function createOption (t: (input: any) => string, { info, text, value, withI18n }: Option, overrides: string[] = [], override = 'empty'): Option {
return {
text: (
<div
@ -24,14 +24,14 @@ export function createOption ({ info, text, value }: SetOption, overrides: strin
: info
}
/>
<div className='ui--Dropdown-name'>{text}</div>
<div className='ui--Dropdown-name'>{withI18n ? t(text) : text}</div>
</div>
),
value
};
}
export function createIdenticon ({ info, text, value }: SetOption, overrides: string[] = [], override = 'empty'): Option {
export function createIdenticon (t: (input: any) => string, { info, text, value, withI18n }: Option, overrides: string[] = [], override = 'empty'): Option {
return {
text: (
<div
@ -48,7 +48,7 @@ export function createIdenticon ({ info, text, value }: SetOption, overrides: st
}
value='5F9999K9UgTUgSsbXZQcEmRMvQqwJoBUHMv9e1k2MdgghuRA'
/>
<div className='ui--Dropdown-name'>{text}</div>
<div className='ui--Dropdown-name'>{withI18n ? t(text) : text}</div>
</div>
),
value

View File

@ -2,4 +2,8 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export default {};
import Westend from './westend';
export default {
Westend
};

View File

@ -0,0 +1,7 @@
// Copyright 2017-2020 @polkadot/react-api 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 default {
Keys: 'SessionKeys5'
};

View File

@ -45,7 +45,8 @@ const LOGOS: Record<string, any> = {
alexander: polkadot,
kusama: chainKusama,
polkadot,
substrate
substrate,
westend: polkadot
};
interface Props {

View File

@ -26,7 +26,8 @@ const CHAINS: Record<string, string> = {
Kusama: 'kusama-cc1', // old name via W3F nodes
'Kusama CC1': 'kusama-cc1',
'Kusama CC2': 'kusama-cc2',
'Kusama CC3': 'kusama-cc3'
'Kusama CC3': 'kusama-cc3',
Westend: 'westend'
};
const TYPES: Record<string, string> = {

View File

@ -53,9 +53,11 @@ i18n
'app-js',
'app-parachains',
'app-settings',
'app-society',
'app-staking',
'app-storage',
'app-sudo',
'app-tech-comm',
'app-toolbox',
'app-transfer',
'app-treasury',
@ -63,6 +65,7 @@ i18n
'apps-routing',
'react-api',
'react-components',
'react-hooks',
'react-params',
'react-query',
'react-signer'