Skip to content

Commit

Permalink
Dvpn, Dwifi: Add World Map On Explorer Page
Browse files Browse the repository at this point in the history
  • Loading branch information
vaibhavvvvv committed Aug 21, 2024
1 parent edda1e5 commit 8f19a98
Show file tree
Hide file tree
Showing 6 changed files with 339 additions and 22 deletions.
123 changes: 123 additions & 0 deletions components/DvpnMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import dynamic from 'next/dynamic';
import { useEffect, useState } from 'react';
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';

// Dynamically import components with ssr: false
const MapContainer = dynamic(() => import('react-leaflet').then((module) => module.MapContainer), { ssr: false });
const TileLayer = dynamic(() => import('react-leaflet').then((module) => module.TileLayer), { ssr: false });
const Marker = dynamic(() => import('react-leaflet').then((module) => module.Marker), { ssr: false });
const Popup = dynamic(() => import('react-leaflet').then((module) => module.Popup), { ssr: false });

// Define a custom animated icon
const animatedIcon = L.divIcon({
className: 'custom-animated-icon',
html: `
<div style="
width: 20px;
height: 20px;
background: radial-gradient(circle, blue, white);
border-radius: 50%;
animation: pulse 2s infinite;
"></div>
`,
iconSize: [20, 20],
iconAnchor: [10, 10],
popupAnchor: [0, -10],
});

const DvpnMap = ({ nodes }) => {
const [isClient, setIsClient] = useState(false);
const [offsets, setOffsets] = useState({});

useEffect(() => {
setIsClient(true);

// Initialize offsets
const offsetMap = {};
nodes.forEach((node) => {
const [lat, lon] = node.ipinfolocation.split(',').map(Number);
const key = `${lat},${lon}`;
if (!offsetMap[key]) {
offsetMap[key] = [0, 0];
} else {
// Apply a small offset if multiple markers have the same coordinates
offsetMap[key] = [offsetMap[key][0] + 0.01, offsetMap[key][1] + 0.01];
}
});
setOffsets(offsetMap);
}, [nodes]);

if (!isClient) {
return null;
}

return (
<div className="relative h-full w-full p-20 pl-20 pr-20">
<MapContainer
center={[20, 0]}
zoom={2}
minZoom={2}
maxZoom={5}
style={{ height: '100%', width: '100%', padding: '20px', }}
// className="leaflet-container"
// maxBounds={[[-90, -180], [90, 180]]}
// maxBoundsViscosity={1.0}
>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
/>
{/* <TileLayer
url="https://{s}.basemaps.cartocdn.com/light_all/{z}/{x}/{y}{r}.png" // CartoDB Dark theme URL
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors | Map tiles by <a href="https://carto.com/attributions">CartoDB</a>'
noWrap={true}
/> */}
{/* <TileLayer
url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/dark_all/{z}/{x}/{y}.png"
attribution='&copy; <a href="http://www.openstreetmap.org/copyright">OpenStreetMap</a> &copy; <a href="http://cartodb.com/attributions">CartoDB</a>'
noWrap={true}
/> */}
{nodes.map((node, index) => {
const [lat, lon] = node.ipinfolocation.split(',').map(Number);
const key = `${lat},${lon}`;
const offset = offsets[key] || [0, 0];
return (
<Marker
key={index}
position={[lat + offset[0], lon + offset[1]]}
icon={animatedIcon}
>
<Popup>
<div className="text-blue-800">
<h3 className="text-blue-900 text-lg font-semibold">{node.name}</h3>
<p><strong>Country:</strong> {node.ipinfocountry}</p>
<p><strong>City:</strong> {node.ipinfocity}</p>
<p><strong>Node Name:</strong> {node.nodename}</p>
<p><strong>Download Speed:</strong> {node.downloadSpeed} Mbps</p>
<p><strong>Upload Speed:</strong> {node.uploadSpeed} Mbps</p>
</div>
</Popup>
</Marker>
);
})}
</MapContainer>
<style jsx>{`
@keyframes pulse {
0% {
transform: scale(1);
}
50% {
transform: scale(1.2);
}
100% {
transform: scale(1);
}
}
`}</style>
</div>
);
};

export default DvpnMap;
124 changes: 124 additions & 0 deletions components/DwifiMap.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
import { useState, useEffect, useRef } from 'react';
import { MapContainer, TileLayer, Marker, Popup } from 'react-leaflet';
import 'leaflet/dist/leaflet.css';
import L from 'leaflet';

// Custom icon
const customIcon = new L.Icon({
iconUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon.png',
iconRetinaUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-icon-2x.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
shadowUrl: 'https://unpkg.com/leaflet@1.7.1/dist/images/marker-shadow.png',
shadowSize: [41, 41],
});

export default function DwifiMap() {
const [nodes, setNodes] = useState([]);
const socketRef = useRef(null); // Use ref to maintain WebSocket across renders

useEffect(() => {
const socket = new WebSocket('wss://dev.gateway.erebrus.io/api/v1.0/nodedwifi/stream');

socket.onopen = function () {
console.log('WebSocket is open now.');
};

socket.onmessage = function (event) {
console.log('Received:', event.data);
};

socket.onerror = function (event) {
console.error('WebSocket error:', event);
};

socket.onclose = function (event) {
console.log('WebSocket is closed now.', event);
};

return () => {
socket.close();
};
}, []);

useEffect(() => {
function connectWebSocket() {
// Initialize the WebSocket connection
socketRef.current = new WebSocket('wss://dev.gateway.erebrus.io/api/v1.0/nodedwifi/stream');

// Handle the WebSocket connection opening
socketRef.current.onopen = function () {
console.log('WebSocket is open now.');
};

// Handle incoming WebSocket messages
socketRef.current.onmessage = function (event) {
const newNode = JSON.parse(event.data);
setNodes((prevNodes) => {
const existingIndex = prevNodes.findIndex((node) => node.id === newNode.id);
if (existingIndex !== -1) {
return prevNodes.map((node) => (node.id === newNode.id ? newNode : node));
} else {
return [...prevNodes, newNode];
}
});
};

// Handle WebSocket errors
socketRef.current.onerror = function (event) {
console.error('WebSocket error:', event);
};

// Handle WebSocket closure
socketRef.current.onclose = function () {
console.log('WebSocket is closed. Attempting to reconnect...');
setTimeout(connectWebSocket, 5000); // Attempt to reconnect after 5 seconds
};
}

// Establish WebSocket connection
connectWebSocket();

// Cleanup function
return () => {
console.log('Cleaning up WebSocket connection...');
if (socketRef.current) {
socketRef.current.close();
}
};
}, []); // Empty dependency array ensures this runs once

return (
<div className="relative h-full w-full p-20 pl-20 pr-20">
<MapContainer
center={[20, 0]}
zoom={2}
style={{ height: '100%', width: '100%', padding: '20px', }}
maxBounds={[[-90, -180], [90, 180]]}
maxBoundsViscosity={1.0}
>
<TileLayer
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
attribution='&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
/>
{nodes.map((node) => {
const [lat, lon] = node.co_ordinates.split(',').map(Number);
return (
<Marker key={node.id} position={[lat, lon]} icon={customIcon}>
<Popup>
<div className="text-blue-800">
<h6 className="text-blue-600 text-lg "><strong>Address:</strong> {node.location}</h6>
<p><strong>Gateway:</strong> {node.gateway}</p>
<p><strong>Price per Minute:</strong> {node.price_per_min}</p>
<p><strong>Wallet Address:</strong> <span style={{ wordWrap: 'break-word' }}>{node.wallet_address}</span></p>
<p><strong>Chain Name:</strong> {node.chain_name}</p>
</div>
</Popup>
</Marker>
);
})}
</MapContainer>
</div>
);
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
"file-saver": "^2.0.5",
"framer-motion": "^8.0.2",
"js-cookie": "^3.0.5",
"leaflet": "^1.9.4",
"mapbox-gl": "^3.5.2",
"next": "13.1.1",
"nft.storage": "^7.1.1",
Expand All @@ -68,6 +69,7 @@
"react-google-recaptcha": "^2.1.0",
"react-icons": "^4.7.1",
"react-intersection-observer": "^9.13.0",
"react-leaflet": "^4.2.1",
"react-mapbox-gl": "^5.1.1",
"react-responsive-carousel": "^3.2.23",
"react-toastify": "^9.1.1",
Expand Down
14 changes: 14 additions & 0 deletions pages/dwifi.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import React, { useEffect, useState} from "react";
import Link from "next/link";
import NodeDwifiStream from "../components/nodedataDwifi";
import { motion } from "framer-motion";
import dynamic from 'next/dynamic';

const DwifiMap = dynamic(() => import('../components/DwifiMap'), { ssr: false });


const Dwifi = () => {

Expand Down Expand Up @@ -45,7 +49,17 @@ const Dwifi = () => {
</motion.div>
</div>
</div>
<div className="map-page" style={{ height: '100vh', width: '100vw' }}>

<div className="map-controls" style={{ position: 'absolute', top: 10, left: 10, zIndex: 1000 }}>
</div>
<div className="map-container" style={{ height: '100%', width: '100%' }}>
<DwifiMap />
</div>
</div>

<NodeDwifiStream />

{/* <img src="/mapRegions.png"/> */}
</div>
)
Expand Down
28 changes: 27 additions & 1 deletion pages/explorer.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
import React, { useEffect, useState} from "react";
import Link from "next/link";
import NodesData from "../components/NodesData";
import dynamic from 'next/dynamic';
// import Dvpn Map from "../components/DvpnMap"
import { motion } from "framer-motion";

const DvpnMap = dynamic(() => import('../components/DvpnMap'), { ssr: false });


const Explorer = () => {

const [nodes, setNodes] = useState([]);
const [activeMap, setActiveMap] = useState('pin');

useEffect(() => {
async function fetchNodes() {
const response = await fetch('https://gateway.erebrus.io/api/v1.0/nodes/all');
const data = await response.json();
setNodes(data.payload);
}
fetchNodes();
}, []);

return (
<div className="bg-[#040819]">
<div className="mx-auto py-20"
Expand Down Expand Up @@ -45,9 +62,18 @@ const Explorer = () => {
</motion.div>
</div>
</div>
<NodesData />
{/* <img src="/mapRegions.png"/> */}
<div className="map-page" style={{ height: '100vh', width: '100vw' }}>

<div className="map-controls" style={{ position: 'absolute', top: 10, left: 10, zIndex: 1000 }}>
</div>
<div className="map-container" style={{ height: '100%', width: '100%' }}>
<DvpnMap nodes={nodes} />
</div>
</div>

<NodesData />
</div>
)
}

Expand Down
Loading

0 comments on commit 8f19a98

Please sign in to comment.