diff --git a/common/components/Header/index.tsx b/common/components/Header/index.tsx index c549f889..f336912b 100644 --- a/common/components/Header/index.tsx +++ b/common/components/Header/index.tsx @@ -13,7 +13,7 @@ import { } from '../../config/data'; import GasPriceDropdown from './components/GasPriceDropdown'; import Navigation from './components/Navigation'; - +import { getKeyByValue } from 'utils/helpers'; import './index.scss'; interface Props { @@ -30,8 +30,7 @@ interface Props { export default class Header extends Component { public render() { const { languageSelection, changeNode, nodeSelection } = this.props; - const selectedLanguage = - languages.find(l => l.sign === languageSelection) || languages[0]; + const selectedLanguage = languageSelection; const selectedNode = NODES[nodeSelection]; const selectedNetwork = NETWORKS[selectedNode.network]; const LanguageDropDown = Dropdown as new () => Dropdown< @@ -76,10 +75,11 @@ export default class Header extends Component { /> ,
  • @@ -109,20 +109,19 @@ export default class Header extends Component { ); } - public changeLanguage = (value: { sign: string }) => { - this.props.changeLanguage(value.sign); + public changeLanguage = (value: string) => { + const key = getKeyByValue(languages, value); + if (key) { + this.props.changeLanguage(key); + } }; - private extractName(): (option: { sign: string; name: string }) => string { - return name; - } - private nodeNetworkAndService = (option: string) => [ NODES[option].network, ' ', diff --git a/common/components/ui/Dropdown.tsx b/common/components/ui/Dropdown.tsx index 18cc22d1..141a448d 100644 --- a/common/components/ui/Dropdown.tsx +++ b/common/components/ui/Dropdown.tsx @@ -5,7 +5,7 @@ interface Props { options: T[]; ariaLabel: string; extra?: any; - formatTitle(option: T): any; + formatTitle?(option: T): any; onChange(value: T): void; } @@ -32,10 +32,10 @@ export default class DropdownComponent extends Component, State> { className="dropdown-toggle" onClick={this.toggleExpanded} > - {this.formatTitle(value)} + {this.props.formatTitle ? this.formatTitle(value) : value} - {expanded && + {expanded && (
      {options.map((option, i) => { return ( @@ -44,20 +44,23 @@ export default class DropdownComponent extends Component, State> { className={option === value ? 'active' : ''} onClick={this.onChange.bind(null, option)} > - {this.formatTitle(option)} + {this.props.formatTitle ? this.formatTitle(option) : option} ); })} {extra} -
    } + + )} ); } - public formatTitle(option: any) { - return this.props.formatTitle(option); - } + public formatTitle = (option: any) => { + if (this.props.formatTitle) { + return this.props.formatTitle(option); + } + }; public toggleExpanded = () => { this.setState(state => { diff --git a/common/config/data.ts b/common/config/data.ts index b91fef50..19a40051 100644 --- a/common/config/data.ts +++ b/common/config/data.ts @@ -1,5 +1,5 @@ import { EtherscanNode, InfuraNode, RPCNode } from 'libs/nodes'; - +export const languages = require('./languages.json'); // Displays in the header export const VERSION = '4.0.0 (Alpha 0.0.2)'; @@ -40,101 +40,6 @@ export const gasPriceDefaults = { export const bityReferralURL = 'https://bity.com/af/jshkb37v'; -export const languages = [ - { - sign: 'en', - name: 'English' - }, - { - sign: 'de', - name: 'Deutsch' - }, - { - sign: 'el', - name: 'Ελληνικά' - }, - { - sign: 'es', - name: 'Español' - }, - { - sign: 'fi', - name: 'Suomi' - }, - { - sign: 'fr', - name: 'Français' - }, - { - sign: 'hu', - name: 'Magyar' - }, - { - sign: 'id', - name: 'Indonesian' - }, - { - sign: 'it', - name: 'Italiano' - }, - { - sign: 'ja', - name: '日本語' - }, - { - sign: 'nl', - name: 'Nederlands' - }, - { - sign: 'no', - name: 'Norsk Bokmål' - }, - { - sign: 'pl', - name: 'Polski' - }, - { - sign: 'pt', - name: 'Português' - }, - { - sign: 'ru', - name: 'Русский' - }, - { - sign: 'ko', - name: 'Korean' - }, - // { - // 'sign': 'sk', - // 'name': 'Slovenčina' - // }, - // { - // 'sign': 'sl', - // 'name': 'Slovenščina' - // }, - // { - // 'sign': 'sv', - // 'name': 'Svenska' - // }, - { - sign: 'tr', - name: 'Türkçe' - }, - { - sign: 'vi', - name: 'Tiếng Việt' - }, - { - sign: 'zhcn', - name: '简体中文' - }, - { - sign: 'zhtw', - name: '繁體中文' - } -]; - export interface BlockExplorerConfig { name: string; tx(txHash: string): string; @@ -156,6 +61,7 @@ export interface NetworkContract { export interface NetworkConfig { name: string; unit: string; + color?: string; blockExplorer?: BlockExplorerConfig; tokenExplorer?: { name: string; @@ -173,22 +79,92 @@ export interface NodeConfig { estimateGas?: boolean; } +// Must be a website that follows the ethplorer convention of /tx/[hash] and +// address/[address] to generate the correct functions. +function makeExplorer(url): BlockExplorerConfig { + return { + name: url, + tx: hash => `${url}/tx/${hash}`, + address: address => `${url}/address/${address}` + }; +} + export const NETWORKS: { [key: string]: NetworkConfig } = { ETH: { name: 'ETH', unit: 'ETH', chainId: 1, - blockExplorer: { - name: etherScan, - tx: ETHTxExplorer, - address: ETHAddressExplorer - }, + color: '#0e97c0', + blockExplorer: makeExplorer('https://etherscan.io'), tokenExplorer: { name: ethPlorer, address: ETHTokenExplorer }, - tokens: require('./tokens/eth'), + tokens: require('./tokens/eth.json'), contracts: require('./contracts/eth.json') + }, + ETC: { + name: 'ETC', + unit: 'ETC', + chainId: 61, + color: '#669073', + blockExplorer: makeExplorer('https://gastracker.io'), + tokens: require('./tokens/etc.json'), + contracts: require('./contracts/etc.json') + }, + Ropsten: { + name: 'Ropsten', + unit: 'ETH', + chainId: 3, + color: '#adc101', + blockExplorer: makeExplorer('https://ropsten.etherscan.io'), + tokens: require('./tokens/ropsten.json'), + contracts: require('./contracts/ropsten.json') + }, + Kovan: { + name: 'Kovan', + unit: 'ETH', + chainId: 42, + color: '#adc101', + blockExplorer: makeExplorer('https://kovan.etherscan.io'), + tokens: require('./tokens/ropsten.json'), + contracts: require('./contracts/ropsten.json') + }, + Rinkeby: { + name: 'Rinkeby', + unit: 'ETH', + chainId: 4, + color: '#adc101', + blockExplorer: makeExplorer('https://rinkeby.etherscan.io'), + tokens: require('./tokens/rinkeby.json'), + contracts: require('./contracts/rinkeby.json') + }, + RSK: { + name: 'RSK', + unit: 'RSK', + chainId: 31, + color: '#ff794f', + blockExplorer: makeExplorer('https://explorer.rsk.co'), + tokens: require('./tokens/rsk.json'), + contracts: require('./contracts/rsk.json') + }, + EXP: { + name: 'EXP', + unit: 'EXP', + chainId: 2, + color: '#673ab7', + blockExplorer: makeExplorer('http://www.gander.tech'), + tokens: require('./tokens/exp.json'), + contracts: require('./contracts/exp.json') + }, + UBQ: { + name: 'UBQ', + unit: 'UBQ', + chainId: 8, + color: '#b37aff', + blockExplorer: makeExplorer('https://ubiqscan.io/en'), + tokens: require('./tokens/ubq.json'), + contracts: require('./contracts/ubq.json') } }; @@ -198,5 +174,71 @@ export const NODES: { [key: string]: NodeConfig } = { lib: new RPCNode('https://api.myetherapi.com/eth'), service: 'MyEtherWallet', estimateGas: true + }, + eth_ethscan: { + network: 'ETH', + service: 'Etherscan.io', + lib: new EtherscanNode('https://api.etherscan.io/api'), + estimateGas: false + }, + eth_infura: { + network: 'ETH', + service: 'infura.io', + lib: new InfuraNode('https://mainnet.infura.io/mew'), + estimateGas: false + }, + etc_epool: { + network: 'ETC', + service: 'Epool.io', + lib: new RPCNode('https://mewapi.epool.io'), + estimateGas: false + }, + rop_mew: { + network: 'Ropsten', + service: 'MyEtherWallet', + lib: new RPCNode('https://api.myetherapi.com/rop'), + estimateGas: false + }, + rop_infura: { + network: 'Ropsten', + service: 'infura.io', + lib: new InfuraNode('https://ropsten.infura.io/mew'), + estimateGas: false + }, + kov_ethscan: { + network: 'Kovan', + service: 'Etherscan.io', + lib: new EtherscanNode('https://kovan.etherscan.io/api'), + estimateGas: false + }, + rin_ethscan: { + network: 'Rinkeby', + service: 'Etherscan.io', + lib: new EtherscanNode('https://rinkeby.etherscan.io/api'), + estimateGas: false + }, + rin_infura: { + network: 'Rinkeby', + service: 'infura.io', + lib: new InfuraNode('https://rinkeby.infura.io/mew'), + estimateGas: false + }, + rsk: { + network: 'RSK', + service: 'GK2.sk', + lib: new RPCNode('https://rsk-test.gk2.sk/'), + estimateGas: true + }, + exp: { + network: 'EXP', + service: 'Expanse.tech', + lib: new RPCNode('https://node.expanse.tech/'), + estimateGas: true + }, + ubq: { + network: 'UBQ', + service: 'ubiqscan.io', + lib: new RPCNode('https://pyrus2.ubiqscan.io'), + estimateGas: true } }; diff --git a/common/config/languages.json b/common/config/languages.json new file mode 100644 index 00000000..bf575eb4 --- /dev/null +++ b/common/config/languages.json @@ -0,0 +1,22 @@ +{ + "en": "English", + "de": "Deutsch", + "el": "Ελληνικά", + "es": "Español", + "fi": "Suomi", + "fr": "Français", + "hu": "Magyar", + "id": "Indonesian", + "it": "Italiano", + "ja": "日本語", + "nl": "Nederlands", + "no": "Norsk Bokmål", + "pl": "Polski", + "pt": "Português", + "ru": "Русский", + "ko": "Korean", + "tr": "Türkçe", + "vi": "Tiếng Việt", + "zhcn": "简体中文", + "zhtw": "繁體中文" +} diff --git a/common/reducers/config.ts b/common/reducers/config.ts index 80e92cf3..1185192b 100644 --- a/common/reducers/config.ts +++ b/common/reducers/config.ts @@ -15,7 +15,7 @@ export interface State { } export const INITIAL_STATE: State = { - languageSelection: languages[0].sign, + languageSelection: 'en', nodeSelection: Object.keys(NODES)[0], gasPriceGwei: 21 }; diff --git a/common/utils/helpers.ts b/common/utils/helpers.ts new file mode 100644 index 00000000..276043a9 --- /dev/null +++ b/common/utils/helpers.ts @@ -0,0 +1,3 @@ +export function getKeyByValue(object, value) { + return Object.keys(object).find(key => object[key] === value); +}