Skip to content

Commit

Permalink
fix: update model
Browse files Browse the repository at this point in the history
  • Loading branch information
sokolova-an committed Apr 5, 2024
1 parent d8c5b2f commit 8b1ea98
Show file tree
Hide file tree
Showing 11 changed files with 103 additions and 55 deletions.
15 changes: 15 additions & 0 deletions src/renderer/entities/network/model/network-model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,20 @@ const updateConnectionFx = createEffect((connection: Connection): Promise<Connec
return storageService.connections.put(connection);
});

type DisconnectParams = {
chainId: ChainId;
providers: Record<ChainId, ProviderWithMetadata>;
};
const disconnectProviderFx = createEffect(async ({ chainId, providers }: DisconnectParams): Promise<ChainId> => {
await providers[chainId].disconnect();

providers[chainId].on('connected', () => undefined);
providers[chainId].on('disconnected', () => undefined);
providers[chainId].on('error', () => undefined);

return chainId;
});

type CreateProviderParams = {
chainId: ChainId;
nodes: string[];
Expand Down Expand Up @@ -407,5 +421,6 @@ export const networkModel = {
},
effects: {
updateConnectionFx,
disconnectProviderFx,
},
};
2 changes: 1 addition & 1 deletion src/renderer/features/network/NetworkSelector/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export { NetworkSelector } from './ui/NetworkSelector';
export { networkSelectorUtils } from './lib/network-selector-utils';
export { networkSelectorModel } from './model/network-selector-model';
export type { SelectorPayload, ConnectionList } from './lib/types';
export type { SelectorPayload, ConnectionItem } from './lib/types';
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import { ExtendedChain } from '@entities/network';
import { ConnectionType } from '@shared/core';
import { ConnectionList } from './types';
import { ConnectionItem } from './types';

export const networkSelectorUtils = {
getConnectionsList,
canDeleteNode,
};

function getConnectionsList(networkItem: ExtendedChain): ConnectionList[] {
function getConnectionsList(networkItem: ExtendedChain): ConnectionItem[] {
const { connection, nodes } = networkItem;
const { canUseLightClient, customNodes } = connection;

Expand All @@ -16,8 +17,20 @@ function getConnectionsList(networkItem: ExtendedChain): ConnectionList[] {
{ type: ConnectionType.DISABLED },
];

const customs = (customNodes || []).map((node) => ({ node, type: ConnectionType.RPC_NODE, isCustom: true }));
const nodesWithType = nodes.map((node) => ({ node, type: ConnectionType.RPC_NODE, isCustom: false }));
const customs = (customNodes || []).map((node) => ({
node,
type: ConnectionType.RPC_NODE,
isCustom: true,
}));
const nodesWithType = nodes.map((node) => ({
node,
type: ConnectionType.RPC_NODE,
isCustom: false,
}));

return [...actionNodes, ...nodesWithType, ...customs];
}

function canDeleteNode(nodeUrl: string, selectedConnectionUrl?: string): boolean {
return selectedConnectionUrl !== nodeUrl;
}
2 changes: 1 addition & 1 deletion src/renderer/features/network/NetworkSelector/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export type SelectorPayload = {
node?: RpcNode;
};

export type ConnectionList = {
export type ConnectionItem = {
type: ConnectionType;
node?: RpcNode;
isCustom?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { ConnectionType, Connection, RpcNode } from '@shared/core';
import { storageService } from '@shared/api/storage';
import { networkSelectorModel } from '../network-selector-model';

describe('features/network/NetworkSelector/model', () => {
describe('features/network/NetworkSelector/model/network-selector-model', () => {
const getMockConnection = (type: ConnectionType, activeNode?: RpcNode): Connection => ({
id: 1,
chainId: '0x01',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { createEvent, sample, createEffect, attach } from 'effector';
import { createEvent, sample, attach } from 'effector';
import { delay, spread } from 'patronum';

import { ProviderWithMetadata } from '@/src/renderer/shared/api/network';
import { networkModel, networkUtils } from '@entities/network';
import { ChainId, ConnectionType, RpcNode } from '@shared/core';

Expand All @@ -10,21 +9,8 @@ const autoBalanceSelected = createEvent<ChainId>();
const rpcNodeSelected = createEvent<{ chainId: ChainId; node: RpcNode }>();
const chainDisabled = createEvent<ChainId>();

const updateConnectionFx = networkModel.effects.updateConnectionFx;

type DisconnectParams = {
chainId: ChainId;
providers: Record<ChainId, ProviderWithMetadata>;
};
const disconnectProviderFx = createEffect(async ({ chainId, providers }: DisconnectParams): Promise<ChainId> => {
await providers[chainId].disconnect();

providers[chainId].on('connected', () => undefined);
providers[chainId].on('disconnected', () => undefined);
providers[chainId].on('error', () => undefined);

return chainId;
});
const updateConnectionFx = attach({ effect: networkModel.effects.updateConnectionFx });
const disconnectProviderFx = attach({ effect: networkModel.effects.disconnectProviderFx });

const reconnectProviderFx = attach({ effect: disconnectProviderFx });

Expand Down Expand Up @@ -67,6 +53,7 @@ sample({
fn: (connections, chainId) => ({
...connections[chainId],
connectionType: ConnectionType.DISABLED,
activeNode: undefined,
}),
target: updateConnectionFx,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import { TFunction } from 'react-i18next';
import { cnTw } from '@shared/lib/utils';
import { Icon, FootnoteText, IconButton, Button, HelpText } from '@shared/ui';
import { useI18n } from '@app/providers';
import type { ConnectionList, SelectorPayload } from '../lib/types';
import { SelectButtonStyle, OptionStyle } from '@shared/ui/Dropdowns/common/constants';
import { useScrollTo } from '@shared/lib/hooks';
import { CommonInputStyles, CommonInputStylesTheme } from '@shared/ui/Inputs/common/styles';
import { ConnectionType } from '@shared/core';
import { networkSelectorUtils } from '../lib/network-selector-utils';
import type { Theme } from '@shared/ui/types';
import type { RpcNode } from '@shared/core';
import type { ConnectionItem, SelectorPayload } from '../lib/types';

const OptionsContainerStyle =
'mt-1 absolute z-20 py-1 px-1 w-full border border-token-container-border rounded bg-input-background shadow-card-shadow';
Expand All @@ -34,8 +35,8 @@ const Title = {
};

type Props = {
nodesList: ConnectionList[];
selectedConnection?: ConnectionList;
nodesList: ConnectionItem[];
selectedConnection?: ConnectionItem;
theme?: Theme;
onChange: (value: SelectorPayload) => void;
onRemoveCustomNode: (node: RpcNode) => void;
Expand Down Expand Up @@ -113,7 +114,7 @@ export const NetworkSelector = ({
onChangeCustomNode(node);
}}
/>
{selectedConnection?.node?.url !== node.url && (
{networkSelectorUtils.canDeleteNode(node.url, selectedConnection?.node?.url) && (
<IconButton
name="delete"
onClick={(event) => {
Expand Down
12 changes: 6 additions & 6 deletions src/renderer/pages/Settings/Networks/Networks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ export const Networks = () => {
const inactiveNetworks = useUnit(inactiveNetworksModel.$inactiveNetworks);
const connections = useUnit(networkModel.$connections);
const filterQuery = useUnit(networksFilterModel.$filterQuery);
const enabledNodeListMap = useUnit(networksOverviewModel.$enabledNodeListMap);
const disabledNodeListMap = useUnit(networksOverviewModel.$disabledNodeListMap);
const activeConnectionsMap = useUnit(networksOverviewModel.$activeConnectionsMap);
const inactiveConnectionsMap = useUnit(networksOverviewModel.$inactiveConnectionsMap);

const [isCustomRpcOpen, toggleCustomRpc] = useToggle();
const [isNetworksModalOpen, toggleNetworksModal] = useToggle(true);
Expand Down Expand Up @@ -214,8 +214,8 @@ export const Networks = () => {
{(network) => (
<InactiveNetwork networkItem={network}>
<NetworkSelector
nodesList={disabledNodeListMap[network.chainId].nodes}
selectedConnection={disabledNodeListMap[network.chainId].selectedNode}
nodesList={inactiveConnectionsMap[network.chainId].nodes}
selectedConnection={inactiveConnectionsMap[network.chainId].selectedNode}
onChange={changeConnection(network)}
onRemoveCustomNode={removeCustomNode(network.chainId)}
onChangeCustomNode={changeCustomNode(network)}
Expand All @@ -232,8 +232,8 @@ export const Networks = () => {
{(network) => (
<ActiveNetwork networkItem={network}>
<NetworkSelector
nodesList={enabledNodeListMap[network.chainId].nodes}
selectedConnection={enabledNodeListMap[network.chainId].selectedNode}
nodesList={activeConnectionsMap[network.chainId].nodes}
selectedConnection={activeConnectionsMap[network.chainId].selectedNode}
onChange={changeConnection(network)}
onRemoveCustomNode={removeCustomNode(network.chainId)}
onChangeCustomNode={changeCustomNode(network)}
Expand Down
11 changes: 11 additions & 0 deletions src/renderer/pages/Settings/Networks/lib/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { ConnectionType, RpcNode } from '@shared/core';

export const Predicates: Record<
ConnectionType,
(data: { type: ConnectionType; node?: RpcNode }, active?: RpcNode) => boolean
> = {
[ConnectionType.LIGHT_CLIENT]: (data) => data.type === ConnectionType.LIGHT_CLIENT,
[ConnectionType.AUTO_BALANCE]: (data) => data.type === ConnectionType.AUTO_BALANCE,
[ConnectionType.DISABLED]: (data) => data.type === ConnectionType.DISABLED,
[ConnectionType.RPC_NODE]: (data, active) => data.node?.url === active?.url,
};
34 changes: 32 additions & 2 deletions src/renderer/pages/Settings/Networks/model/manage-network-model.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { createEvent, sample, attach } from 'effector';
import { spread } from 'patronum';

import { networkModel } from '@entities/network';
import { networkModel, networkUtils } from '@entities/network';
import { ChainId, RpcNode } from '@shared/core';

// TODO: create 2 features for Network selection & Manage custom RPC
Expand All @@ -14,10 +15,11 @@ const rpcNodeAdded = createEvent<NodeEventParams>();
const rpcNodeUpdated = createEvent<NodeEventParams>();
const rpcNodeRemoved = createEvent<NodeEventParams>();

const updateConnectionFx = networkModel.effects.updateConnectionFx;
const updateConnectionFx = attach({ effect: networkModel.effects.updateConnectionFx });

const addRpcNodeFx = attach({ effect: updateConnectionFx });
const removeRpcNodeFx = attach({ effect: updateConnectionFx });
const reconnectProviderFx = attach({ effect: networkModel.effects.disconnectProviderFx });

sample({
clock: rpcNodeAdded,
Expand Down Expand Up @@ -79,6 +81,34 @@ sample({
target: updateConnectionFx,
});

sample({
clock: updateConnectionFx.doneData,
source: networkModel.$connections,
filter: (connection) => Boolean(connection),
fn: (connections, connection) => ({
...connections,
[connection!.chainId]: connection,
}),
target: networkModel.$connections,
});

sample({
clock: updateConnectionFx.doneData,
source: networkModel.$providers,
filter: (_, connection) => {
return Boolean(connection) && networkUtils.isEnabledConnection(connection!);
},
fn: (providers, connection) => {
const chainId = connection!.chainId;

return providers[chainId] ? { reconnect: { chainId, providers } } : { start: chainId };
},
target: spread({
start: networkModel.events.chainConnected,
reconnect: reconnectProviderFx,
}),
});

export const manageNetworkModel = {
events: {
rpcNodeAdded,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,22 @@
import { sample, combine } from 'effector';

import { ChainId, ConnectionType, RpcNode } from '@shared/core';
import { ChainId } from '@shared/core';
import type { ConnectionItem } from '@features/network/NetworkSelector';
import {
networksFilterModel,
activeNetworksModel,
inactiveNetworksModel,
networkSelectorUtils,
} from '@features/network';
import { ConnectionList } from '@/src/renderer/features/network/NetworkSelector';
import { Predicates } from '../lib/constants';

sample({
clock: networksFilterModel.$filteredNetworks,
target: [activeNetworksModel.events.networksChanged, inactiveNetworksModel.events.networksChanged],
});

const Predicates: Record<
ConnectionType,
(data: { type: ConnectionType; node?: RpcNode }, active?: RpcNode) => boolean
> = {
[ConnectionType.LIGHT_CLIENT]: (data) => data.type === ConnectionType.LIGHT_CLIENT,
[ConnectionType.AUTO_BALANCE]: (data) => data.type === ConnectionType.AUTO_BALANCE,
[ConnectionType.DISABLED]: (data) => data.type === ConnectionType.DISABLED,
[ConnectionType.RPC_NODE]: (data, active) => data.node?.url === active?.url,
};

const $enabledNodeListMap = combine(activeNetworksModel.$activeNetworks, (list) => {
return list.reduce<Record<ChainId, { nodes: ConnectionList[]; selectedNode?: ConnectionList }>>((acc, item) => {
const $activeConnectionsMap = combine(activeNetworksModel.$activeNetworks, (list) => {
return list.reduce<Record<ChainId, { nodes: ConnectionItem[]; selectedNode?: ConnectionItem }>>((acc, item) => {
const nodes = networkSelectorUtils.getConnectionsList(item);
const selectedNode = nodes.find((node) =>
Predicates[item.connection.connectionType]({ type: node.type, node: node.node }, item.connection.activeNode),
Expand All @@ -37,10 +28,10 @@ const $enabledNodeListMap = combine(activeNetworksModel.$activeNetworks, (list)
}, {});
});

const $disabledNodeListMap = combine(inactiveNetworksModel.$inactiveNetworks, (list) => {
return list.reduce<Record<ChainId, { nodes: ConnectionList[]; selectedNode?: ConnectionList }>>((acc, item) => {
const $inactiveConnectionsMap = combine(inactiveNetworksModel.$inactiveNetworks, (list) => {
return list.reduce<Record<ChainId, { nodes: ConnectionItem[]; selectedNode: ConnectionItem }>>((acc, item) => {
const nodes = networkSelectorUtils.getConnectionsList(item);
const selectedNode = nodes.find((node) => node.type === item.connection.connectionType);
const selectedNode = nodes.find((node) => node.type === item.connection.connectionType)!;

acc[item.chainId] = { nodes, selectedNode };

Expand All @@ -49,6 +40,6 @@ const $disabledNodeListMap = combine(inactiveNetworksModel.$inactiveNetworks, (l
});

export const networksOverviewModel = {
$enabledNodeListMap,
$disabledNodeListMap,
$activeConnectionsMap,
$inactiveConnectionsMap,
};

0 comments on commit 8b1ea98

Please sign in to comment.