Skip to content

Commit

Permalink
2.1.12 (#648)
Browse files Browse the repository at this point in the history
* generate login modal icons from both apiEndpoint and nodeAddress

* change the node icon in the navbar once nodeAddress is loaded

* change the node icon in the navbar based on localStorage

* better config overview

* better format strategies hopr values

* move save btn in config

* open swagger and scallar ui

* peers page, nodes and peers in 1 column

* peer address and peer id in the same lines in subpages

* cleanup

* node-jazz

* scalar icon changed

* sortable tables

* format

* fix build errors

* sort peers subpage

* sort channels subpages

* format

* bold alias and alias page last seen

* format
  • Loading branch information
mjadach-iv authored Dec 3, 2024
1 parent 4bc9775 commit dca88b3
Show file tree
Hide file tree
Showing 25 changed files with 655 additions and 266 deletions.
2 changes: 1 addition & 1 deletion config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export const environment: 'dev' | 'node' | 'web3' = 'node'; //'node';
export const environment: 'dev' | 'node' | 'web3' = 'node'; //'node'; //'node';

// Smart Contracts
export const mHOPR_TOKEN_SMART_CONTRACT_ADDRESS = '0x66225dE86Cac02b32f34992eb3410F59DE416698';
Expand Down
3 changes: 1 addition & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,7 @@
"dev": "vite",
"dev:clean": "npm run dev -- --force",
"build-vite": "tsc && vite build",
"build-hub": "node ./scripts/prepare-build-hub.js && tsc && vite build && node ./scripts/post-build.js",
"build": "node ./scripts/prepare-build-node.js && tsc && vite build && node ./scripts/post-build.js",
"build": "tsc && vite build",
"test": "echo \"Error: no test specified\" && exit 0",
"serve": "vite preview --port 3000",
"format": "prettier --write src/ .github/ *.ts *.json *.md",
Expand Down
Binary file added public/assets/scalar-removebg-preview.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 0 additions & 13 deletions scripts/post-build.js

This file was deleted.

22 changes: 0 additions & 22 deletions scripts/prepare-build-hub.js

This file was deleted.

25 changes: 0 additions & 25 deletions scripts/prepare-build-node.js

This file was deleted.

31 changes: 23 additions & 8 deletions src/components/ConnectNode/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { useState, useEffect, useRef } from 'react';
import styled from '@emotion/styled';
import { Link, useNavigate } from 'react-router-dom';

Check warning on line 3 in src/components/ConnectNode/index.tsx

View workflow job for this annotation

GitHub Actions / Close release

'Link' is defined but never used
import { generateBase64Jazz } from '../../utils/functions';
import { toHexMD5, generateBase64Jazz } from '../../utils/functions';

// Components
import Modal from './modal';
Expand Down Expand Up @@ -62,10 +62,15 @@ const NodeButton = styled.div`
.node-info {
color: #414141;
line-height: 12px;
height: 12px;
white-space: nowrap;
}
.node-info-localname {
font-weight: 700;
color: #000050;
height: 12px;
line-height: 12px;
white-space: nowrap;
}
`;

Expand Down Expand Up @@ -98,11 +103,16 @@ export default function ConnectNode() {
const error = useAppSelector((store) => store.auth.status.error);
const openLoginModalToNode = useAppSelector((store) => store.auth.helper.openLoginModalToNode);
const peerId = useAppSelector((store) => store.node.addresses.data.hopr);
const localName = useAppSelector((store) => store.auth.loginData.localName);
const localNameFromLocalStorage = useAppSelector((store) => store.auth.loginData.localName);
const jazzIconFromLocalStorage = useAppSelector((store) => store.auth.loginData.jazzIcon);
const nodeAddress = useAppSelector((store) => store.node.addresses.data.native);
const localNameToDisplay =
localName && localName.length > 17
? `${localName?.substring(0, 5)}${localName?.substring(localName.length - 11, localName.length)}`
: localName;
localNameFromLocalStorage && localNameFromLocalStorage.length > 17
? `${localNameFromLocalStorage?.substring(0, 5)}${localNameFromLocalStorage?.substring(
localNameFromLocalStorage.length - 11,
localNameFromLocalStorage.length,
)}`
: localNameFromLocalStorage;
const apiEndpoint = useAppSelector((store) => store.auth.loginData.apiEndpoint);
const [nodeAddressIcon, set_nodeAddressIcon] = useState<string | null>(null);
const [anchorEl, setAnchorEl] = useState<null | HTMLElement>(null); // State variable to hold the anchor element for the menu
Expand All @@ -124,10 +134,15 @@ export default function ConnectNode() {
}, []);

useEffect(() => {
if (!connected) set_nodeAddressIcon(null);
if (!apiEndpoint) return;
const b64 = generateBase64Jazz(apiEndpoint);
if (b64) set_nodeAddressIcon(b64);
}, [apiEndpoint]);
console.log(jazzIconFromLocalStorage);
const md5 = toHexMD5(apiEndpoint);
const b64 = generateBase64Jazz(
nodeAddress ? nodeAddress : jazzIconFromLocalStorage ? jazzIconFromLocalStorage : md5,
);
if (connected && b64) set_nodeAddressIcon(b64);
}, [connected, apiEndpoint, nodeAddress, jazzIconFromLocalStorage]);

useEffect(() => {
if (error) set_modalVisible(true);
Expand Down
7 changes: 7 additions & 0 deletions src/components/ConnectNode/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type ParsedNode = {
value: string;
apiEndpoint: string;
apiToken: string;
jazzIcon?: string;
};

type ConnectNodeModalProps = {
Expand Down Expand Up @@ -138,8 +139,10 @@ function ConnectNodeModal(props: ConnectNodeModalProps) {
const [nodesSavedLocallyParsed, set_nodesSavedLocallyParsed] = useState([] as ParsedNode[]);
const errorMessage = useAppSelector((store) => store.auth.status.error?.data);
const loginData = useAppSelector((store) => store.auth.loginData);
const loginPending = useAppSelector((store) => store.auth.status.connecting);
const [searchParams, set_searchParams] = useSearchParams();
const [localName, set_localName] = useState(loginData.localName ? loginData.localName : '');
const [jazzIcon, set_jazzIcon] = useState(loginData.jazzIcon ? loginData.jazzIcon : null);
const [apiEndpoint, set_apiEndpoint] = useState(loginData.apiEndpoint ? loginData.apiEndpoint : '');
const [apiToken, set_apiToken] = useState(loginData.apiToken ? loginData.apiToken : '');
const [saveApiToken, set_saveApiToken] = useState(false);
Expand All @@ -156,6 +159,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) {
value: index.toString(),
apiEndpoint: node.apiEndpoint,
apiToken: node.apiToken,
jazzIcon: node.jazzIcon,
};
}) as ParsedNode[];
set_nodesSavedLocallyParsed(parsed);
Expand Down Expand Up @@ -261,6 +265,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) {
apiEndpoint: formattedApiEndpoint,
apiToken,
localName,
jazzIcon,
}),
);
dispatch(
Expand Down Expand Up @@ -350,6 +355,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) {
set_apiToken(chosenNode.apiToken);
set_saveApiToken(chosenNode.apiToken?.length > 0);
set_localName(chosenNode.localName);
chosenNode.jazzIcon && set_jazzIcon(chosenNode.jazzIcon);
};

return (
Expand Down Expand Up @@ -434,6 +440,7 @@ function ConnectNodeModal(props: ConnectNodeModalProps) {
<Button
onClick={() => useNode({})}
disabled={apiEndpoint.length === 0}
pending={loginPending}
>
Connect to the node
</Button>
Expand Down
7 changes: 7 additions & 0 deletions src/components/Modal/node/OpenChannelModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,18 @@ export const OpenChannelModal = ({ ...props }: OpenChannelModalProps) => {
const dispatch = useAppDispatch();
const loginData = useAppSelector((store) => store.auth.loginData);
const outgoingOpening = useAppSelector((store) => store.node.channels.parsed.outgoingOpening);
const aliases = useAppSelector((store) => store.node.aliases.data);
const peerIdToAliasLink = useAppSelector((store) => store.node.links.peerIdToAlias);
const channelIsBeingOpened = props.peerAddress ? !!outgoingOpening[props.peerAddress] : false;
const [openChannelModal, set_openChannelModal] = useState(false);
const [amount, set_amount] = useState('');
const [peerAddress, set_peerAddress] = useState(props.peerAddress ? props.peerAddress : '');

const getAliasByPeerId = (peerId: string): string => {
if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${peerId})`;
return peerId;
};

const handleOpenChannelDialog = () => {
set_openChannelModal(true);
};
Expand Down
11 changes: 9 additions & 2 deletions src/components/Modal/node/PingModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,17 @@ type PingModalProps = {
export const PingModal = (props: PingModalProps) => {
const dispatch = useAppDispatch();
const loginData = useAppSelector((selector) => selector.auth.loginData);
const aliases = useAppSelector((store) => store.node.aliases.data);
const peerIdToAliasLink = useAppSelector((store) => store.node.links.peerIdToAlias);
const [peerId, set_peerId] = useState<string>(props.peerId ? props.peerId : '');
const [openModal, set_OpenModal] = useState(false);
const [disableButton, set_disableButton] = useState(false);

const getAliasByPeerId = (peerId: string): string => {
if (aliases && peerId && peerIdToAliasLink[peerId]) return `${peerIdToAliasLink[peerId]} (${peerId})`;
return peerId;
};

const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
set_peerId(event.target.value);
};
Expand Down Expand Up @@ -57,7 +64,7 @@ export const PingModal = (props: PingModalProps) => {
)
.unwrap()
.then((resp: any) => {
const msg = `Ping of ${peerId} succeded with latency of ${resp.latency}ms`;
const msg = `Ping of ${getAliasByPeerId(peerId)} succeeded with latency of ${resp.latency}ms`;
console.log(msg, resp);
sendNotification({
notificationPayload: {
Expand All @@ -76,7 +83,7 @@ export const PingModal = (props: PingModalProps) => {
).unwrap();
if (!isCurrentApiEndpointTheSame) return;

let errMsg = `Ping of ${peerId} failed`;
let errMsg = `Ping of ${getAliasByPeerId(peerId)} failed`;
if (e instanceof sdkApiError && e.hoprdErrorPayload?.status)
errMsg = errMsg + `.\n${e.hoprdErrorPayload.status}`;
if (e instanceof sdkApiError && e.hoprdErrorPayload?.error)
Expand Down
92 changes: 92 additions & 0 deletions src/future-hopr-lib-components/PeerInfo/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
import { useEffect } from 'react';
import { useAppDispatch, useAppSelector } from '../../store';
import { Link } from 'react-router-dom';
import styled from '@emotion/styled';

// HOPR Components
import SmallActionButton from '../../future-hopr-lib-components/Button/SmallActionButton';
import { generateBase64Jazz } from '../../utils/functions';

//Mui
import CopyIcon from '@mui/icons-material/ContentCopy';
import LaunchIcon from '@mui/icons-material/Launch';

interface Props {
peerId?: string;
nodeAddress?: string;
shortenPeerId?: boolean;
}

const Container = styled.div`
display: flex;
align-items: center;
.node-jazz-icon {
height: 30px;
width: 30px;
}
`;

const PeersInfo: React.FC<Props> = (props) => {
const { peerId, nodeAddress, ...rest } = props;
const aliases = useAppSelector((store) => store.node.aliases.data);
const peerIdToAliasLink = useAppSelector((store) => store.node.links.peerIdToAlias);

const getAliasByPeerId = (peerId: string): string | JSX.Element => {
const shortPeerId = peerId && `${peerId.substring(0, 6)}...${peerId.substring(peerId.length - 8, peerId.length)}`;
const displayPeerId = props.shortenPeerId ? shortPeerId : peerId;
if (aliases && peerId && peerIdToAliasLink[peerId])
return (
<>
<strong>{peerIdToAliasLink[peerId]}</strong> ({displayPeerId})
</>
);
return displayPeerId;
};

const noCopyPaste = !(
window.location.protocol === 'https:' ||
window.location.hostname === 'localhost' ||
window.location.hostname === '127.0.0.1'
);

const icon = nodeAddress && generateBase64Jazz(nodeAddress);

return (
<Container>
<img
className={`node-jazz-icon node-jazz-icon-present`}
src={icon || ''}
data-src={nodeAddress}
/>
<div>
<span>{peerId && getAliasByPeerId(peerId)}</span>{' '}
<SmallActionButton
onClick={() => navigator.clipboard.writeText(peerId as string)}
disabled={noCopyPaste}
tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy Peer Id'}
>
<CopyIcon />
</SmallActionButton>
<br />
<span>{nodeAddress}</span>{' '}
<SmallActionButton
onClick={() => navigator.clipboard.writeText(nodeAddress as string)}
disabled={noCopyPaste}
tooltip={noCopyPaste ? 'Clipboard not supported on HTTP' : 'Copy Node Address'}
>
<CopyIcon />
</SmallActionButton>
<SmallActionButton tooltip={'Open in gnosisscan.io'}>
<Link
to={`https://gnosisscan.io/address/${nodeAddress}`}
target="_blank"
>
<LaunchIcon />
</Link>
</SmallActionButton>
</div>
</Container>
);
};

export default PeersInfo;
10 changes: 8 additions & 2 deletions src/future-hopr-lib-components/Select/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import FormControl from '@mui/material/FormControl';
import SelectMui, { SelectProps as SelectMuiProps } from '@mui/material/Select';
import { Tooltip, IconButton } from '@mui/material';
import DeleteIcon from '@mui/icons-material/Delete';
import { generateBase64Jazz } from '../../utils/functions';
import { toHexMD5, generateBase64Jazz } from '../../utils/functions';

const SFormControl = styled(FormControl)`
margin-bottom: 16px;
Expand Down Expand Up @@ -50,12 +50,14 @@ interface Props extends SelectMuiProps {
value: string | number;
name: string | number | null;
apiEndpoint: string | null;
jazzIcon?: string | null;
disabled?: boolean;
}[];
native?: boolean;
}

const Select: React.FC<Props> = (props) => {
console.log('props.values', props.values);
return (
<SFormControl
style={props.style}
Expand All @@ -75,7 +77,10 @@ const Select: React.FC<Props> = (props) => {
>
{props.values &&
props.values.map((elem, index) => {
const icon = elem.apiEndpoint && generateBase64Jazz(elem.apiEndpoint);
const jazzMd5apiEndpoint = elem.apiEndpoint && toHexMD5(elem.apiEndpoint);
const icon = elem.jazzIcon
? generateBase64Jazz(elem.jazzIcon)
: jazzMd5apiEndpoint && generateBase64Jazz(jazzMd5apiEndpoint);
return (
<MenuItem
value={elem.value}
Expand All @@ -88,6 +93,7 @@ const Select: React.FC<Props> = (props) => {
<img
className={`node-jazz-icon ${icon && 'node-jazz-icon-present'}`}
src={icon ?? '/assets/hopr_logo.svg'}
data-src={elem.jazzIcon ? elem.jazzIcon : jazzMd5apiEndpoint}
/>
)}
<span className="select-menu-item-text">{elem.name}</span>
Expand Down
Loading

0 comments on commit dca88b3

Please sign in to comment.