diff --git a/packages/backend/src/Feed.ts b/packages/backend/src/Feed.ts index a9bb75c..2c87371 100644 --- a/packages/backend/src/Feed.ts +++ b/packages/backend/src/Feed.ts @@ -28,7 +28,7 @@ export default class Feed { public static feedVersion(): FeedMessage.Message { return { - action: Actions.FeedVersion, + action: Actions.FeedVersionLegacy, payload: VERSION }; } diff --git a/packages/common/src/feed.ts b/packages/common/src/feed.ts index 5d1204d..24748fe 100644 --- a/packages/common/src/feed.ts +++ b/packages/common/src/feed.ts @@ -16,18 +16,19 @@ import { } from './types'; export const Actions = { - FeedVersion : 0xff as 0xff, - BestBlock : 0x00 as 0x00, - AddedNode : 0x01 as 0x01, - RemovedNode : 0x02 as 0x02, - LocatedNode : 0x03 as 0x03, - ImportedBlock : 0x04 as 0x04, - NodeStats : 0x05 as 0x05, - TimeSync : 0x06 as 0x06, - AddedChain : 0x07 as 0x07, - RemovedChain : 0x08 as 0x08, - SubscribedTo : 0x09 as 0x09, - UnsubscribedFrom : 0x0A as 0x0A, + FeedVersionLegacy : 0xff as 0xff, + FeedVersion : 0x00 as 0x00, + BestBlock : 0x01 as 0x01, + AddedNode : 0x02 as 0x02, + RemovedNode : 0x03 as 0x03, + LocatedNode : 0x04 as 0x04, + ImportedBlock : 0x05 as 0x05, + NodeStats : 0x06 as 0x06, + TimeSync : 0x07 as 0x07, + AddedChain : 0x08 as 0x08, + RemovedChain : 0x09 as 0x09, + SubscribedTo : 0x0A as 0x0A, + UnsubscribedFrom : 0x0B as 0x0B, }; export type Action = typeof Actions[keyof typeof Actions]; @@ -38,6 +39,12 @@ export namespace Variants { action: Action; } + // TOOD: remove + export interface FeedVersionLegacyMessage extends MessageBase { + action: typeof Actions.FeedVersionLegacy; + payload: FeedVersion; + } + export interface FeedVersionMessage extends MessageBase { action: typeof Actions.FeedVersion; payload: FeedVersion; @@ -100,6 +107,7 @@ export namespace Variants { } export type Message = + | Variants.FeedVersionLegacyMessage | Variants.FeedVersionMessage | Variants.BestBlockMessage | Variants.AddedNodeMessage diff --git a/packages/frontend/src/Connection.ts b/packages/frontend/src/Connection.ts index 7b5ef37..37ac85c 100644 --- a/packages/frontend/src/Connection.ts +++ b/packages/frontend/src/Connection.ts @@ -97,6 +97,8 @@ export class Connection { messages: for (const message of FeedMessage.deserialize(data)) { switch (message.action) { + // TODO: Kick legacy out on next update + case Actions.FeedVersionLegacy: case Actions.FeedVersion: { if (message.payload !== VERSION) { this.state = this.update({ status: 'upgrade-requested' }); diff --git a/packages/frontend/src/assets/map.svg b/packages/frontend/src/assets/map.svg deleted file mode 100644 index c003b8d..0000000 --- a/packages/frontend/src/assets/map.svg +++ /dev/null @@ -1,75 +0,0 @@ - - - - - - - - - - - - - image/svg+xml - - - - - - - - - diff --git a/packages/frontend/src/components/Chain.css b/packages/frontend/src/components/Chain.css index f495afa..44c0ab6 100644 --- a/packages/frontend/src/components/Chain.css +++ b/packages/frontend/src/components/Chain.css @@ -39,10 +39,11 @@ .Chain-map-node { width: 10px; height: 10px; - background: #f00; /* #d64ca8;*/ - border-radius: 5px; - margin-left: -5px; - margin-top: -5px; + background: #d64ca8; + border: 1px solid #000; + border-radius: 6px; + margin-left: -6px; + margin-top: -6px; position: absolute; top: 50%; left: 50%; diff --git a/packages/frontend/src/components/Chain.tsx b/packages/frontend/src/components/Chain.tsx index 8d065ce..27af7b1 100644 --- a/packages/frontend/src/components/Chain.tsx +++ b/packages/frontend/src/components/Chain.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; import { State as AppState } from '../state'; -import { formatNumber, secondsWithPrecision } from '../utils'; +import { formatNumber, secondsWithPrecision, viewport } from '../utils'; import { Tile, Icon, Node, Ago } from './'; +import { Types } from '@dotstats/common'; import nodeIcon from '../icons/server.svg'; import nodeTypeIcon from '../icons/terminal.svg'; @@ -13,6 +14,9 @@ import blockTimeIcon from '../icons/history.svg'; import propagationTimeIcon from '../icons/dashboard.svg'; import lastTimeIcon from '../icons/watch.svg'; +const MAP_RATIO = 495 / 266; // width / height +const HEADER = 148; + import './Chain.css'; export namespace Chain { @@ -22,6 +26,12 @@ export namespace Chain { export interface State { display: 'map' | 'table'; + map: { + width: number; + height: number; + top: number; + left: number; + } } } @@ -43,10 +53,45 @@ export class Chain extends React.Component { super(props); this.state = { - display: 'table' + display: window.location.hash === '#map' ? 'map' : 'table', + map: { + width: 0, + height: 0, + top: 0, + left: 0 + } }; } + public componentWillMount() { + const vp = viewport(); + + vp.height -= HEADER; + + const ratio = vp.width / vp.height; + + let top = 0; + let left = 0; + let width = 0; + let height = 0; + + if (ratio >= MAP_RATIO) { + console.log('wider'); + + width = Math.round(vp.height * MAP_RATIO); + height = Math.round(vp.height); + left = (vp.width - width) / 2; + } else { + console.log('taller'); + + width = Math.round(vp.width); + height = Math.round(vp.width / MAP_RATIO); + top = (vp.height - height) / 2; + } + + this.setState({ map: { top, left, width, height }}); + } + public render() { const { best, blockTimestamp, blockAverage } = this.props.appState; @@ -75,12 +120,40 @@ export class Chain extends React.Component { return (
{ - this.nodes().map((node) =>
) + // Debug rect + //
+ } + { + this.nodes().map((node) => { + 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 + // const location = [36.7183391, -4.5193071]as Types.NodeLocation; // Malaga + + return ( +
+ ); + }) }
); } + private pixelPosition(lat: Types.Latitude, lon: Types.Longitude): { left: number, top: number } { + const { map } = this.state; + + const left = Math.round(((lon + 180) / 360) * map.width + map.left) - 35; + const top = Math.round(((-lat + 90) / 180) * map.height + map.top) + 4; + + return { left, top } + } + private renderTable() { return ( diff --git a/packages/frontend/src/components/Chains.tsx b/packages/frontend/src/components/Chains.tsx index 0b782fe..8b73520 100644 --- a/packages/frontend/src/components/Chains.tsx +++ b/packages/frontend/src/components/Chains.tsx @@ -28,7 +28,7 @@ export class Chains extends React.Component { { this.chains.map((chain) => this.renderChain(chain)) } - + diff --git a/packages/frontend/src/utils.ts b/packages/frontend/src/utils.ts index 7a459b4..82fd9ce 100644 --- a/packages/frontend/src/utils.ts +++ b/packages/frontend/src/utils.ts @@ -1,3 +1,15 @@ +export interface Viewport { + width: number; + height: number; +} + +export function viewport(): Viewport { + const width = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); + const height = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); + + return { width, height }; +} + export function formatNumber(num: number): string { const input = num.toString();