mirror of
https://github.com/status-im/MyCrypto.git
synced 2025-01-24 18:09:10 +00:00
Enable network switching from header
This commit is contained in:
parent
a9e6528a06
commit
d904706f51
@ -33,6 +33,16 @@ export function changeNode(
|
||||
};
|
||||
}
|
||||
|
||||
export type TChangeNetwork = typeof changeNetwork;
|
||||
export function changeNetwork(
|
||||
payload: interfaces.ChangeNetworkAction['payload']
|
||||
): interfaces.ChangeNetworkAction {
|
||||
return {
|
||||
type: TypeKeys.CONFIG_NETWORK_CHANGE,
|
||||
payload
|
||||
};
|
||||
}
|
||||
|
||||
export type TPollOfflineStatus = typeof pollOfflineStatus;
|
||||
export function pollOfflineStatus(): interfaces.PollOfflineStatus {
|
||||
return {
|
||||
|
@ -26,6 +26,13 @@ export interface ChangeNodeAction {
|
||||
};
|
||||
}
|
||||
|
||||
export interface ChangeNetworkAction {
|
||||
type: TypeKeys.CONFIG_NETWORK_CHANGE;
|
||||
payload: {
|
||||
networkId: string;
|
||||
};
|
||||
}
|
||||
|
||||
/*** Poll offline status ***/
|
||||
export interface PollOfflineStatus {
|
||||
type: TypeKeys.CONFIG_POLL_OFFLINE_STATUS;
|
||||
@ -82,6 +89,8 @@ export type CustomNetworkAction = AddCustomNetworkAction | RemoveCustomNetworkAc
|
||||
|
||||
export type CustomNodeAction = AddCustomNodeAction | RemoveCustomNodeAction;
|
||||
|
||||
export type NetworkAction = ChangeNetworkAction;
|
||||
|
||||
export type NodeAction =
|
||||
| ChangeNodeAction
|
||||
| ChangeNodeIntentAction
|
||||
|
@ -14,6 +14,7 @@ export enum TypeKeys {
|
||||
CONFIG_ADD_CUSTOM_NODE = 'CONFIG_ADD_CUSTOM_NODE',
|
||||
CONFIG_REMOVE_CUSTOM_NODE = 'CONFIG_REMOVE_CUSTOM_NODE',
|
||||
|
||||
CONFIG_NETWORK_CHANGE = 'CONFIG_NETWORK_CHANGE',
|
||||
CONFIG_ADD_CUSTOM_NETWORK = 'CONFIG_ADD_CUSTOM_NETWORK',
|
||||
CONFIG_REMOVE_CUSTOM_NETWORK = 'CONFIG_REMOVE_CUSTOM_NETWORK'
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import {
|
||||
NodeOnlineAction,
|
||||
NodeRemovedAction,
|
||||
TypeKeys,
|
||||
NetworkSwitchRequestedAction,
|
||||
BalancerNetworkSwitchRequestedAction,
|
||||
NetworkSwitchSucceededAction
|
||||
} from 'actions/nodeBalancer';
|
||||
|
||||
@ -83,10 +83,10 @@ export const nodeCallSucceeded = (
|
||||
payload
|
||||
});
|
||||
|
||||
export const networkSwitchRequested = (): NetworkSwitchRequestedAction => ({
|
||||
type: TypeKeys.NETWORK_SWTICH_REQUESTED
|
||||
export const balancerNetworkSwitchRequested = (): BalancerNetworkSwitchRequestedAction => ({
|
||||
type: TypeKeys.BALANCER_NETWORK_SWTICH_REQUESTED
|
||||
});
|
||||
|
||||
export const networkSwitchSucceeded = (
|
||||
payload: NetworkSwitchSucceededAction['payload']
|
||||
): NetworkSwitchSucceededAction => ({ type: TypeKeys.NETWORK_SWITCH_SUCCEEDED, payload });
|
||||
): NetworkSwitchSucceededAction => ({ type: TypeKeys.BALANCER_NETWORK_SWITCH_SUCCEEDED, payload });
|
||||
|
@ -62,12 +62,12 @@ export interface WorkerProcessingAction {
|
||||
};
|
||||
}
|
||||
|
||||
export interface NetworkSwitchRequestedAction {
|
||||
type: TypeKeys.NETWORK_SWTICH_REQUESTED;
|
||||
export interface BalancerNetworkSwitchRequestedAction {
|
||||
type: TypeKeys.BALANCER_NETWORK_SWTICH_REQUESTED;
|
||||
}
|
||||
|
||||
export interface NetworkSwitchSucceededAction {
|
||||
type: TypeKeys.NETWORK_SWITCH_SUCCEEDED;
|
||||
type: TypeKeys.BALANCER_NETWORK_SWITCH_SUCCEEDED;
|
||||
payload: {
|
||||
nodeStats: NodeBalancerState['nodes'];
|
||||
workers: NodeBalancerState['workers'];
|
||||
@ -103,9 +103,20 @@ export interface NodeCallSucceededAction {
|
||||
payload: { result: string; nodeCall: NodeCall };
|
||||
}
|
||||
|
||||
export interface BalancerAutoAction {
|
||||
type: TypeKeys.BALANCER_AUTO;
|
||||
}
|
||||
|
||||
export interface BalancerManualAction {
|
||||
type: TypeKeys.BALANCER_MANUAL;
|
||||
payload: { nodeId: string };
|
||||
}
|
||||
|
||||
export type BalancerAction =
|
||||
| BalancerFlushAction
|
||||
| NetworkSwitchRequestedAction
|
||||
| BalancerAutoAction
|
||||
| BalancerManualAction
|
||||
| BalancerNetworkSwitchRequestedAction
|
||||
| NetworkSwitchSucceededAction;
|
||||
|
||||
export type NodeAction = NodeOnlineAction | NodeOfflineAction | NodeAddedAction | NodeRemovedAction;
|
||||
|
@ -9,12 +9,14 @@ export enum TypeKeys {
|
||||
WORKER_KILLED = 'WORKER_KILLED',
|
||||
|
||||
BALANCER_FLUSH = 'BALANCER_FLUSH',
|
||||
BALANCER_AUTO = 'BALANCER_AUTO',
|
||||
BALANCER_MANUAL = 'BALANCER_MANUAL',
|
||||
|
||||
NODE_CALL_REQUESTED = 'NODE_CALL_REQUESTED',
|
||||
NODE_CALL_TIMEOUT = 'NODE_CALL_TIMEOUT',
|
||||
NODE_CALL_SUCCEEDED = 'NODE_CALL_SUCCEEDED',
|
||||
NODE_CALL_FAILED = 'NODE_CALL_FAILED',
|
||||
|
||||
NETWORK_SWTICH_REQUESTED = 'NETWORK_SWTICH_REQUESTED',
|
||||
NETWORK_SWITCH_SUCCEEDED = 'NETWORK_SWITCH_SUCCEEDED'
|
||||
BALANCER_NETWORK_SWTICH_REQUESTED = 'BALANCER_NETWORK_SWTICH_REQUESTED',
|
||||
BALANCER_NETWORK_SWITCH_SUCCEEDED = 'BALANCER_NETWORK_SWITCH_SUCCEEDED'
|
||||
}
|
||||
|
217
common/components/Header/components/NetworksAndNodesDropdown.tsx
Normal file
217
common/components/Header/components/NetworksAndNodesDropdown.tsx
Normal file
@ -0,0 +1,217 @@
|
||||
import {
|
||||
TChangeNodeIntent,
|
||||
TAddCustomNode,
|
||||
TRemoveCustomNode,
|
||||
TAddCustomNetwork,
|
||||
AddCustomNodeAction,
|
||||
changeNodeIntent,
|
||||
addCustomNode,
|
||||
removeCustomNode,
|
||||
addCustomNetwork,
|
||||
changeNetwork,
|
||||
TChangeNetwork
|
||||
} from 'actions/config';
|
||||
import { ColorDropdown } from 'components/ui';
|
||||
import React, { Component } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import CustomNodeModal from './CustomNodeModal';
|
||||
import { NodeConfig } from 'types/node';
|
||||
import { AppState } from 'reducers';
|
||||
import {
|
||||
isNodeChanging,
|
||||
getNodeId,
|
||||
getNodeConfig,
|
||||
CustomNodeOption,
|
||||
NodeOption,
|
||||
getNodeOptions,
|
||||
getNetworkOptions,
|
||||
NetworkOptions,
|
||||
getSelectedNetwork
|
||||
} from 'selectors/config';
|
||||
import { connect } from 'react-redux';
|
||||
import { isManual } from 'selectors/nodeBalancer';
|
||||
|
||||
interface DispatchProps {
|
||||
changeNetwork: TChangeNetwork;
|
||||
changeNodeIntent: TChangeNodeIntent;
|
||||
addCustomNode: TAddCustomNode;
|
||||
removeCustomNode: TRemoveCustomNode;
|
||||
addCustomNetwork: TAddCustomNetwork;
|
||||
}
|
||||
|
||||
interface StateProps {
|
||||
networkOptions: NetworkOptions;
|
||||
isBalancerOnManual: boolean;
|
||||
currentNetworkId: string;
|
||||
node: NodeConfig;
|
||||
nodeSelection: AppState['config']['nodes']['selectedNode']['nodeId'];
|
||||
isChangingNode: AppState['config']['nodes']['selectedNode']['pending'];
|
||||
nodeOptions: (CustomNodeOption | NodeOption)[];
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: AppState): StateProps => ({
|
||||
isBalancerOnManual: isManual(state),
|
||||
networkOptions: getNetworkOptions(state),
|
||||
isChangingNode: isNodeChanging(state),
|
||||
nodeSelection: getNodeId(state),
|
||||
node: getNodeConfig(state),
|
||||
nodeOptions: getNodeOptions(state),
|
||||
currentNetworkId: getSelectedNetwork(state)
|
||||
});
|
||||
|
||||
const mapDispatchToProps: DispatchProps = {
|
||||
changeNetwork,
|
||||
changeNodeIntent,
|
||||
addCustomNode,
|
||||
removeCustomNode,
|
||||
addCustomNetwork
|
||||
};
|
||||
|
||||
interface State {
|
||||
isAddingCustomNode: boolean;
|
||||
}
|
||||
|
||||
type Props = StateProps & DispatchProps;
|
||||
|
||||
class DropDown extends Component<Props, State> {
|
||||
public state: State = {
|
||||
isAddingCustomNode: false
|
||||
};
|
||||
|
||||
public render() {
|
||||
const {
|
||||
node,
|
||||
nodeSelection,
|
||||
isChangingNode,
|
||||
nodeOptions,
|
||||
currentNetworkId,
|
||||
networkOptions,
|
||||
isBalancerOnManual
|
||||
} = this.props;
|
||||
const { isAddingCustomNode } = this.state;
|
||||
|
||||
const nodeOpts = nodeOptions.map(n => {
|
||||
if (n.isCustom) {
|
||||
const { name: { networkId, nodeId }, isCustom, id, ...rest } = n;
|
||||
return {
|
||||
...rest,
|
||||
name: (
|
||||
<span>
|
||||
{networkId} - {nodeId} <small>(custom)</small>
|
||||
</span>
|
||||
),
|
||||
onRemove: () => this.props.removeCustomNode({ id })
|
||||
};
|
||||
} else {
|
||||
const { name: { networkId, service }, isCustom, ...rest } = n;
|
||||
return {
|
||||
...rest,
|
||||
name: (
|
||||
<span>
|
||||
{networkId} <small>({service})</small>
|
||||
</span>
|
||||
)
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
const networkOpts = networkOptions.map(n => {
|
||||
const { networkId } = n;
|
||||
return {
|
||||
value: n.networkId,
|
||||
name: (
|
||||
<span>
|
||||
{networkId} <small>{n.isCustom ? '(custom)' : ''}</small>
|
||||
</span>
|
||||
)
|
||||
// onRemove: () => this.props.removeCustomNode({ id })
|
||||
};
|
||||
});
|
||||
|
||||
const addCustomNodeItem = (
|
||||
<li>
|
||||
<a onClick={this.openCustomNodeModal}>Add Custom Node</a>
|
||||
</li>
|
||||
);
|
||||
|
||||
const nodeDropDown = (
|
||||
<ColorDropdown
|
||||
ariaLabel={`
|
||||
change node. current node is on the ${node.network} network
|
||||
provided by ${node.service}
|
||||
`}
|
||||
options={nodeOpts}
|
||||
value={nodeSelection}
|
||||
extra={
|
||||
<>
|
||||
{addCustomNodeItem}
|
||||
<li>
|
||||
<a onClick={() => {}}> Switch to auto network mode </a>
|
||||
</li>
|
||||
</>
|
||||
}
|
||||
disabled={nodeSelection === 'web3'}
|
||||
onChange={this.props.changeNodeIntent}
|
||||
size="smr"
|
||||
color="white"
|
||||
menuAlign="right"
|
||||
/>
|
||||
);
|
||||
const networkDropDown = (
|
||||
<ColorDropdown
|
||||
ariaLabel={``}
|
||||
options={networkOpts}
|
||||
value={currentNetworkId}
|
||||
extra={
|
||||
<>
|
||||
{addCustomNodeItem}
|
||||
<li>
|
||||
<a onClick={() => {}}> Switch to manual node selection </a>
|
||||
</li>>
|
||||
</>
|
||||
}
|
||||
disabled={nodeSelection === 'web3'}
|
||||
onChange={(networkId: string) => {
|
||||
this.props.changeNetwork({ networkId });
|
||||
}}
|
||||
size="smr"
|
||||
color="white"
|
||||
menuAlign="right"
|
||||
/>
|
||||
);
|
||||
return (
|
||||
<>
|
||||
<div
|
||||
className={classnames({
|
||||
'Header-branding-right-dropdown': true,
|
||||
'is-flashing': isChangingNode
|
||||
})}
|
||||
>
|
||||
{isBalancerOnManual ? nodeDropDown : networkDropDown}
|
||||
</div>
|
||||
|
||||
{isAddingCustomNode && (
|
||||
<CustomNodeModal
|
||||
addCustomNode={this.addCustomNode}
|
||||
handleClose={this.closeCustomNodeModal}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
private openCustomNodeModal = () => {
|
||||
this.setState({ isAddingCustomNode: true });
|
||||
};
|
||||
|
||||
private closeCustomNodeModal = () => {
|
||||
this.setState({ isAddingCustomNode: false });
|
||||
};
|
||||
|
||||
private addCustomNode = (payload: AddCustomNodeAction['payload']) => {
|
||||
this.setState({ isAddingCustomNode: false });
|
||||
this.props.addCustomNode(payload);
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(DropDown);
|
@ -1,130 +1,60 @@
|
||||
import {
|
||||
TChangeLanguage,
|
||||
TChangeNodeIntent,
|
||||
TAddCustomNode,
|
||||
TRemoveCustomNode,
|
||||
TAddCustomNetwork,
|
||||
AddCustomNodeAction,
|
||||
changeLanguage,
|
||||
changeNodeIntent,
|
||||
addCustomNode,
|
||||
removeCustomNode,
|
||||
addCustomNetwork
|
||||
} from 'actions/config';
|
||||
import { TChangeLanguage, changeLanguage } from 'actions/config';
|
||||
import logo from 'assets/images/logo-mycrypto.svg';
|
||||
import { Dropdown, ColorDropdown } from 'components/ui';
|
||||
import { Dropdown } from 'components/ui';
|
||||
import React, { Component } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { Link } from 'react-router-dom';
|
||||
import { TSetGasPriceField, setGasPriceField } from 'actions/transaction';
|
||||
import { ANNOUNCEMENT_MESSAGE, ANNOUNCEMENT_TYPE, languages } from 'config';
|
||||
import Navigation from './components/Navigation';
|
||||
import CustomNodeModal from './components/CustomNodeModal';
|
||||
|
||||
import OnlineStatus from './components/OnlineStatus';
|
||||
import { getKeyByValue } from 'utils/helpers';
|
||||
import { NodeConfig } from 'types/node';
|
||||
|
||||
import './index.scss';
|
||||
import { AppState } from 'reducers';
|
||||
import {
|
||||
getOffline,
|
||||
isNodeChanging,
|
||||
getLanguageSelection,
|
||||
getNodeId,
|
||||
getNodeConfig,
|
||||
CustomNodeOption,
|
||||
NodeOption,
|
||||
getNodeOptions,
|
||||
getNetworkConfig
|
||||
} from 'selectors/config';
|
||||
import { NetworkConfig } from 'types/network';
|
||||
import { connect } from 'react-redux';
|
||||
import NetworksAndNodesDropdown from 'components/Header/components/NetworksAndNodesDropdown';
|
||||
|
||||
interface DispatchProps {
|
||||
changeLanguage: TChangeLanguage;
|
||||
changeNodeIntent: TChangeNodeIntent;
|
||||
setGasPriceField: TSetGasPriceField;
|
||||
addCustomNode: TAddCustomNode;
|
||||
removeCustomNode: TRemoveCustomNode;
|
||||
addCustomNetwork: TAddCustomNetwork;
|
||||
}
|
||||
|
||||
interface StateProps {
|
||||
network: NetworkConfig;
|
||||
languageSelection: AppState['config']['meta']['languageSelection'];
|
||||
node: NodeConfig;
|
||||
nodeSelection: AppState['config']['nodes']['selectedNode']['nodeId'];
|
||||
isChangingNode: AppState['config']['nodes']['selectedNode']['pending'];
|
||||
isOffline: AppState['config']['meta']['offline'];
|
||||
nodeOptions: (CustomNodeOption | NodeOption)[];
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: AppState): StateProps => ({
|
||||
isOffline: getOffline(state),
|
||||
isChangingNode: isNodeChanging(state),
|
||||
languageSelection: getLanguageSelection(state),
|
||||
nodeSelection: getNodeId(state),
|
||||
node: getNodeConfig(state),
|
||||
nodeOptions: getNodeOptions(state),
|
||||
network: getNetworkConfig(state)
|
||||
});
|
||||
|
||||
const mapDispatchToProps: DispatchProps = {
|
||||
setGasPriceField,
|
||||
changeLanguage,
|
||||
changeNodeIntent,
|
||||
addCustomNode,
|
||||
removeCustomNode,
|
||||
addCustomNetwork
|
||||
changeLanguage
|
||||
};
|
||||
|
||||
interface State {
|
||||
isAddingCustomNode: boolean;
|
||||
}
|
||||
|
||||
type Props = StateProps & DispatchProps;
|
||||
|
||||
class Header extends Component<Props, State> {
|
||||
public state = {
|
||||
isAddingCustomNode: false
|
||||
};
|
||||
|
||||
class Header extends Component<Props> {
|
||||
public render() {
|
||||
const {
|
||||
languageSelection,
|
||||
node,
|
||||
nodeSelection,
|
||||
isChangingNode,
|
||||
isOffline,
|
||||
nodeOptions,
|
||||
network
|
||||
} = this.props;
|
||||
const { isAddingCustomNode } = this.state;
|
||||
const { languageSelection, isChangingNode, isOffline, network } = this.props;
|
||||
|
||||
const selectedLanguage = languageSelection;
|
||||
const LanguageDropDown = Dropdown as new () => Dropdown<typeof selectedLanguage>;
|
||||
const options = nodeOptions.map(n => {
|
||||
if (n.isCustom) {
|
||||
const { name: { networkId, nodeId }, isCustom, id, ...rest } = n;
|
||||
return {
|
||||
...rest,
|
||||
name: (
|
||||
<span>
|
||||
{networkId} - {nodeId} <small>(custom)</small>
|
||||
</span>
|
||||
),
|
||||
onRemove: () => this.props.removeCustomNode({ id })
|
||||
};
|
||||
} else {
|
||||
const { name: { networkId, service }, isCustom, ...rest } = n;
|
||||
return {
|
||||
...rest,
|
||||
name: (
|
||||
<span>
|
||||
{networkId} <small>({service})</small>
|
||||
</span>
|
||||
)
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<div className="Header">
|
||||
@ -174,37 +104,13 @@ class Header extends Component<Props, State> {
|
||||
'is-flashing': isChangingNode
|
||||
})}
|
||||
>
|
||||
<ColorDropdown
|
||||
ariaLabel={`
|
||||
change node. current node is on the ${node.network} network
|
||||
provided by ${node.service}
|
||||
`}
|
||||
options={options}
|
||||
value={nodeSelection || ''}
|
||||
extra={
|
||||
<li>
|
||||
<a onClick={this.openCustomNodeModal}>Add Custom Node</a>
|
||||
</li>
|
||||
}
|
||||
disabled={nodeSelection === 'web3'}
|
||||
onChange={this.props.changeNodeIntent}
|
||||
size="smr"
|
||||
color="white"
|
||||
menuAlign="right"
|
||||
/>
|
||||
<NetworksAndNodesDropdown />
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
<Navigation color={!network.isCustom && network.color} />
|
||||
|
||||
{isAddingCustomNode && (
|
||||
<CustomNodeModal
|
||||
addCustomNode={this.addCustomNode}
|
||||
handleClose={this.closeCustomNodeModal}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@ -215,19 +121,6 @@ class Header extends Component<Props, State> {
|
||||
this.props.changeLanguage(key);
|
||||
}
|
||||
};
|
||||
|
||||
private openCustomNodeModal = () => {
|
||||
this.setState({ isAddingCustomNode: true });
|
||||
};
|
||||
|
||||
private closeCustomNodeModal = () => {
|
||||
this.setState({ isAddingCustomNode: false });
|
||||
};
|
||||
|
||||
private addCustomNode = (payload: AddCustomNodeAction['payload']) => {
|
||||
this.setState({ isAddingCustomNode: false });
|
||||
this.props.addCustomNode(payload);
|
||||
};
|
||||
}
|
||||
|
||||
export default connect(mapStateToProps, mapDispatchToProps)(Header);
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ChangeLanguageAction, SetLatestBlockAction, MetaAction } from 'actions/config';
|
||||
import { TypeKeys } from 'actions/config/constants';
|
||||
import {
|
||||
NetworkSwitchRequestedAction,
|
||||
BalancerNetworkSwitchRequestedAction,
|
||||
TypeKeys as NodeBalancerTypeKeys,
|
||||
NodeBalancerAction
|
||||
} from 'actions/nodeBalancer';
|
||||
@ -20,7 +20,7 @@ const INITIAL_STATE: State = {
|
||||
latestBlock: '???'
|
||||
};
|
||||
|
||||
function handleNetworkSwitchRequested(state: State, _: NetworkSwitchRequestedAction) {
|
||||
function handleNetworkSwitchRequested(state: State, _: BalancerNetworkSwitchRequestedAction) {
|
||||
return {
|
||||
...state,
|
||||
offline: true
|
||||
@ -69,7 +69,7 @@ export function meta(state: State = INITIAL_STATE, action: MetaAction | NodeBala
|
||||
case TypeKeys.CONFIG_SET_LATEST_BLOCK:
|
||||
return setLatestBlock(state, action);
|
||||
|
||||
case NodeBalancerTypeKeys.NETWORK_SWTICH_REQUESTED:
|
||||
case NodeBalancerTypeKeys.BALANCER_NETWORK_SWTICH_REQUESTED:
|
||||
return handleNetworkSwitchRequested(state, action);
|
||||
default:
|
||||
return state;
|
||||
|
@ -1,15 +1,18 @@
|
||||
import { customNetworks, State as CustomNetworksState } from './customNetworks';
|
||||
import { staticNetworks, State as StaticNetworksState } from './staticNetworks';
|
||||
import { selectedNetwork, State as SelectedNetworkState } from './selectedNetwork';
|
||||
import { combineReducers } from 'redux';
|
||||
|
||||
interface State {
|
||||
customNetworks: CustomNetworksState;
|
||||
staticNetworks: StaticNetworksState;
|
||||
selectedNetwork: SelectedNetworkState;
|
||||
}
|
||||
|
||||
const networks = combineReducers<State>({
|
||||
customNetworks,
|
||||
staticNetworks
|
||||
staticNetworks,
|
||||
selectedNetwork
|
||||
});
|
||||
|
||||
export { State, networks, StaticNetworksState, CustomNetworksState };
|
||||
export { State, networks, StaticNetworksState, CustomNetworksState, SelectedNetworkState };
|
||||
|
17
common/reducers/config/networks/selectedNetwork.ts
Normal file
17
common/reducers/config/networks/selectedNetwork.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { TypeKeys, ChangeNetworkAction, NetworkAction } from 'actions/config';
|
||||
import { StaticNetworkIds } from 'types/network';
|
||||
|
||||
export type State = StaticNetworkIds;
|
||||
|
||||
const INITIAL_STATE: State = 'ETH';
|
||||
|
||||
const handleNetworkChange = (_: State, { payload }: ChangeNetworkAction) => payload.networkId;
|
||||
|
||||
export const selectedNetwork = (state: State = INITIAL_STATE, action: NetworkAction) => {
|
||||
switch (action.type) {
|
||||
case TypeKeys.CONFIG_NETWORK_CHANGE:
|
||||
return handleNetworkChange(state, action);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
@ -33,57 +33,68 @@ export const INITIAL_STATE: State = {
|
||||
pLib: new PInfuraNode('https://mainnet.infura.io/mew'),
|
||||
|
||||
estimateGas: false
|
||||
}
|
||||
/*
|
||||
},
|
||||
|
||||
rop_infura: {
|
||||
network: 'Ropsten',
|
||||
isCustom: false,
|
||||
service: 'infura.io',
|
||||
lib: new InfuraNode('https://ropsten.infura.io/mew'),
|
||||
lib: InfuraNode('https://ropsten.infura.io/mew'),
|
||||
pLib: new PInfuraNode('https://ropsten.infura.io/mew'),
|
||||
estimateGas: false
|
||||
},
|
||||
kov_ethscan: {
|
||||
network: 'Kovan',
|
||||
isCustom: false,
|
||||
service: 'Etherscan.io',
|
||||
lib: new EtherscanNode('https://kovan.etherscan.io/api'),
|
||||
pLib: new PEtherscanNode('https://kovan.etherscan.io/api'),
|
||||
lib: EtherscanNode('https://kovan.etherscan.io/api'),
|
||||
estimateGas: false
|
||||
},
|
||||
rin_ethscan: {
|
||||
network: 'Rinkeby',
|
||||
isCustom: false,
|
||||
service: 'Etherscan.io',
|
||||
lib: new EtherscanNode('https://rinkeby.etherscan.io/api'),
|
||||
lib: EtherscanNode('https://rinkeby.etherscan.io/api'),
|
||||
pLib: new PEtherscanNode('https://rinkeby.etherscan.io/api'),
|
||||
|
||||
estimateGas: false
|
||||
},
|
||||
rin_infura: {
|
||||
network: 'Rinkeby',
|
||||
isCustom: false,
|
||||
service: 'infura.io',
|
||||
lib: new InfuraNode('https://rinkeby.infura.io/mew'),
|
||||
lib: InfuraNode('https://rinkeby.infura.io/mew'),
|
||||
pLib: new PInfuraNode('https://rinkeby.infura.io/mew'),
|
||||
estimateGas: false
|
||||
},
|
||||
etc_epool: {
|
||||
network: 'ETC',
|
||||
isCustom: false,
|
||||
service: 'Epool.io',
|
||||
lib: new RPCNode('https://mewapi.epool.io'),
|
||||
lib: RPCNode('https://mewapi.epool.io'),
|
||||
pLib: new PRPCNode('https://mewapi.epool.io'),
|
||||
|
||||
estimateGas: false
|
||||
},
|
||||
ubq: {
|
||||
network: 'UBQ',
|
||||
isCustom: false,
|
||||
service: 'ubiqscan.io',
|
||||
lib: new RPCNode('https://pyrus2.ubiqscan.io'),
|
||||
lib: RPCNode('https://pyrus2.ubiqscan.io'),
|
||||
pLib: new PRPCNode('https://pyrus2.ubiqscan.io'),
|
||||
|
||||
estimateGas: true
|
||||
},
|
||||
exp_tech: {
|
||||
network: 'EXP',
|
||||
isCustom: false,
|
||||
service: 'Expanse.tech',
|
||||
lib: new RPCNode('https://node.expanse.tech/'),
|
||||
lib: RPCNode('https://node.expanse.tech/'),
|
||||
pLib: new PRPCNode('https://node.expanse.tech/'),
|
||||
|
||||
estimateGas: true
|
||||
}*/
|
||||
}
|
||||
};
|
||||
|
||||
export const staticNodes = (state: State = INITIAL_STATE, action: NodeAction) => {
|
||||
|
36
common/reducers/nodeBalancer/balancerConfig.ts
Normal file
36
common/reducers/nodeBalancer/balancerConfig.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { TypeKeys } from 'actions/nodeBalancer/constants';
|
||||
import { Reducer } from 'redux';
|
||||
import { BalancerAction, BalancerAutoAction } from 'actions/nodeBalancer';
|
||||
|
||||
export interface State {
|
||||
manual: boolean;
|
||||
offline: boolean;
|
||||
}
|
||||
|
||||
const INITIAL_STATE: State = {
|
||||
manual: false,
|
||||
offline: false
|
||||
};
|
||||
|
||||
const handleBalancerAuto: Reducer<State> = (state: State, _: BalancerAutoAction) => ({
|
||||
...state,
|
||||
manual: false
|
||||
});
|
||||
const handleBalancerManual: Reducer<State> = (state: State, _: BalancerAutoAction) => ({
|
||||
...state,
|
||||
manual: true
|
||||
});
|
||||
|
||||
export const balancerConfig: Reducer<State> = (
|
||||
state: State = INITIAL_STATE,
|
||||
action: BalancerAction
|
||||
): State => {
|
||||
switch (action.type) {
|
||||
case TypeKeys.BALANCER_AUTO:
|
||||
return handleBalancerAuto(state, action);
|
||||
case TypeKeys.BALANCER_MANUAL:
|
||||
return handleBalancerManual(state, action);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
};
|
@ -1,10 +1,16 @@
|
||||
import { nodes, State as NodeState } from './nodes';
|
||||
import { State as WorkerState, workers } from './workers';
|
||||
import { State as BalancerConfigState, balancerConfig } from './balancerConfig';
|
||||
import { combineReducers } from 'redux';
|
||||
|
||||
export interface State {
|
||||
nodes: NodeState;
|
||||
workers: WorkerState;
|
||||
balancerConfig: BalancerConfigState;
|
||||
}
|
||||
|
||||
export const nodeBalancer = combineReducers({ nodes, workers });
|
||||
export const nodeBalancer = combineReducers({
|
||||
nodes,
|
||||
workers,
|
||||
balancerConfig
|
||||
});
|
||||
|
@ -13,12 +13,9 @@ import {
|
||||
BalancerFlushAction,
|
||||
BalancerAction,
|
||||
NodeRemovedAction,
|
||||
NetworkSwitchRequestedAction,
|
||||
NetworkSwitchSucceededAction
|
||||
} from 'actions/nodeBalancer';
|
||||
import { TypeKeys } from 'actions/nodeBalancer/constants';
|
||||
import { configuredStore } from 'store';
|
||||
import { getNodeConfig } from 'selectors/config';
|
||||
|
||||
export interface INodeStats {
|
||||
isCustom: boolean;
|
||||
@ -141,7 +138,7 @@ export const nodes: Reducer<State> = (
|
||||
case TypeKeys.BALANCER_FLUSH:
|
||||
return handleBalancerFlush(state, action);
|
||||
|
||||
case TypeKeys.NETWORK_SWITCH_SUCCEEDED:
|
||||
case TypeKeys.BALANCER_NETWORK_SWITCH_SUCCEEDED:
|
||||
return handleNetworkSwitch(state, action);
|
||||
default:
|
||||
return state;
|
||||
|
@ -89,7 +89,7 @@ export const workers: Reducer<State> = (
|
||||
action: WorkerAction | NodeCallAction | BalancerAction
|
||||
): State => {
|
||||
switch (action.type) {
|
||||
case TypeKeys.NETWORK_SWITCH_SUCCEEDED:
|
||||
case TypeKeys.BALANCER_NETWORK_SWITCH_SUCCEEDED:
|
||||
return handleNetworkSwitch(state, action);
|
||||
case TypeKeys.WORKER_SPAWNED:
|
||||
return handleWorkerSpawned(state, action);
|
||||
|
@ -15,7 +15,6 @@ import {
|
||||
import {
|
||||
nodeCallRequested,
|
||||
NodeCall,
|
||||
workerSpawned,
|
||||
NodeCallRequestedAction,
|
||||
nodeCallSucceeded,
|
||||
workerProcessing,
|
||||
@ -30,7 +29,7 @@ import {
|
||||
nodeOnline,
|
||||
BalancerFlushAction,
|
||||
balancerFlush,
|
||||
networkSwitchRequested,
|
||||
balancerNetworkSwitchRequested,
|
||||
NetworkSwitchSucceededAction,
|
||||
networkSwitchSucceeded
|
||||
} from 'actions/nodeBalancer';
|
||||
@ -43,10 +42,9 @@ import {
|
||||
getOffline,
|
||||
getNodeById,
|
||||
getAllNodesOfNetworkId,
|
||||
getNetworkConfig,
|
||||
getSelectedNetwork
|
||||
} from 'selectors/config';
|
||||
import { toggleOffline } from 'actions/config';
|
||||
import { toggleOffline, ChangeNetworkAction, TypeKeys as ConfigTypeKeys } from 'actions/config';
|
||||
import { StaticNodeConfig, CustomNodeConfig, NodeConfig } from '../../../shared/types/node';
|
||||
import { INodeStats } from 'reducers/nodeBalancer/nodes';
|
||||
import { IWorker } from 'reducers/nodeBalancer/workers';
|
||||
@ -72,7 +70,7 @@ interface IChannels {
|
||||
const channels: IChannels = {};
|
||||
|
||||
function* networkSwitch(): SagaIterator {
|
||||
yield put(networkSwitchRequested());
|
||||
yield put(balancerNetworkSwitchRequested());
|
||||
|
||||
//flush all existing requests
|
||||
yield put(balancerFlush());
|
||||
@ -154,7 +152,7 @@ function* networkSwitch(): SagaIterator {
|
||||
nodeStats: { ...accu.nodeStats, [currNode.nodeId]: currNode.stats },
|
||||
workers: { ...accu.workers, ...currNode.workers }
|
||||
}),
|
||||
{} as NetworkSwitchSucceededAction['payload']
|
||||
{ nodeStats: {}, workers: {} } as NetworkSwitchSucceededAction['payload']
|
||||
);
|
||||
|
||||
yield put(networkSwitchSucceeded(networkSwitchPayload));
|
||||
@ -367,6 +365,7 @@ function* flushHandler(_: BalancerFlushAction): SagaIterator {
|
||||
export function* nodeBalancer() {
|
||||
yield all([
|
||||
call(networkSwitch),
|
||||
takeEvery(ConfigTypeKeys.CONFIG_NETWORK_CHANGE, networkSwitch),
|
||||
takeEvery(TypeKeys.NODE_OFFLINE, watchOfflineNode),
|
||||
fork(handleNodeCallRequests),
|
||||
takeEvery(TypeKeys.NODE_CALL_TIMEOUT, handleCallTimeouts),
|
||||
|
@ -3,7 +3,8 @@ import {
|
||||
CustomNetworkConfig,
|
||||
StaticNetworkConfig,
|
||||
StaticNetworkIds,
|
||||
NetworkContract
|
||||
NetworkContract,
|
||||
NetworkConfig
|
||||
} from 'types/network';
|
||||
import { getNodeConfig } from 'selectors/config';
|
||||
const getConfig = (state: AppState) => state.config;
|
||||
@ -44,7 +45,7 @@ export const getStaticNetworkConfig = (state: AppState): StaticNetworkConfig | u
|
||||
return defaultNetwork;
|
||||
};
|
||||
|
||||
export const getSelectedNetwork = (state: AppState) => getNodeConfig(state).network;
|
||||
export const getSelectedNetwork = (state: AppState) => getNetworks(state).selectedNetwork;
|
||||
|
||||
export const getCustomNetworkConfig = (state: AppState): CustomNetworkConfig | undefined => {
|
||||
const selectedNetwork = getSelectedNetwork(state);
|
||||
@ -74,3 +75,18 @@ export const getNetworkContracts = (state: AppState): NetworkContract[] | null =
|
||||
export const getCustomNetworkConfigs = (state: AppState) => getNetworks(state).customNetworks;
|
||||
|
||||
export const getStaticNetworkConfigs = (state: AppState) => getNetworks(state).staticNetworks;
|
||||
|
||||
export type NetworkOptions = (NetworkConfig & { networkId: string })[];
|
||||
|
||||
export const getNetworkOptions = (state: AppState): NetworkOptions => {
|
||||
const customNetworks = getCustomNetworkConfigs(state);
|
||||
const staticNetworks = getStaticNetworkConfigs(state);
|
||||
const allNetworks: { [networkId: string]: NetworkConfig } = {
|
||||
...customNetworks,
|
||||
...staticNetworks
|
||||
};
|
||||
return Object.entries(allNetworks).map(([networkId, network]) => ({
|
||||
...network,
|
||||
networkId
|
||||
}));
|
||||
};
|
||||
|
@ -2,7 +2,6 @@ import { AppState } from 'reducers';
|
||||
import { State as NodeBalancerState, INodeStats } from 'reducers/nodeBalancer/nodes';
|
||||
import { Omit } from 'react-redux';
|
||||
import { NodeCall } from 'actions/nodeBalancer';
|
||||
import { getNodeById } from 'selectors/config';
|
||||
|
||||
const allMethods = [
|
||||
'client',
|
||||
@ -19,6 +18,11 @@ const allMethods = [
|
||||
];
|
||||
|
||||
export const getNodeBalancer = (state: AppState) => state.nodeBalancer;
|
||||
|
||||
export const getBalancerConfig = (state: AppState) => getNodeBalancer(state).balancerConfig;
|
||||
|
||||
export const isManual = (state: AppState) => getBalancerConfig(state).manual;
|
||||
|
||||
export const getNodesState = (state: AppState) => getNodeBalancer(state).nodes;
|
||||
|
||||
export type AvailableNodes = {
|
||||
|
Loading…
x
Reference in New Issue
Block a user