Skip to content

Commit

Permalink
feat: change icons, add item handler (#106)
Browse files Browse the repository at this point in the history
* feat: change icons, add item handler

* refactor: allow fallback add dialog

* refactor: change current location text

* refactor: include geoloc
  • Loading branch information
pyphilia authored Apr 15, 2024
1 parent 60fcb10 commit 32c0ebb
Show file tree
Hide file tree
Showing 20 changed files with 273 additions and 162 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
"dependencies": {
"@emotion/react": "11.11.4",
"@emotion/styled": "11.11.5",
"@graasp/sdk": "github:graasp/graasp-sdk#packed",
"@graasp/sdk": "4.7.1",
"@graasp/translations": "1.23.0",
"@graasp/ui": "4.9.3",
"@mui/icons-material": "5.15.15",
Expand Down
11 changes: 10 additions & 1 deletion src/components/Map.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,15 @@ export const Map = {
},
],
}) as any,
useAddressFromGeolocation: () => ({ data: 'address' }) as any,
useAddressFromGeolocation: () =>
({ data: { addressLabel: 'address', country: 'countryName' } }) as any,
usePostItem: () => ({}) as any,
useRecycleItems: () => ({}) as any,
useSuggestionsForAddress: MOCK_USE_SUGGESTIONS as any,
handleAddOnClick({ location }) {
// eslint-disable-next-line no-alert
alert(JSON.stringify(location));
},
},
decorators: [
(Story) => (
Expand All @@ -47,6 +52,8 @@ export const Map = {
// cannot play inside an iframe
} satisfies Story;

// it shows the country form if localisation is disabled
// it shows the current location otherwise
export const MapSignedOut = {
args: {
itemId: 'd5a1c73d-cd4d-4f20-8a91-3c689ee87ea4',
Expand Down Expand Up @@ -102,6 +109,8 @@ export const MapMobile = {
// cannot play inside an iframe
} satisfies Story;

// it shows the country form if localisation is disabled
// it shows the current location otherwise
export const MapSignOutMobile = {
parameters: { viewport: { defaultViewport: 'mobile1' } },
args: {
Expand Down
52 changes: 49 additions & 3 deletions src/components/Map.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { useEffect, useState } from 'react';
import { MapContainer, TileLayer } from 'react-leaflet';

import { Skeleton } from '@mui/material';

import { DEFAULT_LANG } from '@graasp/translations';

import 'leaflet-easybutton/src/easy-button.css';
Expand All @@ -19,6 +21,12 @@ import MapContent from './map/MapContent';

type Props = QueryClientContextInterface;

const options = {
enableHighAccuracy: true,
timeout: 5000,
maximumAge: 0,
};

const Map = ({
itemId,
currentMember,
Expand All @@ -29,15 +37,48 @@ const Map = ({
usePostItem,
viewItem,
useDeleteItemGeolocation,
handleAddOnClick,
}: Props): JSX.Element => {
const [showMap, setShowMap] = useState<boolean>(false);
const [hasFetchedCurrentLocation, setHasFetchedCurrentLocation] =
useState<boolean>(false);

const [currentPosition, setCurrentPosition] = useState<{
lat: number;
lng: number;
}>();

useEffect(() => {
if (currentMember) {
i18n.changeLanguage(currentMember.extra.lang ?? DEFAULT_LANG);
}
}, [currentMember]);

// get current location
useEffect(() => {
const success = (pos: {
coords: { latitude: number; longitude: number };
}) => {
const crd = pos.coords;
setCurrentPosition({ lat: crd.latitude, lng: crd.longitude });
setHasFetchedCurrentLocation(true);
};

navigator.geolocation.getCurrentPosition(
success,
(err: { code: number; message: string }) => {
// eslint-disable-next-line no-console
console.warn(`ERROR(${err.code}): ${err.message}`);
setHasFetchedCurrentLocation(true);
},
options,
);
}, []);

if (!hasFetchedCurrentLocation) {
return <Skeleton width="100%" height="100%" />;
}

return (
<QueryClientContextProvider
itemId={itemId}
Expand All @@ -48,6 +89,7 @@ const Map = ({
useRecycleItems={useRecycleItems}
usePostItem={usePostItem}
viewItem={viewItem}
handleAddOnClick={handleAddOnClick}
useDeleteItemGeolocation={useDeleteItemGeolocation}
>
<div
Expand All @@ -73,12 +115,16 @@ const Map = ({
<LoggedOutWarning />

{/* focus on initial geoloc if item id is defined, cannot use useffect because of map updates */}
<InitialSetup showMap={showMap} setShowMap={setShowMap} />
<InitialSetup
showMap={showMap}
setShowMap={setShowMap}
currentPosition={currentPosition}
/>

{!showMap ? (
{!showMap && !currentPosition ? (
<CountryContent setShowMap={setShowMap} />
) : (
<MapContent />
<MapContent currentPosition={currentPosition} />
)}
</MapContainer>
</div>
Expand Down
19 changes: 18 additions & 1 deletion src/components/context/QueryClientContext.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
import { createContext, useContext, useMemo } from 'react';

import type { configureQueryClient } from '@graasp/query-client';
import { CompleteMember, DiscriminatedItem } from '@graasp/sdk';
import {
CompleteMember,
DiscriminatedItem,
ItemGeolocation,
} from '@graasp/sdk';

type QueryClientHooks = ReturnType<typeof configureQueryClient>['hooks'];
type QueryClientMutations = ReturnType<
Expand All @@ -11,13 +15,20 @@ type QueryClientMutations = ReturnType<
export interface QueryClientContextInterface {
itemId?: DiscriminatedItem['id'];
currentMember?: CompleteMember | null;
currentPosition?: { lat: number; lng: number };
useAddressFromGeolocation: QueryClientHooks['useAddressFromGeolocation'];
useItemsInMap: QueryClientHooks['useItemsInMap'];
useRecycleItems: QueryClientMutations['useRecycleItems'];
usePostItem: QueryClientMutations['usePostItem'];
useDeleteItemGeolocation: QueryClientMutations['useDeleteItemGeolocation'];
useSuggestionsForAddress: QueryClientHooks['useSuggestionsForAddress'];
viewItem: (item: DiscriminatedItem) => void;
handleAddOnClick?: ({
location,
}: {
location: Pick<ItemGeolocation, 'lat' | 'lng'> &
Partial<Pick<ItemGeolocation, 'country' | 'addressLabel'>>;
}) => void;
}

export const QueryClientContext = createContext<QueryClientContextInterface>({
Expand Down Expand Up @@ -45,6 +56,8 @@ export const QueryClientContextProvider = ({
useSuggestionsForAddress,
viewItem,
itemId,
currentPosition,
handleAddOnClick,
}: QueryClientContextInterface & { children: JSX.Element }): JSX.Element => {
const value = useMemo(
() => ({
Expand All @@ -57,6 +70,8 @@ export const QueryClientContextProvider = ({
viewItem,
itemId,
useSuggestionsForAddress,
currentPosition,
handleAddOnClick,
}),
[
currentMember,
Expand All @@ -68,6 +83,8 @@ export const QueryClientContextProvider = ({
useSuggestionsForAddress,
viewItem,
itemId,
currentPosition,
handleAddOnClick,
],
);

Expand Down
17 changes: 17 additions & 0 deletions src/components/icons/currentLocationMarker.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
47 changes: 19 additions & 28 deletions src/components/icons/icons.ts
Original file line number Diff line number Diff line change
@@ -1,40 +1,31 @@
import L from 'leaflet';
import 'leaflet-easybutton';

import markerPinPerson from '../../location.svg';
import { MarkerParent } from '../../types';
import currentMarker from './currentLocationMarker.svg';
import markerIcon from './marker.svg';
import pointerIcon from './pointer.svg';

const iconPerson = new L.Icon({
iconUrl: markerPinPerson,
iconSize: new L.Point(30, 30),
className: 'leaflet-div-icon',
const currentLocationMarker = new L.Icon({
iconUrl: currentMarker,
iconSize: [30, 30],
iconAnchor: [15, 30],
popupAnchor: [0, -30],
});

export const greenIcon = new L.Icon({
iconUrl:
'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-green.png',
shadowUrl:
'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
const marker = new L.Icon({
iconUrl: markerIcon,
iconSize: [30, 30],
iconAnchor: [15, 30],
popupAnchor: [0, -30],
shadowSize: [41, 41],
});

const redIcon = new L.Icon({
iconUrl:
'https://raw.githubusercontent.com/pointhi/leaflet-color-markers/master/img/marker-icon-2x-red.png',
shadowUrl:
'https://cdnjs.cloudflare.com/ajax/libs/leaflet/0.7.7/images/marker-shadow.png',
iconSize: [25, 41],
iconAnchor: [12, 41],
popupAnchor: [1, -34],
const pointer = new L.Icon({
iconUrl: pointerIcon,
iconSize: [30, 30],
iconAnchor: [15, 30],
popupAnchor: [0, -30],
shadowSize: [41, 41],
});

const iconsPerParent: { [key in MarkerParent]: L.Icon<any> } = {
MyItems: redIcon,
Published: greenIcon,
};

export { iconPerson, iconsPerParent };
export { currentLocationMarker, marker, pointer };
17 changes: 17 additions & 0 deletions src/components/icons/marker.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 17 additions & 0 deletions src/components/icons/pointer.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 32c0ebb

Please sign in to comment.