Skip to content

Commit

Permalink
Merge pull request #28 from VSG-EMEA/v1.1.1
Browse files Browse the repository at this point in the history
V1.1.1
  • Loading branch information
erikyo authored Jul 4, 2024
2 parents 69e8376 + c44b51a commit 31a7302
Show file tree
Hide file tree
Showing 18 changed files with 257 additions and 180 deletions.
10 changes: 3 additions & 7 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,10 @@ root = true
[*]
charset = utf-8
end_of_line = lf
indent_style = space
indent_size = 2
insert_final_newline = true
trim_trailing_whitespace = true

[*.php]
indent_size = 4
indent_style = tab

[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_style = space
indent_size = 2
8 changes: 4 additions & 4 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@
"@mapbox/mapbox-gl-language": "^1.0.1",
"@turf/turf": "^6.5.0",
"mapbox-gl": "^3.4.0",
"iso3166-helper": "^1.0.1"
"iso3166-helper": "^1.0.2"
},
"browserslist": [
"extends @wordpress/browserslist-config"
Expand Down
96 changes: 38 additions & 58 deletions src/components/Geocoder/init.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
import { getNextId } from '../../utils/dataset';
import * as MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
import { __ } from '@wordpress/i18n';
import { MapboxBlockDefaults, MapBoxListing, MarkerProps } from '../../types';
import { geoMarkerStyle } from '../Marker/defaults';
import { locateNearestStore } from '../../utils/spatialCalcs';
import { removePopups, showNearestStore } from '../Popup/';
import { MapboxBlockDefaults, MapBoxListing } from '../../types';
import { removePopups } from '../Popup/';
import { fitInView, flyToStore } from '../../utils/view';
import { removeTempMarkers } from '../Marker/utils';
import { DEFAULT_GEOCODER_TYPE_SEARCH } from '../../constants';
import { initGeoMarker } from '../Marker/Geomarker';
import './style.scss';
import type mapboxgl from 'mapbox-gl';
import { filterByPreferredArea, getCurrentContext } from './utils';
import { getNearestStore } from './utils';
import './style.scss';

/**
* Initializes the geocoder for the map.
Expand All @@ -37,13 +35,7 @@ export function initGeoCoder(
setFilteredListings: ( listings: MapBoxListing[] | null ) => void,
mapDefaults: MapboxBlockDefaults
): MapboxGeocoder | undefined {
const geomarkerListing = initGeoMarker( getNextId( listings ), markersRef );

const marker = {
element: geomarkerListing,
offset: [ 0, ( geoMarkerStyle.size || 0 ) * -0.5 ],
draggable: true,
};
const marker = initGeoMarker( getNextId( listings ), markersRef );

let searchResult: MapboxGeocoder.Result | undefined;

Expand All @@ -53,14 +45,20 @@ export function initGeoCoder(
mapboxgl,
marker: marker as unknown as mapboxgl.Marker,
language: mapDefaults.language || 'en',
placeholder: __( 'Find the nearest store', 'vsge-mapbox-block' ),
placeholder: __(
'Find the nearest sales agent',
'vsge-mapbox-block'
),
types: DEFAULT_GEOCODER_TYPE_SEARCH,
} );

if ( geocoder && geocoderRef ) {
( geocoderRef as HTMLElement ).appendChild( geocoder.onAdd( map ) );
}

/**
* Clears the geocoder input and resets the displayed listings.
*/
function onGeocoderClear() {
document
.getElementById( 'feature-listing' )
Expand All @@ -81,6 +79,12 @@ export function initGeoCoder(
fitInView( map, listings, mapRef );
}

/**
* A function that handles the geocoder result.
*
* @param {Object} ev - An object containing the geocoder result.
* @param {MapboxGeocoder.Result | undefined} ev.result - The geocoder result.
*/
function onGeocoderResult( ev: {
result: MapboxGeocoder.Result | undefined;
} ) {
Expand All @@ -100,61 +104,37 @@ export function initGeoCoder(
// Remove the active class from the geocoder
geocoderRef?.classList.remove( 'disabled' );

const sortedNearestStores = locateNearestStore(
searchResult.geometry,
listings
);

const currentArea = getCurrentContext( searchResult );
// const markerEl = geocoder.mapMarker.getElement() as HTMLElement;
const geoMarker = {
// @ts-expect-error - mapMarker is a property on the geocoder
...geocoder.mapMarker,
...searchResult,
geometry: searchResult.geometry,
};

const preferredStores = filterByPreferredArea(
currentArea,
sortedNearestStores
const filtered = getNearestStore(
searchResult,
mapRef,
map,
listings
);

// @ts-ignore
const geoMarker = geocoder.mapMarker;

// The map marker element
// const markerEl = geocoder.mapMarker.getElement() as HTMLElement;
geoMarker.geometry = searchResult.geometry;

geoMarker.onclick = () => {
// Remove the active class from the geocoder
geocoder.clear();
};
// Display the nearest store
setFilteredListings( filtered );

geoMarker.on( 'dragend', () => {
geoMarker.onDragEnd = () => {
// Update the marker's position
const lngLat = geoMarker.getLngLat();
// Update the marker's position
geoMarker.setLngLat( lngLat );
// Center the map
flyToStore( map, geoMarker );
} );

const newFilteredListings = showNearestStore(
{
...searchResult,
id: getNextId( listings ),
properties: searchResult.properties as MarkerProps,
geometry: {
coordinates: [
geoMarker.getLngLat().lng,
geoMarker.getLngLat().lat,
],
type: 'Point',
},
},
preferredStores.length
? preferredStores
: sortedNearestStores,
mapRef,
map
);
};

// Display the nearest store
setFilteredListings( [ ...newFilteredListings, geoMarker ] );
geoMarker.onclick = () => {
// Remove the active class from the geocoder
geocoder.clear();
};
}
}

Expand Down
51 changes: 49 additions & 2 deletions src/components/Geocoder/utils.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import * as MapboxGeocoder from '@mapbox/mapbox-gl-geocoder';
import { MapBoxListing } from '../../types';
import { CoordinatesDef, MapBoxListing } from '../../types';
import { isChildOf } from 'iso3166-helper';
import { locateNearestStore } from '../../utils/spatialCalcs';
import { showNearestStore } from '../Popup';
import { SEARCH_RESULTS_SHOWN } from '../../constants';

/**
* The geocoder entry context
*/
Expand Down Expand Up @@ -56,7 +60,7 @@ export function getCurrentContext(
* @return the filtered stores
*/
export function filterByPreferredArea(
currentContext: { region: CurrentContext[ 'region' ] },
currentContext: CurrentContext,
stores: MapBoxListing[]
): MapBoxListing[] {
/** @member preferredStores the list of the stores that should be shown because related to the area of the search */
Expand All @@ -78,3 +82,46 @@ export function filterByPreferredArea(
} );
return preferredStores;
}

/**
* Retrieves the nearest store based on the given result, map, listings, and optional myLocationPin.
*
* @param {MapboxGeocoder.Result} result - The result object from the Mapbox geocoder.
* @param {HTMLDivElement} mapRef - The reference to the map container.
* @param {mapboxgl.Map} map - The map object.
* @param {MapBoxListing[]} listings - The list of stores.
* @param {MapBoxListing} [myLocationPin] - The optional location pin.
*
* @return {MapBoxListing[]} The sorted list of nearest stores.
*/
export function getNearestStore(
result: MapboxGeocoder.Result,
mapRef: HTMLDivElement,
map: mapboxgl.Map,
listings: MapBoxListing[],
myLocationPin?: MapBoxListing
): MapBoxListing[] {
const currentArea = getCurrentContext( result );

// locate the nearest store on the map
const sortedNearestStores = locateNearestStore(
result.geometry.coordinates as CoordinatesDef,
listings
)?.slice( 0, SEARCH_RESULTS_SHOWN );

// filter results by preferred area
const preferredStores = filterByPreferredArea(
currentArea,
sortedNearestStores
);

// if there are preferred stores, show them otherwise show the nearest store
const sortedListings = preferredStores.length
? preferredStores
: sortedNearestStores;

// then show the nearest store
showNearestStore( myLocationPin, sortedListings, mapRef, map );

return [ ...sortedListings ];
}
19 changes: 19 additions & 0 deletions src/components/Mapbox/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,23 @@ export function MapBox( {

setUpdatedPin( [ newTempMarker ] );
setListings( newListings );

const popupRef = createRef< HTMLDivElement | null >();
addPopup(
map.current,
newTempMarker,
popupRef.current,
<PinPointPopup
location={ clickedPoint }
listings={ listings }
setListings={ setListings }
setFilteredListings={ setFilteredListings }
mapRef={ mapRef.current }
map={ map.current }
mapDefaults={ mapDefaults }
markersRef={ markersRef.current }
/>
);
return;
}

Expand Down Expand Up @@ -236,6 +253,8 @@ export function MapBox( {
setFilteredListings={ setFilteredListings }
mapRef={ mapRef.current }
map={ map.current }
mapDefaults={ mapDefaults }
markersRef={ markersRef.current }
/>
);
return;
Expand Down
6 changes: 2 additions & 4 deletions src/components/Mapbox/style.scss
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
// the map
.wp-block-vsge-mapbox .map-wrapper {
display: flex;
overflow: hidden;
gap: 24px;
width: 100%;

@media (max-width: 600px) {
gap: var(--wp--preset--spacing--20);
gap: var(--wp--preset--spacing--30);
flex-direction: column-reverse;
min-height: 100vh;
}

.map {
Expand All @@ -29,7 +27,7 @@
}

.mapboxgl-popup-content {
max-width: 280px;
width: auto !important;

@media (max-width: 600px) {
width: 100%;
Expand Down
19 changes: 14 additions & 5 deletions src/components/Marker/Geomarker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { PinPoint } from './marker-icons';
import { createRoot } from '@wordpress/element';
import { Marker } from './';
import { geocoderMarkerDefaults, geoMarkerStyle } from './defaults';
import type mapboxgl from 'mapbox-gl';

/**
* This function initializes a map marker using a React component and adds it to a Mapbox map.
Expand All @@ -13,12 +14,22 @@ import { geocoderMarkerDefaults, geoMarkerStyle } from './defaults';
export const initGeoMarker = (
id: number,
markersRef: HTMLButtonElement[]
): Element => {
): mapboxgl.Marker => {
// Create a new DOM root and save it to the React ref
markersRef[ id ] = document.createElement( 'button' );
markersRef[ id ].className = 'marker marker-geocoder disabled';

const root = createRoot( markersRef[ id ] );
makeGeoMarker( markersRef[ id ], id );

return {
element: markersRef[ id ] as HTMLButtonElement,
offset: [ 0, ( geoMarkerStyle.size || 0 ) * -0.5 ],
draggable: true,
};
};

export function makeGeoMarker( markersRef, id ) {
const root = createRoot( markersRef );

const defaultStyle = geoMarkerStyle;
const markerData = geocoderMarkerDefaults( id, defaultStyle );
Expand All @@ -32,6 +43,4 @@ export const initGeoMarker = (
<PinPoint color={ defaultStyle.color } size={ defaultStyle.size } />
</Marker>
);

return markersRef[ id ];
};
}
Loading

0 comments on commit 31a7302

Please sign in to comment.