Skip to content

Commit

Permalink
Merge pull request #4 from mfrederic/fix/map-markers
Browse files Browse the repository at this point in the history
Add numerous map features and fix minor issues
  • Loading branch information
mfrederic authored Mar 29, 2024
2 parents fe27763 + 79478bf commit e34d81c
Show file tree
Hide file tree
Showing 16 changed files with 219 additions and 50 deletions.
49 changes: 47 additions & 2 deletions frontend/package-lock.json

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

5 changes: 4 additions & 1 deletion frontend/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "realt-properties-map-frontend",
"version": "1.0.1",
"version": "1.1.0",
"license": "Apache-2.0",
"scripts": {
"start": "PORT=3010 react-scripts start",
Expand Down Expand Up @@ -34,6 +34,7 @@
"@emotion/styled": "^11.11.0",
"@graphql-codegen/cli": "^5.0.2",
"@heroicons/react": "^2.1.3",
"@mantine/carousel": "^7.7.0",
"@mantine/core": "^7.7.0",
"@mantine/form": "^7.7.0",
"@mantine/hooks": "^7.7.0",
Expand All @@ -43,6 +44,8 @@
"@reduxjs/toolkit": "^2.2.2",
"axios": "^1.6.8",
"axios-cache-interceptor": "^1.5.1",
"dayjs": "^1.11.10",
"embla-carousel-react": "^8.0.0",
"ethers": "^6.11.1",
"graphql": "^16.8.1",
"i18next": "^23.10.1",
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Provider } from 'react-redux';
import store from './store/store';
import { RealtMap } from './components/Map/MapWrapper';
import { MapWrapper } from './components/Map/MapWrapper';
import { AppActions } from './components/Settings/AppActions';
import { MantineProviders } from './providers/MantineProvider';
import { HotkeysProvider } from './providers/HotkeysProvider';
Expand All @@ -13,7 +13,7 @@ function App() {
<InitStoreProvider>
<MantineProviders>
<HotkeysProvider>
<RealtMap />
<MapWrapper />
<AppActions />
</HotkeysProvider>
</MantineProviders>
Expand Down
19 changes: 18 additions & 1 deletion frontend/src/components/Map/MapEvents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@ import { LatLng } from 'leaflet';
import { useLeafletContext } from '@react-leaflet/core';
import { useAppSelector } from '../../hooks/useInitStore';
import { selectedLatLng } from '../../store/marker/markerSelector';
import { selectMarkerOpacity } from '../../store/mapOptions/mapOptionsSelector';
import { selectDifferentiateOwned, selectMarkerOpacity } from '../../store/mapOptions/mapOptionsSelector';
import { CSSCLASSES, OWNED_SELECTOR } from './MapMarkers';

let previousLatLng: Pick<LatLng, 'lat' | 'lng'> | undefined;
export function MapEvents() {
const { map } = useLeafletContext();
const latLng = useAppSelector(selectedLatLng);
const markerOpacity = useAppSelector(selectMarkerOpacity);
const differentiateOwned = useAppSelector(selectDifferentiateOwned);

useEffect(() => {
if (latLng) {
Expand All @@ -30,5 +32,20 @@ export function MapEvents() {
});
}, [markerOpacity]);

useEffect(() => {
const owned = CSSCLASSES.owned.split(' ');
const notOwned = CSSCLASSES.notOwned.split(' ');
document
.querySelectorAll(`${OWNED_SELECTOR} .marker-svg`)
.forEach((el) => {
el.classList.remove(...notOwned, ...owned);
if (differentiateOwned) {
el.classList.add(...owned);
return;
}
el.classList.add(...notOwned);
});
}, [differentiateOwned]);

return null;
}
39 changes: 21 additions & 18 deletions frontend/src/components/Map/MapMarkers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,13 @@ import { Property } from '../../types/property';
import { useAppDispatch, useAppSelector } from '../../hooks/useInitStore';
import { setSelected } from '../../store/marker/markerReducer';

export const OWNED_SELECTOR = '[data-marker-owned]';
export const CSSCLASSES = {
owned: 'stroke-white owned drop-shadow-lg',
notOwned: 'opacity-80',
}


function pinSvg(cssClasses: string) {
return `<svg width="50" height="50" viewBox="0 0 50 78" class="marker-svg ${cssClasses
}"><path class="at-176__pin" d="M24,0A24,24,0,0,0,0,24C0,37.25,20,72,24,72S48,37.25,48,24A24,24,0,0,0,24,0Zm0,33a9,9,0,1,1,9-9A9,9,0,0,1,24,33Z"/></svg>`;
Expand All @@ -17,9 +24,11 @@ function pinSvg(cssClasses: string) {
// TODO - Map options for opacity
export function generateIcon(
property: Property,
differentiateOwned: boolean,
markerOpacity: number,
) {
const owned = property.ownedAmount > 0;
const ownedClass = differentiateOwned && owned ? CSSCLASSES.owned : CSSCLASSES.notOwned;
return new DivIcon({
html:
`<div class="relative marker-icon"
Expand All @@ -28,7 +37,7 @@ export function generateIcon(
${owned ? 'data-marker-owned' : ''}
${property.source ? `data-marker-${property.source}` : ''}
${property.ownerWallets.length ? `data-marker-wallet="${property.ownerWallets.join(' ')}"` : ''}>
${pinSvg(`${property.iconColorClass}-icon ${owned ? 'stroke-white owned drop-shadow-lg' : 'opacity-80'}`)}
${pinSvg(`${property.iconColorClass}-icon ${ownedClass}`)}
<i class="text-3xl drop-shadow-sm mf-icon material-icons absolute top-0 left-[20%]">${property.icon}</i>
</div>`,
iconSize: [50, 50],
Expand All @@ -41,7 +50,6 @@ function filterProperties(
displayAll: boolean,
displayGnosis: boolean,
displayRmm: boolean,
displayedWalletsAddresses: string[],
) {
return properties
.filter((property) => {
Expand All @@ -55,20 +63,18 @@ function filterProperties(
if (!displayRmm && property.source === 'rmm') {
toInclude = false;
}
if (
displayedWalletsAddresses.length > 0
&& property.ownerWallets.length > 0
&& !property.ownerWallets.some((address) => displayedWalletsAddresses.includes(address.toLowerCase()))
) {
toInclude = false;
}
return toInclude;
})
}

function createMarker(property: Property, markerOpacity: number, t: TFunction<"common", undefined>): Marker {
function createMarker(
property: Property,
markerOpacity: number,
differentiateOwned: boolean,
t: TFunction<"common", undefined>,
): Marker {
return marker([property.coordinate.lat, property.coordinate.lng], {
icon: generateIcon(property, markerOpacity),
icon: generateIcon(property, differentiateOwned, markerOpacity),
alt: property.propertyTypeName,
title: t('propertyType.' + property.propertyTypeName),
});
Expand Down Expand Up @@ -113,13 +119,10 @@ export function MapMarkers({
displayAll,
displayGnosis,
displayRmm,
differentiateOwned,
markerOpacity,
} = useAppSelector((state) => state.mapOptions);

const displayedWalletsAddresses = wallets
.filter((wallet) => wallet.visible)
.map((wallet) => wallet.address.toLowerCase());

function onMarkerClicked(event: LeafletMouseEvent, property: Property) {
const currentZoom = map.getZoom();
map.setView({
Expand Down Expand Up @@ -170,17 +173,17 @@ export function MapMarkers({
clearMap();
markerCluster = getCleanMarkerCluster();

filterProperties(properties, displayAll, displayGnosis, displayRmm, displayedWalletsAddresses)
filterProperties(properties, displayAll, displayGnosis, displayRmm)
.forEach((property) => {
const marker = createMarker(property, markerOpacity, t)
const marker = createMarker(property, markerOpacity, differentiateOwned, t)
.addEventListener('click', (event) => onMarkerClicked(event, property));
markers.push(marker);
markerCluster.addLayer(marker);
});
map.addLayer(markerCluster);

// eslint-disable-next-line react-hooks/exhaustive-deps
}, [properties, displayAll, displayGnosis, displayRmm, displayedWalletsAddresses]);
}, [properties, displayAll, displayGnosis, displayRmm, differentiateOwned, markerOpacity]);

return null;
}
2 changes: 1 addition & 1 deletion frontend/src/components/Map/MapWrapper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { PropertyPanel } from './PropertyPanel';
import { MapMarkers } from './MapMarkers';
import { MapEvents } from './MapEvents';

export function RealtMap() {
export function MapWrapper() {
const realToken = useAppSelector(selectRealtokensList);
const wallets = useAppSelector(selectWalletsList);

Expand Down
Loading

0 comments on commit e34d81c

Please sign in to comment.