mirror of
https://github.com/ajvpot/meshexplorer.git
synced 2026-03-28 17:42:58 +01:00
First seen time
This commit is contained in:
@@ -2,17 +2,7 @@ import React from 'react';
|
||||
import moment from "moment";
|
||||
import { formatPublicKey } from '../lib/meshcore';
|
||||
import { getNameIconLabel } from '../lib/meshcore-map-nodeutils';
|
||||
|
||||
type NodePosition = {
|
||||
node_id: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
altitude?: number;
|
||||
last_seen?: string;
|
||||
type?: string;
|
||||
short_name?: string;
|
||||
name?: string | null;
|
||||
};
|
||||
import { NodePosition } from '../types/map';
|
||||
|
||||
interface NodeMarkerProps {
|
||||
node: NodePosition;
|
||||
@@ -163,6 +153,14 @@ export function PopupContent({ node }: PopupContentProps) {
|
||||
) : (
|
||||
<div><b>Last seen:</b> -</div>
|
||||
)}
|
||||
{node.first_seen ? (
|
||||
<div>
|
||||
<b>First seen:</b> {moment.utc(node.first_seen).format('YYYY-MM-DD HH:mm:ss')} <span style={{color: '#888'}}>(UTC)</span><br/>
|
||||
<span style={{color: '#888'}}>{moment.utc(node.first_seen).local().fromNow()}</span>
|
||||
</div>
|
||||
) : (
|
||||
<div><b>First seen:</b> -</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import RefreshButton from "@/components/RefreshButton";
|
||||
import { NodeMarker, ClusterMarker, PopupContent } from "./MapIcons";
|
||||
import { renderToString } from "react-dom/server";
|
||||
import { buildApiUrl } from "../lib/api";
|
||||
import { NodePosition } from "../types/map";
|
||||
|
||||
const DEFAULT = {
|
||||
lat: 46.56, // Center between Seattle and Portland
|
||||
@@ -19,17 +20,6 @@ const DEFAULT = {
|
||||
zoom: 7, // Zoom level to show both cities
|
||||
};
|
||||
|
||||
type NodePosition = {
|
||||
node_id: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
altitude?: number;
|
||||
last_seen?: string;
|
||||
type?: string;
|
||||
short_name?: string;
|
||||
name?: string | null;
|
||||
};
|
||||
|
||||
type ClusteredMarkersProps = { nodes: NodePosition[] };
|
||||
|
||||
// Individual marker component
|
||||
|
||||
@@ -33,7 +33,7 @@ export async function getNodePositions({ minLat, maxLat, minLng, maxLng, nodeTyp
|
||||
where.push(`last_seen >= now() - INTERVAL {lastSeen:UInt32} SECOND`);
|
||||
params.lastSeen = Number(lastSeen);
|
||||
}
|
||||
const query = `SELECT node_id, name, short_name, latitude, longitude, last_seen, type FROM unified_latest_nodeinfo WHERE ${where.join(" AND ")}`;
|
||||
const query = `SELECT node_id, name, short_name, latitude, longitude, last_seen, first_seen, type FROM unified_latest_nodeinfo WHERE ${where.join(" AND ")}`;
|
||||
const resultSet = await clickhouse.query({ query, query_params: params, format: 'JSONEachRow' });
|
||||
const rows = await resultSet.json();
|
||||
return rows as Array<{
|
||||
@@ -43,6 +43,7 @@ export async function getNodePositions({ minLat, maxLat, minLng, maxLng, nodeTyp
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
last_seen: string;
|
||||
first_seen?: string;
|
||||
type: string;
|
||||
}>;
|
||||
} catch (error) {
|
||||
|
||||
11
src/types/map.ts
Normal file
11
src/types/map.ts
Normal file
@@ -0,0 +1,11 @@
|
||||
export type NodePosition = {
|
||||
node_id: string;
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
altitude?: number;
|
||||
last_seen?: string;
|
||||
first_seen?: string;
|
||||
type?: string;
|
||||
short_name?: string;
|
||||
name?: string | null;
|
||||
};
|
||||
Reference in New Issue
Block a user