diff --git a/packages/backend/declarations/index.d.ts b/packages/backend/declarations/index.d.ts index e20674e..97e0c40 100644 --- a/packages/backend/declarations/index.d.ts +++ b/packages/backend/declarations/index.d.ts @@ -2,7 +2,7 @@ declare module 'iplocation' { namespace iplocation { export interface LocationData { as?: string; - city?: string; + city: string; country?: string; countryCode?: string; isp?: string; diff --git a/packages/backend/src/Feed.ts b/packages/backend/src/Feed.ts index a9bb75c..1fce77f 100644 --- a/packages/backend/src/Feed.ts +++ b/packages/backend/src/Feed.ts @@ -57,7 +57,7 @@ export default class Feed { public static locatedNode(node: Node, location: Location): FeedMessage.Message { return { action: Actions.LocatedNode, - payload: [node.id, location.lat, location.lon] + payload: [node.id, location.lat, location.lon, location.city] }; } diff --git a/packages/backend/src/Node.ts b/packages/backend/src/Node.ts index 40d1278..2cfb4cd 100644 --- a/packages/backend/src/Node.ts +++ b/packages/backend/src/Node.ts @@ -98,8 +98,6 @@ export default class Node { return; } - console.log('node', ip, 'located at', location); - this.location = location; this.events.emit('location', location); @@ -107,8 +105,6 @@ export default class Node { } public static fromSocket(socket: WebSocket, ip: string): Promise { - console.log('node ip', ip); - return new Promise((resolve, reject) => { function cleanup() { clearTimeout(timeout); @@ -160,7 +156,7 @@ export default class Node { public nodeLocation(): Maybe { const { location } = this; - return location ? [location.lat, location.lon] : null; + return location ? [location.lat, location.lon, location.city] : null; } public get average(): number { diff --git a/packages/backend/src/location.ts b/packages/backend/src/location.ts index c09f81a..077c497 100644 --- a/packages/backend/src/location.ts +++ b/packages/backend/src/location.ts @@ -4,6 +4,7 @@ import { Maybe, Types } from '@dotstats/common'; export interface Location { lat: Types.Latitude; lon: Types.Longitude; + city: Types.City; } const cache = new Map(); @@ -12,7 +13,8 @@ export async function locate(ip: string): Promise> { if (ip === '127.0.0.1') { return Promise.resolve({ lat: 52.5166667 as Types.Latitude, - lon: 13.4 as Types.Longitude + lon: 13.4 as Types.Longitude, + city: 'Berlin' as Types.City, }); } @@ -30,8 +32,8 @@ export async function locate(ip: string): Promise> { return resolve(null); } - const { latitude: lat, longitude: lon } = result; - const location = { lat, lon } as Location; + const { latitude: lat, longitude: lon, city } = result; + const location = { lat, lon, city } as Location; cache.set(ip, location); diff --git a/packages/common/src/feed.ts b/packages/common/src/feed.ts index 219ba17..b2c0edf 100644 --- a/packages/common/src/feed.ts +++ b/packages/common/src/feed.ts @@ -3,6 +3,7 @@ import { FeedVersion, Latitude, Longitude, + City, NodeId, NodeCount, NodeDetails, @@ -60,7 +61,7 @@ export namespace Variants { export interface LocatedNodeMessage extends MessageBase { action: typeof Actions.LocatedNode; - payload: [NodeId, Latitude, Longitude]; + payload: [NodeId, Latitude, Longitude, City]; } export interface ImportedBlockMessage extends MessageBase { diff --git a/packages/common/src/index.ts b/packages/common/src/index.ts index 24b4df7..08ac0b3 100644 --- a/packages/common/src/index.ts +++ b/packages/common/src/index.ts @@ -6,4 +6,4 @@ import * as FeedMessage from './feed'; export { Types, FeedMessage }; -export const VERSION: Types.FeedVersion = 4 as Types.FeedVersion; +export const VERSION: Types.FeedVersion = 5 as Types.FeedVersion; diff --git a/packages/common/src/types.ts b/packages/common/src/types.ts index 88aee4d..cf9dc1b 100644 --- a/packages/common/src/types.ts +++ b/packages/common/src/types.ts @@ -18,8 +18,9 @@ export type PeerCount = Opaque; export type TransactionCount = Opaque; export type Latitude = Opaque; export type Longitude = Opaque; +export type City = Opaque; export type BlockDetails = [BlockNumber, BlockHash, Milliseconds, Timestamp, Maybe]; export type NodeDetails = [NodeName, NodeImplementation, NodeVersion]; export type NodeStats = [PeerCount, TransactionCount]; -export type NodeLocation = [Latitude, Longitude]; +export type NodeLocation = [Latitude, Longitude, City]; diff --git a/packages/frontend/src/Connection.ts b/packages/frontend/src/Connection.ts index e352a59..fe3ec8f 100644 --- a/packages/frontend/src/Connection.ts +++ b/packages/frontend/src/Connection.ts @@ -139,14 +139,14 @@ export class Connection { } case Actions.LocatedNode: { - const [id, latitude, longitude] = message.payload; + const [id, latitude, longitude, city] = message.payload; const node = nodes.get(id); if (!node) { return; } - node.location = [latitude, longitude]; + node.location = [latitude, longitude, city]; break; } diff --git a/packages/frontend/src/components/Chain.tsx b/packages/frontend/src/components/Chain.tsx index 504df3f..a6da4bc 100644 --- a/packages/frontend/src/components/Chain.tsx +++ b/packages/frontend/src/components/Chain.tsx @@ -118,7 +118,7 @@ export class Chain extends React.Component { } { this.nodes().map((node) => { - const location = node.location || [0, 0] as Types.NodeLocation; + const location = node.location || [0, 0, ''] as Types.NodeLocation; // const location = [51.4825891, -0.0164137] as Types.NodeLocation; // Greenwich // const location = [52.2330653, 20.921111] as Types.NodeLocation; // Warsaw // const location = [48.8589507, 2.2770201] as Types.NodeLocation; // Paris diff --git a/packages/frontend/src/components/Node.css b/packages/frontend/src/components/Node.css index 15a9e25..cd6b1d4 100644 --- a/packages/frontend/src/components/Node.css +++ b/packages/frontend/src/components/Node.css @@ -12,6 +12,11 @@ cursor: pointer; } +.Node-Location:hover { + z-index: 2; + background: #fff; +} + .Node-details { display: none; min-width: 335px; diff --git a/packages/frontend/src/components/Node.tsx b/packages/frontend/src/components/Node.tsx index 9f475bd..43d2790 100644 --- a/packages/frontend/src/components/Node.tsx +++ b/packages/frontend/src/components/Node.tsx @@ -5,6 +5,7 @@ import { Types, Maybe } from '@dotstats/common'; import nodeIcon from '../icons/server.svg'; import nodeTypeIcon from '../icons/terminal.svg'; +import nodeLocationIcon from '../icons/location.svg'; import peersIcon from '../icons/broadcast.svg'; import transactionsIcon from '../icons/inbox.svg'; import blockIcon from '../icons/package.svg'; @@ -68,10 +69,14 @@ export namespace Node { } export function Location(props: Props & PixelPosition) { - const { left, top } = props; + const { left, top, location } = props; const [name, implementation, version] = props.nodeDetails; const [height, hash, blockTime, blockTimestamp, propagationTime] = props.blockDetails; + if (!location) { + return null; + } + return (
@@ -82,6 +87,9 @@ export namespace Node { + + +
{implementation} v{version}
{location[2]}
#{formatNumber(height)}