Síntoma: en staging /fires no pintaba teselas ni fuegos, no creaba la suscripción `activefiresmyloc` y se quedaba con "Actualizando…" para siempre. Se había atribuido a que el navegador de las pruebas no compone; no era eso. El mismo navegador pinta la portada, y pinta /fires perfectamente contra un servidor local. La diferencia era la clave de Google. `DefMapLayers` montaba el control de capas con dos capas base (OSM color y gris) y, cuando `Gkeys` resolvía la clave, volvía a renderizar añadiendo tres capas de Google. En esa segunda pasada react-leaflet se dejaba por el camino la capa base marcada, y el mapa se quedaba sin ninguna. En desarrollo no hay clave, así que la segunda pasada no añadía nada y el bug no se veía nunca. El control se monta ahora una sola vez, con la lista de capas ya cerrada, y con un tope de 5 s por si el script de Google no llega: las capas de Google son un extra, el mapa tiene que salir igual. Reproducido en local poniendo una clave falsa en settings-ci.json (0 teselas antes del arreglo, 15 después). Esa clave falsa se queda ahí a propósito, para que la suite e2e recorra el mismo camino que staging y producción, y e2e/tests/fires-map.spec.js lo fija: teselas, una única capa base marcada, suscripción por viewport, y que no se quede en "Actualizando…". 16 tests e2e en verde.
110 lines
3.8 KiB
JavaScript
110 lines
3.8 KiB
JavaScript
/* eslint-disable react/jsx-indent-props */
|
|
/* eslint-disable import/no-absolute-path */
|
|
/* eslint-disable import/no-absolute-path */
|
|
|
|
import React, { Component } from 'react';
|
|
import PropTypes from 'prop-types';
|
|
import { withTranslation } from 'react-i18next';
|
|
import GoogleMutantLayer from '/imports/ui/components/Maps/GoogleMutantLayer';
|
|
import Gkeys from '/imports/startup/client/Gkeys';
|
|
import { TileLayer, LayersControl } from 'react-leaflet';
|
|
|
|
const { BaseLayer } = LayersControl;
|
|
|
|
const defOpacity = 0.7;
|
|
|
|
// Cuánto se espera a que Google conteste antes de montar el control solo con
|
|
// OpenStreetMap. Si el script de Google no llega (sin red hacia Google, una
|
|
// extensión que lo bloquea, un despliegue sin clave), el mapa tiene que salir
|
|
// igual: las capas de Google son un extra.
|
|
const GMAPS_WAIT_MS = 5000;
|
|
|
|
class DefMapLayers extends Component {
|
|
constructor(props) {
|
|
super(props);
|
|
this.state = {
|
|
gkey: null,
|
|
// El control de capas se monta UNA vez, con la lista de capas ya cerrada.
|
|
// Añadirle capas después —que es lo que pasaba al resolverse la clave de
|
|
// Google— hacía que react-leaflet se dejara por el camino la capa base
|
|
// marcada, y el mapa se quedaba en gris: sin teselas, sin fuegos y con el
|
|
// "Actualizando…" eterno. Solo se veía en despliegues CON clave de Google
|
|
// (staging y producción), nunca en desarrollo, que no la tiene.
|
|
ready: false
|
|
};
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.mounted = true;
|
|
const settle = (key) => {
|
|
if (!this.mounted || this.state.ready) return;
|
|
this.setState({ gkey: key || null, ready: true });
|
|
};
|
|
Gkeys.load((err, key) => settle(key));
|
|
this.waitTimer = setTimeout(() => settle(null), GMAPS_WAIT_MS);
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.mounted = false;
|
|
clearTimeout(this.waitTimer);
|
|
}
|
|
|
|
render() {
|
|
const { t } = this.props;
|
|
if (!this.state.ready) return null;
|
|
const osmgraylayer = (
|
|
<BaseLayer checked={this.props.gray} name={t('Mapa gris de OpenStreetMap')}>
|
|
<TileLayer
|
|
opacity={defOpacity}
|
|
attribution="© <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
|
|
// url="https://tiles.wmflabs.org/bw-mapnik/{z}/{x}/{y}.png"
|
|
url="https://cartodb-basemaps-{s}.global.ssl.fastly.net/light_all/{z}/{x}/{y}.png"
|
|
/>
|
|
</BaseLayer>);
|
|
const osmlayer = (
|
|
<BaseLayer checked={this.props.osmcolor} name={t('Mapa color de OpenStreetMap')}>
|
|
<TileLayer
|
|
opacity={defOpacity}
|
|
attribution="&copy <a href="http://osm.org/copyright">OpenStreetMap</a> contributors"
|
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
/>
|
|
</BaseLayer>);
|
|
return (
|
|
<LayersControl position="topleft">
|
|
{osmlayer}
|
|
{osmgraylayer}
|
|
{/* React.Fragment does not work here */}
|
|
{ this.state.gkey &&
|
|
<BaseLayer name={t('Mapa de carreteras de Google')}>
|
|
<GoogleMutantLayer opacity={defOpacity} maptype="ROADMAP" />
|
|
</BaseLayer> }
|
|
{ this.state.gkey &&
|
|
<BaseLayer name={t('Mapa de terreno de Google')} checked={this.props.terrain}>
|
|
<GoogleMutantLayer opacity={defOpacity} maptype="TERRAIN" />
|
|
</BaseLayer> }
|
|
{ this.state.gkey &&
|
|
<BaseLayer name={t('Mapa de satélite de Google')} checked={this.props.satellite}>
|
|
<GoogleMutantLayer opacity={defOpacity} maptype="SATELLITE" />
|
|
</BaseLayer> }
|
|
</LayersControl>
|
|
);
|
|
}
|
|
}
|
|
|
|
DefMapLayers.propTypes = {
|
|
t: PropTypes.func.isRequired,
|
|
gray: PropTypes.bool,
|
|
osmcolor: PropTypes.bool,
|
|
terrain: PropTypes.bool,
|
|
satellite: PropTypes.bool
|
|
|
|
};
|
|
|
|
DefMapLayers.defaultProps = {
|
|
gray: false,
|
|
osmcolor: false,
|
|
terrain: false,
|
|
satellite: false
|
|
};
|
|
|
|
export default withTranslation()(DefMapLayers);
|