Browse Source

Add Westend, externalize endpoints (#2171)

* Add Westend, externalize endpoints

* Update scanner with all current namespaces

* WebEnd type overrides

* Westend link to Polkascan
Jaco Greeff 5 years ago
parent
commit
d0ed2897cb

+ 1 - 1
i18next-scanner.config.js

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

+ 11 - 14
packages/app-settings/src/Developer.tsx

@@ -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;
+  }
+`;

+ 20 - 35
packages/app-settings/src/General.tsx

@@ -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);

+ 25 - 24
packages/app-settings/src/SelectUrl.tsx

@@ -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;
+  }
+`;

+ 50 - 0
packages/app-settings/src/available/endpoints.ts

@@ -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[];

+ 11 - 0
packages/app-settings/src/available/index.ts

@@ -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
+};

+ 25 - 0
packages/app-settings/src/available/languages.ts

@@ -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[];

+ 10 - 14
packages/app-settings/src/index.tsx

@@ -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);

+ 2 - 6
packages/app-settings/src/types.ts

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

+ 5 - 5
packages/app-settings/src/util.tsx

@@ -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

+ 5 - 1
packages/react-api/src/overrides/chain/index.ts

@@ -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
+};

+ 7 - 0
packages/react-api/src/overrides/chain/westend.ts

@@ -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'
+};

+ 2 - 1
packages/react-components/src/ChainImg.tsx

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

+ 2 - 1
packages/react-components/src/LinkPolkascan.tsx

@@ -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> = {

+ 3 - 0
packages/react-components/src/i18n.ts

@@ -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'