Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix (map): allow dynamic content in location field #3105

Open
wants to merge 12 commits into
base: develop
Choose a base branch
from
17 changes: 16 additions & 1 deletion src/block/map/edit.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
PanelAdvancedSettings,
ResizerTooltip,
StyleControl,
getDynamicContent,
} from '~stackable/components'
import { useDeviceType } from '~stackable/hooks'
import {
Expand Down Expand Up @@ -104,6 +105,7 @@ const Edit = props => {

const { stackable_google_maps_api_key: apiKey } = settings
const userCanManageApiKey = useMemo( () => currentUserHasCapability( 'manage_options' ), [] )
const mapAddress = address.startsWith( '!#stk_dynamic/' ) ? getDynamicContent( address ) : address

// This just forces the tooltip to update.
const [ , setResizingHeight ] = useState( '' )
Expand Down Expand Up @@ -210,6 +212,7 @@ const Edit = props => {
useEffect( () => {
if ( mapRef.current ) {
mapRef.current.setOptions( {
address,
center: location || DEFAULT_LOCATION,
zoom: zoom || DEFAULT_ZOOM,
fullscreenControl: showFullScreenButton,
Expand Down Expand Up @@ -243,6 +246,9 @@ const Edit = props => {
// Try geocoding the address.
const [ useGeocoding, setUseGeocoding ] = useState( true )
const geocodeAddress = useCallback( debounce( address => {
if ( address.startsWith( '!#stk_dynamic/' ) ) {
address = getDynamicContent( address )
}
if ( useGeocoding ) {
geocoderRef.current.geocode( {
address,
Expand All @@ -259,6 +265,12 @@ const Edit = props => {
}
}, 400 ), [ geocoderRef.current, setAttributes, useGeocoding ] )

useEffect( () => {
setTimeout( () => {
geocodeAddress( mapAddress )
}, 8000 )
}, [ mapAddress ] )

return (
<>
{ isSelected && (
Expand Down Expand Up @@ -291,6 +303,9 @@ const Edit = props => {
label={ __( 'Location', i18n ) }
attribute="address"
placeholder={ __( 'Enter an address or location', i18n ) }
help={ __( 'Type in a pair of latitude longitude coordinates.', i18n ) }
isDynamic={ true }
isFormatType={ false }
/>
</>
) : (
Expand Down Expand Up @@ -537,7 +552,7 @@ const Edit = props => {
) : (
<iframe
title={ __( 'Embedded content from Google Map Platform.', i18n ) }
src={ `https://maps.google.com/maps?q=${ address || DEFAULT_ADDRESS }&t=&z=${ zoom || DEFAULT_ZOOM }&ie=UTF8&output=embed` }
src={ `https://maps.google.com/maps?q=${ mapAddress || DEFAULT_ADDRESS }&t=&z=${ zoom || DEFAULT_ZOOM }&ie=UTF8&output=embed` }
frameBorder="0"
/>
) }
Expand Down
17 changes: 17 additions & 0 deletions src/block/map/editor.scss
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,23 @@
}
}

.stk-control__location-control {

.components-base-control {
width: 100%;
}

.stk-control__reset-button {
top: 28px;
}

.components-base-control__help {
text-align: justify;
hyphens: auto;
}

}

.stk-block-map__api-key-notice {
margin: 0 0 16px;
}
Expand Down
48 changes: 41 additions & 7 deletions src/block/map/frontend-map.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,16 +41,50 @@ class StackableMap {
const markerOptions = JSON.parse( mapCanvas.dataset.markerOptions || 'false' )
const markerIconOptions = JSON.parse( mapCanvas.dataset.iconOptions || '{}' )

// Hello Jami, I implemented a way where it doesnt have to be coordinates only haha.
// But if you do not like it just: remove the if and other variables, move the block of code outside of the setTimeout,
// and uncomment the if which is the implementation you originally mentioned

// eslint-disable-next-line no-undef
const map = new google.maps.Map( mapCanvas, mapOptions )
if ( markerOptions ) {
markerOptions.map = map
markerOptions.clickable = false
const geocoder = new google.maps.Geocoder()

// eslint-disable-next-line no-undef
const marker = new google.maps.Marker( markerOptions )
marker.setIcon( markerIconOptions )
let duration = 0
// If coordinates is just a string, turn it into an object
if ( typeof mapOptions.center === 'string' ) {
duration = 500
geocoder.geocode( {
address: mapOptions.center,
}, ( results, status ) => {
if ( status === 'OK' ) {
mapOptions.center = {
lat: parseFloat( results[ 0 ].geometry.location.lat() ),
lng: parseFloat( results[ 0 ].geometry.location.lng() ),
}
}
} )
}

// if ( mapOptions.center.match( /^\s*[-\d.]+(.*?)[, ][-\d.]+/ ) ) { // Check if there's a number comma/space number.
// const [ , lat, , lng ] = mapOptions.center.match( /^\s*([-\d.]+)(.*?)([-\d.]+)/ )
// mapOptions.center = {
// lat: parseFloat( lat ),
// lng: parseFloat( lng ),
// }
// }

// Inside a setTimeout since geolocation speed may vary
setTimeout( () => {
// eslint-disable-next-line no-undef
const map = new google.maps.Map( mapCanvas, mapOptions )
if ( markerOptions ) {
markerOptions.map = map
markerOptions.clickable = false

// eslint-disable-next-line no-undef
const marker = new google.maps.Marker( markerOptions )
marker.setIcon( markerIconOptions )
}
}, duration )
} )
}
}
Expand Down
42 changes: 32 additions & 10 deletions src/block/map/location-control.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
/**
* External dependencies
*/
import { i18n } from 'stackable'
import { i18n, isPro } from 'stackable'
import { DynamicContentControl, useDynamicContentControlProps } from '~stackable/components'

/**
* WordPress dependencies
*/
import { TextControl } from '@wordpress/components'
import { TextControl, BaseControl as GutBaseControl } from '@wordpress/components'
import { __ } from '@wordpress/i18n'
import {
useState, useEffect, useRef,
Expand All @@ -20,6 +21,14 @@ import {
const LocationControl = props => {
const [ waitForGoogle, setWaitForGoogle ] = useState( 0 )

const dynamicContentProps = useDynamicContentControlProps( {
value: props.value,
onChange: value => {
props.onTextChange( value )
},
isFormatType: false,
} )

useEffect( () => {
if ( ! window?.google?.maps ) {
const interval = setInterval( () => {
Expand Down Expand Up @@ -54,15 +63,28 @@ const LocationControl = props => {
}, [ ref.current, waitForGoogle ] )

return (
<TextControl
<GutBaseControl
className="stk-control stk-control__location-control"
label={ __( 'Location', i18n ) }
ref={ ref }
value={ props.value }
help={ __( 'Type in a pair of latitude longitude coordinates. You can also type in the name of the location if your API Key has Geocoding API and Places API enabled.', i18n ) }
onChange={ value => {
props.onTextChange( value )
} }
/>
help={ ! isPro
? __( 'Type in a pair of latitude longitude coordinates. You can also type in the name of the location if your API Key has Geocoding API and Places API enabled.', i18n )
: __( 'Type in a pair of latitude longitude coordinates. You can also type in the name of the location if your API Key has Geocoding API and Places API enabled. Dynamic Content only allows latitude longtitude coordinates', i18n )
}
>
<DynamicContentControl
enable={ true }
hasPanelModifiedIndicator={ true }
{ ...dynamicContentProps }
>
<TextControl
ref={ ref }
value={ props.value }
onChange={ value => {
props.onTextChange( value )
} }
/>
</DynamicContentControl>
</GutBaseControl>
)
}

Expand Down
8 changes: 6 additions & 2 deletions src/block/map/save.js
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ export const Save = props => {

const responsiveClass = getResponsiveClasses( props.attributes )
const blockAlignmentClass = getAlignmentClasses( props.attributes )

let tempLocation = location
const blockClassNames = classnames( [
props.className,
'stk-block-map',
Expand All @@ -60,9 +60,13 @@ export const Save = props => {
'stk--uses-api-key': usesApiKey,
} )

if ( address.startsWith( '!#stk_dynamic/' ) ) {
tempLocation = address
}

const styles = getMapStyles( attributes )
const mapOptions = {
center: location || DEFAULT_LOCATION,
center: tempLocation || DEFAULT_LOCATION,
zoom: zoom || DEFAULT_ZOOM,
styles: styles.length ? styles : undefined,
gestureHandling: isDraggable ? undefined : 'none',
Expand Down
2 changes: 1 addition & 1 deletion src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export {
export { default as Div } from './div'
export { default as ControlIconToggle } from './control-icon-toggle'
export {
default as DynamicContentControl, useDynamicContent, getDynamicContent,
default as DynamicContentControl, useDynamicContent, getDynamicContent, useDynamicContentControlProps,
} from './dynamic-content-control'
export { default as Separator2 } from './separator2'
export { default as ColumnInnerBlocks } from './column-inner-blocks'
Expand Down
Loading