// License: LGPL-3.0-or-later const R = require('ramda') const flyd = require('flyd') // Stream that has true when google script is loaded const loaded$ = flyd.stream() // Stream of autocomplete data const data$ = flyd.stream() function initScript() { // if(document.getElementById('googleAutocomplete')) return // var script = document.createElement('script') // script.type = 'text/javascript' // script.id = 'googleAutocomplete' // document.body.appendChild(script) // script.src = `https://maps.googleapis.com/maps/api/js?key=${app.google_api}&libraries=places&callback=initGoogleAutocomplete` return loaded$ } window.initGoogleAutocomplete = () => loaded$(true) function initInput(input) { var autocomplete = new google.maps.places.Autocomplete(input, {types: ['geocode']}) autocomplete.addListener('place_changed', fillInAddress(autocomplete)) input.addEventListener('focus', geolocate(autocomplete)) input.addEventListener('keydown', e => { if(e.which === 13) e.preventDefault() }) return data$ } const acceptedTypes = { street_number: 'short_name' , route: 'long_name' , locality: 'long_name' , administrative_area_level_1: 'short_name' , country: 'long_name' , postal_code: 'short_name' } const fillInAddress = autocomplete => () => { var place = { components: autocomplete.getPlace().address_components} if(!place.components) return place.types = R.map(x => x.types[0], place.components) var address = placeData(place, 'street_number') ? placeData(place, 'street_number') + ' ' + placeData(place, 'route') : '' var data = { address: address , city: placeData(place, 'locality') , state_code: placeData(place, 'administrative_area_level_1') , country: placeData(place, 'country') , zip_code: placeData(place, 'postal_code') } data$(data) } function placeData(place, key) { const i = R.findIndex(R.equals(key), place.types) if(i >= 0) return place.components[i][acceptedTypes[key]] return '' } // Bias the autocomplete object to the user's geographical location, // as supplied by the browser's 'navigator.geolocation' object. const geolocate = autocomplete => () => { if(!navigator || !navigator.geolocation) return navigator.geolocation.getCurrentPosition(pos => { var geolocation = { lat: pos.coords.latitude , lng: pos.coords.longitude } var circle = new google.maps.Circle({ center: geolocation , radius: pos.coords.accuracy }) autocomplete.setBounds(circle.getBounds()) }) } module.exports = {initScript, initInput, data$, loaded$}