import React, { useContext, useEffect, useState } from "react";
import useGeolocation from 'react-hook-geolocation'
import { booleanString, fakeEvent, FormContext, processOptions } from "../../_core";
/**
* Componente que permite obtener la ubicación del usuario,
* si la app no tiene permisos para obtener las coordenadas del dispositivo,
* solicitará acceso, y al darlo obtendrá la obicación,
* de lo contrario mostrata el contenido del componente.
* @name Reactor.Components.Input.GeolocationOqt
* @param {string!} name
* El nombre o identificador del elemento
* @param {("true"|"false")} [use_change="true"]
* Determina si se usara el evento de cambio
* @param {string} [delay="1000"]
* El tiempo que demora en enviar el evento de cambio al form (en ms)
* @param {GeolocationOqtOptions} [options={}]
* Json string con las opciones de useGeolocation
* @class
* @returns {GeolocationOqtResult}
* @example
<geolocation name="ubicacion">
debe aceptar los datos de geolocalizacion
</geolocation>
*/
export const GeolocationOqt = ({name, change_on_load = "false", use_change = "true", delay = "1000", options, children}) => {
const {latitude, longitude, speed, error} = useGeolocation(processOptions(options));
const formContext = useContext(FormContext);
const [loaded, setLoaded] = useState(false);
const [changes, setChanges] = useState(0);
useEffect(()=>{
setLoaded(true);
}, []);
useEffect(()=>{
if(loaded && !!latitude && !!longitude){
setChanges(changes => changes + 1);
}
}, [latitude, longitude, speed, loaded]);
useEffect(()=>{
if(changes === 1){
if(booleanString(change_on_load) || booleanString(use_change)){
formContext?.change(fakeEvent({name, use_change: "true", delay}));
}
}
if(changes > 1){
if(booleanString(use_change)){
formContext?.change(fakeEvent({name, use_change, delay}));
}
}
}, [changes, change_on_load, use_change, name, delay]);
return (
<>
{!error &&
<>
<input type="hidden" name={`${name}.lat`} value={latitude} use_change="false"/>
<input type="hidden" name={`${name}.lng`} value={longitude} use_change="false"/>
<input type="hidden" name={`${name}.speed`} value={speed} use_change="false"/>
</>
}
{error?.code &&
<>
<input type="hidden" name={`${name}.error.code`} value={error.code} use_change="false"/>
<input type="hidden" name={`${name}.error.message`} value={error.message} use_change="false"/>
{children}
</>
}
</>
)
}
/**
* @typedef {Object} GeolocationOqtOptions
* @property {boolean} enableHighAccuracy
* @property {number} maximumAge
* @property {number} timeout
*/
/**
* @typedef {Object} GeolocationOqtResult
* @property {number} lat Latitud
* @property {number} lng Longitud
* @property {number} speed Velocidad
* @property {GeolocationOqtError?} error Se obtiene un error cuando hay un problema del dispositivo o porque el usuario no otorgo acceso a la ubicación
*/
/**
* @typedef {Object} GeolocationOqtError
* @property {number} code Código de error
* @property {string} message Descripción
*/