Skip to content

Commit

Permalink
chore(rxPage): add missing changes
Browse files Browse the repository at this point in the history
After rebase develop some changes where missing
  • Loading branch information
selankon committed Feb 21, 2024
1 parent 2122de5 commit 9cad758
Show file tree
Hide file tree
Showing 4 changed files with 262 additions and 7 deletions.
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions plugins/lime-plugin-locate/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { LocateMenu } from "./src/locateMenu";
import Locate from "./src/locatePage";

export default {
name: "Locate",
page: Locate,
menu: LocateMenu,
} as LimePlugin;
239 changes: 239 additions & 0 deletions plugins/lime-plugin-locate/src/locatePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,239 @@
import { Trans } from "@lingui/macro";
import L, { LatLngExpression, icon } from "leaflet";
import { useEffect, useRef, useState } from "preact/hooks";
import { LayersControl, MapContainer, Marker, TileLayer } from "react-leaflet";

import { Loading } from "components/loading";

import {
useChangeLocation,
useLoadLeaflet,
useLocation,
useNodesandlinks,
} from "plugins/lime-plugin-locate/src/locateQueries";

import { useBoardData } from "utils/queries";

import { getCommunityGeoJSON } from "./communityGeoJSON";
import { homeIcon } from "./leafletUtils";
import style from "./style.less";

const openStreetMapTileString = "http://{s}.tile.osm.org/{z}/{x}/{y}.png";
const openStreetMapAttribution =
'&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors';

const gmSatellite = "https://{s}.google.com/vt/lyrs=s&x={x}&y={y}&z={z}";
const gmHybrid = "https://{s}.google.com/vt/lyrs=s,h&x={x}&y={y}&z={z}";
const gmSubdomains = ["mt0", "mt1", "mt2", "mt3"];

function getCommunityLayer(nodeHostname, stationLat, stationLon, nodesData) {
/** Create a Leaflet layer with community nodes and links to be added to the map*/
if (nodesData[nodeHostname]) {
nodesData[nodeHostname].data.coordinates = {
lat: stationLat,
lon: stationLon,
};
}
// Get community GeoJSON, filter out nodes in same location as station host.
const geoJSON = getCommunityGeoJSON(nodesData, [stationLon, stationLat]);
return L.geoJSON(geoJSON, {
onEachFeature: (feature, layer) => {
if (feature.properties && feature.properties.name) {
layer.bindTooltip(feature.properties.name).openTooltip();
}
},
});
}

export const LocatePage = () => {
const { data: boardData } = useBoardData();
const {
isError: isAssetError,
isFetchedAfterMount: assetsLoaded,
isLoading: isLoadingAssets,
} = useLoadLeaflet({
refetchOnWindowFocus: false,
});

const {
data: nodeLocation,
isLoading: isLoadingLocation,
isFetched: locationLoaded,
} = useLocation({
enabled: assetsLoaded,
});

const { data: nodesData } = useNodesandlinks({
enabled: locationLoaded,
});

const { mutate: changeLocation, isLoading: submitting } = useChangeLocation(
{
onSettled: () => {
toogleEdition();
},
}
);

const loading = isLoadingLocation || isLoadingAssets;
const isCommunityLocation = nodeLocation.default;
const stationLat =
nodeLocation.location.lat !== "FIXME"
? nodeLocation.location.lat
: null;
const stationLon =
nodeLocation.location.lon !== "FIXME"
? nodeLocation.location.lon
: null;
const hasLocation = stationLat && !isCommunityLocation;

const [editting, setEditting] = useState(false);
const [nodeMarker, setNodeMarker] = useState<LatLngExpression>(null);
const [communityLayer, setCommunityLayer] = useState(null);

const mapRef = useRef<L.Map | null>();

// Set map position when map is available or location gets updated
useEffect(() => {
function updateNodeMarker(lat, lon) {
setNodeMarker([lat, lon]);
}
const mapInstance = mapRef.current;

if (!loading && mapInstance && stationLat) {
mapInstance.setView([+stationLat, +stationLon], 13);
updateNodeMarker(stationLat, stationLon);
}
}, [stationLat, stationLon, loading]);

// Center the map on the node also when editting is turned on
useEffect(() => {
const map = mapRef.current;
if (map && stationLat) {
editting && map.setView([+stationLat, +stationLon], 13);
}
}, [mapRef, editting, stationLat, stationLon]);

function onConfirmLocation() {
const position = mapRef.current.getCenter();
changeLocation({ lat: position.lat, lon: position.lng });
if (communityLayer) {
// Hide the community view, to avoid outdated links
toogleCommunityLayer();
}
}

function toogleCommunityLayer() {
if (communityLayer) {
mapRef.current.removeLayer(communityLayer);
setCommunityLayer(null);
} else {
const layer = getCommunityLayer(
boardData.hostname,
stationLat,
stationLon,
nodesData
);
layer.addTo(mapRef.current);
setCommunityLayer(layer);
}
}

function isReady() {
return !loading && typeof stationLat !== "undefined";
}

function toogleEdition() {
setEditting(!editting);
}

if (isAssetError) {
return (
<div id="map-container" className={style.hasAssetError}>
<Trans>Cannot load map, check your internet connection</Trans>
</div>
);
}

return (
<>
{(!isReady() || submitting) && (
<div id="loading-container" className={style.loadingContainer}>
<Loading />
</div>
)}
{isReady() && (
<MapContainer
center={[-30, -60]}
zoom={3}
scrollWheelZoom={true}
className={style.mapContainer}
ref={mapRef}
>
<LayersControl position="bottomright">
<LayersControl.BaseLayer checked name="Open Street Map">
<TileLayer
attribution={openStreetMapAttribution}
url={openStreetMapTileString}
/>
</LayersControl.BaseLayer>
<LayersControl.BaseLayer name="Google Maps Satellite">
<TileLayer
url={gmSatellite}
subdomains={gmSubdomains}
/>
</LayersControl.BaseLayer>
<LayersControl.BaseLayer name="Google Maps Hybrid">
<TileLayer
url={gmHybrid}
subdomains={gmSubdomains}
/>
</LayersControl.BaseLayer>
</LayersControl>
{nodeMarker && (
<Marker
position={nodeMarker}
icon={icon({ ...homeIcon })}
/>
)}
{editting && (
<div
id="location-marker"
className={style.locationMarker}
/>
)}
</MapContainer>
)}
{isReady() && (
<div id="edit-action" className={style.editAction}>
{editting && (
<button onClick={onConfirmLocation}>
<Trans>confirm location</Trans>
</button>
)}
{!editting && (
<button onClick={toogleCommunityLayer}>
{communityLayer ? (
<Trans>hide community</Trans>
) : (
<Trans>show community</Trans>
)}
</button>
)}

<button onClick={toogleEdition}>
{editting && <Trans>cancel</Trans>}
{!editting && hasLocation && (
<Trans>edit location</Trans>
)}
{!editting && !hasLocation && (
<Trans>locate my node</Trans>
)}
</button>
</div>
)}
</>
);
};

export default LocatePage;
21 changes: 14 additions & 7 deletions plugins/lime-plugin-node-admin/src/components/config/config.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { ComponentChildren } from "preact";

import { ListItem } from "components/list";
import Loading from "components/loading";

import style from "./config.style.less";

type ConfigProps = {
title: React.ReactNode,
subtitle?: React.ReactNode,
value: React.ReactNode,
onClick: () => void,
isLoading: boolean,
}
title: ComponentChildren;
subtitle?: ComponentChildren;
value: ComponentChildren;
onClick: () => void;
isLoading: boolean;
};

export const Config = ({
title,
Expand All @@ -27,7 +29,12 @@ export const Config = ({
{isLoading && <Loading />}
{!isLoading && (
<div>
{subtitle && <div className={style.subtitle}> {subtitle} </div>}
{subtitle && (
<div className={style.subtitle}>
{" "}
{subtitle}{" "}
</div>
)}
<div className={style.value}> {value} </div>
</div>
)}
Expand Down

0 comments on commit 9cad758

Please sign in to comment.