diff --git a/imports/api/ActiveFires/server/publications.js b/imports/api/ActiveFires/server/publications.js
index 0b9b2d7..278d937 100644
--- a/imports/api/ActiveFires/server/publications.js
+++ b/imports/api/ActiveFires/server/publications.js
@@ -27,6 +27,7 @@ const activefires = (northEastLng, northEastLat, southWestLng, southWestLat) =>
fields: {
lat: 1,
lon: 1,
+ when: 1,
scan: 1
}
});
diff --git a/imports/api/Fires/server/publications.js b/imports/api/Fires/server/publications.js
index 68eb4c8..575c7af 100644
--- a/imports/api/Fires/server/publications.js
+++ b/imports/api/Fires/server/publications.js
@@ -7,6 +7,7 @@ import urlEnc from '/imports/modules/url-encode';
import { Promise } from 'meteor/promise';
import NodeGeocoder from 'node-geocoder';
import { gmapServerKey } from '/imports/startup/server/IPGeocoder';
+import ActiveFiresCollection from '/imports/api/ActiveFires/ActiveFires';
import FiresCollection from '../Fires';
function findFire(unsealed) {
@@ -36,6 +37,75 @@ const unseal = async (obj) => {
const unsealW = obj => unseal(obj);
+const fixConfidence = (obj) => {
+ if (typeof obj.confidence === 'string') {
+ obj.confidence = Number.parseInt(obj.confidence, 10);
+ }
+ if (typeof obj.confidence === 'undefined' || isNaN(obj.confidence)) {
+ delete obj.confidence;
+ }
+ return obj;
+};
+
+const findOrCreateFire = (obj) => {
+ const fire = findFire(obj);
+ // console.log(`Found: ${fire.count()}`);
+ if (!obj.address) {
+ try {
+ const rev = Promise.await(geocoder.reverse({ lat: obj.lat, lon: obj.lon }));
+ if (rev[0]) {
+ obj.address = rev[0].formattedAddress;
+ }
+ // console.log(obj.address);
+ } catch (reve) {
+ console.warn(reve);
+ }
+ }
+ if (fire.count() === 0) {
+ // const result =
+ // console.log('Creating new fire');
+ FiresCollection.upsert({ ourid: obj.ourid, when: obj.when, type: obj.type }, { $set: obj }, { multi: false, upsert: true });
+ // console.log(JSON.stringify(result));
+ }
+ return findFire(obj);
+};
+
+Meteor.publish('fireFromActiveId', function fireFromActiveId(_id) {
+ try {
+ check(_id, String);
+ // console.log(`Looking for active fire ${_id}`);
+ const fire = ActiveFiresCollection.findOne(new Meteor.Collection.ObjectID(_id));
+ if (fire) {
+ // console.info(`Active fire found: ${_id}`);
+ return findOrCreateFire(fixConfidence(fire));
+ }
+ console.info(`Active fire not found: ${_id}`);
+ // Not found in active fires!
+ return this.ready();
+ } catch (e) {
+ console.info(`Active fire not found (with error): ${_id}`);
+ return this.ready();
+ }
+});
+
+Meteor.publish('fireFromId', function fireFromId(_id) {
+ try {
+ check(_id, String);
+ // console.log(`Looking for archive fire ${_id}`);
+ const fire = FiresCollection.find(new Meteor.Collection.ObjectID(_id));
+ if (fire.count() !== 0) {
+ // console.info(`Archive fire found: ${_id}`);
+ return fire;
+ }
+ console.info(`Fire not found: ${_id}`);
+ // Not found in active fires!
+ return this.ready();
+ } catch (e) {
+ console.info(`Active fire not found (with error): ${_id}`);
+ return this.ready();
+ }
+});
+
Meteor.publish('fireFromHash', function fireFromHash(fireEnc) {
check(fireEnc, String);
try {
@@ -55,32 +125,9 @@ Meteor.publish('fireFromHash', function fireFromHash(fireEnc) {
unsealed.updatedAt = !u ? new Date() : new Date(u);
// console.log(unsealed);
// FIXME:
- if (typeof unsealed.confidence === 'string') {
- unsealed.confidence = Number.parseInt(unsealed.confidence, 10);
- }
- if (typeof unsealed.confidence === 'undefined' || isNaN(unsealed.confidence)) {
- delete unsealed.confidence;
- }
- FiresCollection.schema.validate(unsealed);
- const fire = findFire(unsealed);
- // console.log(`Found: ${fire.count()}`);
- if (!unsealed.address) {
- try {
- const rev = Promise.await(geocoder.reverse({ lat: unsealed.lat, lon: unsealed.lon }));
- if (rev[0]) {
- unsealed.address = rev[0].formattedAddress;
- }
- // console.log(unsealed.address);
- } catch (reve) {
- console.warn(reve);
- }
- }
- if (fire.count() === 0) {
- // const result =
- FiresCollection.upsert({ ourid: unsealed.ourid, when: unsealed.when, type: unsealed.type }, { $set: unsealed }, { multi: false, upsert: true });
- // console.log(JSON.stringify(result));
- }
- return findFire(unsealed);
+ const unsealedFix = fixConfidence(unsealed);
+ FiresCollection.schema.validate(unsealedFix);
+ return findOrCreateFire(unsealedFix);
/* console.log(`fires: ${fire.count()}`);
* return fire; */
} catch (e) {
diff --git a/imports/startup/client/i18n.js b/imports/startup/client/i18n.js
index 2a3398d..d4e3fcc 100644
--- a/imports/startup/client/i18n.js
+++ b/imports/startup/client/i18n.js
@@ -53,7 +53,7 @@ i18nOpts.react = {
nsMode: 'default' */
};
-const sendMissing = true;
+const sendMissing = Meteor.isDevelopment;
if (sendMissing && !Meteor.isProduction) {
i18nOpts.sendMissing = true;
i18nOpts.sendMissingTo = 'fallback';
diff --git a/imports/startup/server/i18n.js b/imports/startup/server/i18n.js
index e6f3172..053d487 100644
--- a/imports/startup/server/i18n.js
+++ b/imports/startup/server/i18n.js
@@ -11,7 +11,7 @@ i18nOpts.backend.addPath = `${Meteor.rootPath}/../web.browser/app/${i18nOpts.bac
// console.log(i18nOpts.backend.loadPath);
i18nOpts.debug = false;
-i18nOpts.saveMissing = true;
+i18nOpts.saveMissing = Meteor.isDevelopment;
i18nOpts.initImmediate = false;
i18n
diff --git a/imports/ui/components/Maps/FireCircleMark.js b/imports/ui/components/Maps/FireCircleMark.js
index 477fba7..d90e312 100644
--- a/imports/ui/components/Maps/FireCircleMark.js
+++ b/imports/ui/components/Maps/FireCircleMark.js
@@ -1,19 +1,32 @@
import React from 'react';
import { Circle } from 'react-leaflet';
import PropTypes from 'prop-types';
+import FirePopup from './FirePopup';
const FireCircleMark = ({
lat,
lon,
- scan
+ nasa,
+ scan,
+ id,
+ when,
+ history,
+ t
}) => (
-
+
+
+
);
FireCircleMark.propTypes = {
scan: PropTypes.number.isRequired,
lat: PropTypes.number.isRequired,
- lon: PropTypes.number.isRequired
+ lon: PropTypes.number.isRequired,
+ nasa: PropTypes.bool.isRequired,
+ id: PropTypes.object.isRequired,
+ history: PropTypes.object.isRequired,
+ when: PropTypes.instanceOf(Date).isRequired,
+ t: PropTypes.func.isRequired
};
export default FireCircleMark;
diff --git a/imports/ui/components/Maps/FireIconMark.js b/imports/ui/components/Maps/FireIconMark.js
index 65f588d..f83b4bf 100644
--- a/imports/ui/components/Maps/FireIconMark.js
+++ b/imports/ui/components/Maps/FireIconMark.js
@@ -3,15 +3,25 @@ import React from 'react';
import { CircleMarker, Marker } from 'react-leaflet';
import PropTypes from 'prop-types';
import { fireIcon, nFireIcon } from '/imports/ui/components/Maps/Icons';
+import { translate } from 'react-i18next';
+import FirePopup from './FirePopup';
const FireIconMark = ({
lat,
lon,
- nasa
+ nasa,
+ id,
+ history,
+ when,
+ t
}) => (
-
-
+
+
+
+
+
+
);
@@ -19,7 +29,11 @@ FireIconMark.propTypes = {
// https://github.com/PaulLeCam/react-leaflet/tree/master/src/propTypes
lat: PropTypes.number.isRequired,
lon: PropTypes.number.isRequired,
- nasa: PropTypes.bool.isRequired
+ nasa: PropTypes.bool.isRequired,
+ id: PropTypes.object.isRequired,
+ history: PropTypes.object.isRequired,
+ when: PropTypes.instanceOf(Date).isRequired,
+ t: PropTypes.func.isRequired
};
-export default FireIconMark;
+export default translate([], { wait: true })(FireIconMark);
diff --git a/imports/ui/components/Maps/FireList.js b/imports/ui/components/Maps/FireList.js
index 60d8b3e..be20855 100644
--- a/imports/ui/components/Maps/FireList.js
+++ b/imports/ui/components/Maps/FireList.js
@@ -9,18 +9,18 @@ import FirePixel from '/imports/ui/components/Maps/FirePixel';
export default function FireList(props) {
const {
- fires, scale, useMarkers, nasa
+ fires, scale, useMarkers, nasa, t, history
} = props;
const useMarks = useMarkers && scale;
const usePixel = !nasa || !scale;
/* console.log(`Using marks: ${useMarks}, using pixels: ${usePixel}`); */
let items;
if (useMarks) {
- items = fires.map(({ _id, ...otherProps }) => ());
+ items = fires.map(({ _id, ...otherProps }) => ());
} else if (usePixel) {
items = fires.map(({ _id, ...otherProps }) => ());
} else {
- items = fires.map(({ _id, ...otherProps }) => ());
+ items = fires.map(({ _id, ...otherProps }) => ());
}
return ({items}
);
}
@@ -29,5 +29,7 @@ FireList.propTypes = {
fires: PropTypes.array.isRequired,
scale: PropTypes.bool.isRequired,
useMarkers: PropTypes.bool.isRequired,
- nasa: PropTypes.bool.isRequired
+ nasa: PropTypes.bool.isRequired,
+ history: PropTypes.object.isRequired,
+ t: PropTypes.func.isRequired
};
diff --git a/imports/ui/components/Maps/FirePopup.js b/imports/ui/components/Maps/FirePopup.js
new file mode 100644
index 0000000..c3f2f52
--- /dev/null
+++ b/imports/ui/components/Maps/FirePopup.js
@@ -0,0 +1,43 @@
+/* eslint-disable import/no-absolute-path */
+import React, { Fragment } from 'react';
+import { Popup, Tooltip } from 'react-leaflet';
+import PropTypes from 'prop-types';
+import { translate } from 'react-i18next';
+import moment from 'moment';
+
+const FirePopup = ({
+ lat,
+ lon,
+ nasa,
+ id,
+ history,
+ when,
+ t
+}) => (
+
+
+
+ {t('Coordenadas:')} {lat}, {lon}
+ {t('Fuente')}: {t(nasa ? 'NASA' : 'nuestros usuarios/as')}
+ {t('Detectado')}: {moment(when).fromNow()}
+
+ history.push(`/fire/active/${id}`)}>{t('Más información sobre este fuego')}
+
+
+
+ {t('Pulsa para más información')}
+
+);
+
+FirePopup.propTypes = {
+ // https://github.com/PaulLeCam/react-leaflet/tree/master/src/propTypes
+ lat: PropTypes.number.isRequired,
+ lon: PropTypes.number.isRequired,
+ nasa: PropTypes.bool.isRequired,
+ id: PropTypes.object.isRequired,
+ history: PropTypes.object.isRequired,
+ when: PropTypes.instanceOf(Date).isRequired,
+ t: PropTypes.func.isRequired
+};
+
+export default translate([], { wait: true })(FirePopup);
diff --git a/imports/ui/layouts/App/App.js b/imports/ui/layouts/App/App.js
index 4b1eb86..4e3ff27 100644
--- a/imports/ui/layouts/App/App.js
+++ b/imports/ui/layouts/App/App.js
@@ -83,6 +83,7 @@ const App = props => (
+
diff --git a/imports/ui/pages/Fires/Fires.js b/imports/ui/pages/Fires/Fires.js
index 3196865..52d1b81 100644
--- a/imports/ui/pages/Fires/Fires.js
+++ b/imports/ui/pages/Fires/Fires.js
@@ -34,6 +34,10 @@ class Fire extends React.Component {
componentWillReceiveProps(nextProps) {
if (this.props.when !== nextProps.when || this.props.loading !== nextProps.loading || this.props.notfound !== nextProps.notfound) {
// console.log(`Next when ${nextProps.when}`);
+ if (nextProps.fire && (nextProps.active || nextProps.fromHash)) {
+ // change url to archive with new _id
+ nextProps.history.replace(`/fire/archive/${nextProps.fire._id}`);
+ }
this.setState({
loading: nextProps.loading,
notfound: nextProps.notfound,
@@ -124,7 +128,7 @@ class Fire extends React.Component {
{Object.keys(FalsePositiveTypes).map(key => (