import type { Peer } from '@ethersphere/bee-js' import DottedMap, { DottedMapWithoutCountriesLib } from 'dotted-map/without-countries' import { CSSProperties, ReactElement, useContext, useEffect, useState } from 'react' import mapData from '../assets/data/map-data.json' import nodesDb from '../assets/data/nodes-db.json' import { Context } from '../providers/Bee' interface Props { style?: CSSProperties error?: boolean } interface MapRecord { lat: number lng: number } type MapDB = Record const fullMapDb = nodesDb as unknown as MapDB const deduplicatedRecords = deduplicate(fullMapDb) function deduplicate(db: MapDB): MapRecord[] { const noDuplicates: Record = {} Object.entries(fullMapDb).forEach(([key, record]) => { noDuplicates[`${record.lat} ${record.lng}`] = record }) return Object.values(noDuplicates) } function findIntersection(db: MapDB, peers: Peer[]): MapRecord[] { const noDuplicates: Record = {} peers.forEach(({ address }) => { const record = db[address] if (record) noDuplicates[`${record.lat} ${record.lng}`] = record }) return Object.values(noDuplicates) } function addPins(map: DottedMap, pins: MapRecord[], color: string) { pins.forEach(({ lat, lng }) => { map.addPin({ lat, lng, svgOptions: { color } }) }) } const mapPrecomputed = new DottedMap({ map: JSON.parse(mapData) }) const mapNoPins = new DottedMap({ map: JSON.parse(mapData) }) addPins(mapPrecomputed, deduplicatedRecords, '#303030') const mapSvgOptions: DottedMapWithoutCountriesLib.SvgSettings = { shape: 'hexagon', radius: 0.21, color: '#dadada' } export default function Card({ style, error }: Props): ReactElement { const { peers } = useContext(Context) const [map, setMap] = useState(mapPrecomputed.getSVG(mapSvgOptions)) useEffect(() => { // Display error map if (error) setMap(mapNoPins.getSVG({ ...mapSvgOptions, color: '#eaeaea' })) // Display just the base map without any connections if (!peers) return const points = findIntersection(fullMapDb, peers) const mapNew = Object.create(mapPrecomputed) addPins(mapNew, points, '#09CA6C') setMap(mapNew.getSVG(mapSvgOptions)) }, [peers, error]) return (
world map {error && ( )}
) }