| 1 | import './multiaddr-list.css' |
| 2 | import { multiaddr } from '@multiformats/multiaddr' |
| 3 | import { WebRTC, WebSockets, WebSocketsSecure, WebTransport, Circuit, QUIC, QUIC_V1, TCP, WebRTCDirect } from '@multiformats/multiaddr-matcher' |
| 4 | import { useContext } from 'react' |
| 5 | import certifiedMultiaddr from '../../public/img/multiaddr-certified.svg' |
| 6 | import uncertifiedMultiaddr from '../../public/img/multiaddr-uncertified.svg' |
| 7 | import circuitRelayTransport from '../../public/img/transport-circuit-relay.svg' |
| 8 | import quicTransport from '../../public/img/transport-quic.svg' |
| 9 | import tcpTransport from '../../public/img/transport-tcp.svg' |
| 10 | import unknownTransport from '../../public/img/transport-unknown.svg' |
| 11 | import webrtcTransport from '../../public/img/transport-webrtc.svg' |
| 12 | import websocketTransport from '../../public/img/transport-websocket.svg' |
| 13 | import webtransportTransport from '../../public/img/transport-webtransport.svg' |
| 14 | import { HandleCopyToClipboardContext } from '../context/handle-copy-to-clipboard.ts' |
| 15 | import { CopyIcon } from './icons/icon-copy.js' |
| 16 | import type { Multiaddr } from '@multiformats/multiaddr' |
| 17 | import type { ReactElement } from 'react' |
| 18 | |
| 19 | export interface TransportIconProps { |
| 20 | multiaddr: Multiaddr |
| 21 | } |
| 22 | |
| 23 | function TransportIcon ({ multiaddr }: TransportIconProps): ReactElement { |
| 24 | let src: string = unknownTransport |
| 25 | |
| 26 | if (WebRTC.matches(multiaddr) || WebRTCDirect.matches(multiaddr)) { |
| 27 | src = webrtcTransport |
| 28 | } else if (Circuit.matches(multiaddr)) { |
| 29 | src = circuitRelayTransport |
| 30 | } else if (WebSockets.matches(multiaddr) || WebSocketsSecure.matches(multiaddr)) { |
| 31 | src = websocketTransport |
| 32 | } else if (WebTransport.matches(multiaddr)) { |
| 33 | src = webtransportTransport |
| 34 | } else if (QUIC.matches(multiaddr) || QUIC_V1.matches(multiaddr)) { |
| 35 | src = quicTransport |
| 36 | } else if (TCP.matches(multiaddr)) { |
| 37 | src = tcpTransport |
| 38 | } |
| 39 | |
| 40 | return ( |
| 41 | <> |
| 42 | <img src={src} height={16} width={16} className='Icon' /> |
| 43 | </> |
| 44 | ) |
| 45 | } |
| 46 | |
| 47 | export interface CertifiedIconProps { |
| 48 | isCertified?: boolean |
| 49 | } |
| 50 | |
| 51 | function CertifiedIcon ({ isCertified }: CertifiedIconProps): ReactElement { |
| 52 | return ( |
| 53 | <> |
| 54 | <img src={isCertified === true ? certifiedMultiaddr : uncertifiedMultiaddr} height={16} width={16} className='Icon' /> |
| 55 | </> |
| 56 | ) |
| 57 | } |
| 58 | |
| 59 | interface MultiaddrProps { |
| 60 | multiaddr: Multiaddr |
| 61 | isCertified?: boolean |
| 62 | key?: string |
| 63 | includeCertification?: boolean |
| 64 | } |
| 65 | |
| 66 | function MultiaddrPanel ({ multiaddr: m, isCertified, includeCertification }: MultiaddrProps): ReactElement { |
| 67 | const onCopyToClipboard = useContext(HandleCopyToClipboardContext) |
| 68 | const ma = multiaddr(m) |
| 69 | |
| 70 | function onCopy (evt: any): void { |
| 71 | evt.preventDefault() |
| 72 | |
| 73 | onCopyToClipboard(ma.toString()) |
| 74 | } |
| 75 | |
| 76 | return ( |
| 77 | <div className='Multiaddr'> |
| 78 | <TransportIcon multiaddr={ma} /> |
| 79 | { |
| 80 | includeCertification === true ? <CertifiedIcon isCertified={isCertified} /> : undefined |
| 81 | } |
| 82 | <CopyIcon onClick={onCopy} /> |
| 83 | <code>{m.toString()}</code> |
| 84 | </div> |
| 85 | ) |
| 86 | } |
| 87 | |
| 88 | export interface MulitaddrListProps { |
| 89 | addresses: Array<{ multiaddr: Multiaddr, isCertified?: boolean }> |
| 90 | includeCertification?: boolean |
| 91 | } |
| 92 | |
| 93 | export function MultiaddrList ({ addresses, includeCertification }: MulitaddrListProps): ReactElement { |
| 94 | if (addresses.length === 0) { |
| 95 | return ( |
| 96 | <> |
| 97 | <p>There are no multiaddrs to display</p> |
| 98 | </> |
| 99 | ) |
| 100 | } |
| 101 | |
| 102 | return ( |
| 103 | <> |
| 104 | <div className='MultiaddrList'> |
| 105 | <ul> |
| 106 | {addresses.map(({ multiaddr: m, isCertified }, index) => <MultiaddrPanel key={`ma-${index}`} multiaddr={m} includeCertification={includeCertification} isCertified={isCertified} />)} |
| 107 | </ul> |
| 108 | </div> |
| 109 | </> |
| 110 | ) |
| 111 | } |