154 lines
4.1 KiB
TypeScript
154 lines
4.1 KiB
TypeScript
// ---------------------------------------------------------------------------------------------------------------------
|
|
//! Imports
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
// -------------------------------------------------- React & Next -----------------------------------------------------
|
|
import { useEffect, useRef, useState } from 'react';
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
// --------------------------------------------------- Components ------------------------------------------------------
|
|
import { IconLayer, ScatterplotLayer } from 'deck.gl';
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
// ------------------------------------------------- Assets & Styles ---------------------------------------------------
|
|
import { StringifiedPinIcon } from '@/assets/PinIcon';
|
|
import { getDataset } from '../request';
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
export const useData = () => {
|
|
const deckRef = useRef(null);
|
|
|
|
const [canUseGeolocation, setCanUseGeolocation] = useState<boolean>(false);
|
|
const [geoError, setGeoError] = useState<string | null>(null);
|
|
const [userLocation, setUserLocation] = useState<{ [key: string]: number }>(
|
|
{}
|
|
);
|
|
|
|
const [source, setSource] = useState([]);
|
|
const [layers, setLayers] = useState([]);
|
|
|
|
const [isAddLoveOpened, setIsAddLoveOpened] = useState<boolean>(false);
|
|
const [isLoading, setIsLoading] = useState<boolean>(false);
|
|
const [addLoveMessage, setAddLoveMessage] = useState<string | null>(null);
|
|
|
|
const [viewState, setViewState] = useState<any>({
|
|
longitude: 2.209666999999996,
|
|
latitude: 46.232192999999995,
|
|
zoom: 5,
|
|
});
|
|
|
|
useEffect(() => {
|
|
if ('geolocation' in navigator == false) {
|
|
setCanUseGeolocation(false);
|
|
return;
|
|
}
|
|
|
|
setCanUseGeolocation(true);
|
|
|
|
navigator.geolocation.getCurrentPosition(
|
|
(position) => {
|
|
setViewState((prev) => ({
|
|
...prev,
|
|
latitude: position.coords.latitude,
|
|
longitude: position.coords.longitude,
|
|
zoom: 17,
|
|
}));
|
|
setUserLocation({
|
|
latitude: position.coords.latitude,
|
|
longitude: position.coords.longitude,
|
|
});
|
|
},
|
|
(error) => {
|
|
console.warn(error.message);
|
|
if (error.PERMISSION_DENIED) {
|
|
setGeoError('permission_denied');
|
|
}
|
|
},
|
|
{
|
|
maximumAge: 0,
|
|
timeout: 5000,
|
|
enableHighAccuracy: true,
|
|
}
|
|
);
|
|
|
|
(async () => {
|
|
const dataset = await getDataset();
|
|
|
|
const formattedDataset = dataset.map((point) => {
|
|
const properties = { ...point };
|
|
delete properties.geopoint;
|
|
|
|
return {
|
|
type: 'Feature',
|
|
geometry: point.geopoint,
|
|
properties: properties,
|
|
};
|
|
});
|
|
|
|
setSource(formattedDataset);
|
|
})();
|
|
}, []);
|
|
|
|
useEffect(() => {
|
|
const newLayers = [];
|
|
|
|
if (userLocation) {
|
|
const userLayer = new ScatterplotLayer({
|
|
id: 'userLayer',
|
|
data: [userLocation],
|
|
stroked: true,
|
|
getPosition: (d) => [d.longitude, d.latitude],
|
|
getRadius: 10,
|
|
getFillColor: [217, 66, 83],
|
|
getLineColor: [217, 66, 83, 175],
|
|
getLineWidth: 5,
|
|
radiusUnits: 'pixels',
|
|
lineWidthUnits: 'pixels',
|
|
pickable: false,
|
|
});
|
|
|
|
newLayers.push(userLayer);
|
|
}
|
|
|
|
const datasetLayer = new IconLayer({
|
|
id: 'lovePoints',
|
|
data: source,
|
|
iconAtlas: `data:image/svg+xml;charset=utf-8,${encodeURIComponent(
|
|
StringifiedPinIcon()
|
|
)}`,
|
|
iconMapping: {
|
|
marker: {
|
|
x: 0,
|
|
y: 0,
|
|
width: 100,
|
|
height: 100,
|
|
anchorY: 100,
|
|
},
|
|
},
|
|
getIcon: (d) => 'marker',
|
|
getSize: (d) => 35,
|
|
getPosition: (d) => d.geometry.coordinates,
|
|
billboard: true,
|
|
pickable: true,
|
|
});
|
|
|
|
newLayers.push(datasetLayer);
|
|
setLayers(newLayers);
|
|
}, [userLocation, source, isAddLoveOpened]);
|
|
|
|
return {
|
|
deckRef,
|
|
viewState,
|
|
setViewState,
|
|
geoError,
|
|
layers,
|
|
canUseGeolocation,
|
|
isAddLoveOpened,
|
|
setIsAddLoveOpened,
|
|
isLoading,
|
|
setIsLoading,
|
|
addLoveMessage,
|
|
setAddLoveMessage,
|
|
};
|
|
};
|