Added Fires page, collection and fire comments
This commit is contained in:
parent
3bf21c8caf
commit
40aedbfdfb
19 changed files with 290 additions and 66 deletions
|
|
@ -7,6 +7,7 @@ const firesCommonSchema = {
|
|||
ourid: LocationSchema,
|
||||
lat: Number,
|
||||
lon: Number,
|
||||
address: { type: String, optional: true },
|
||||
scan: Number,
|
||||
type: String,
|
||||
when: Date,
|
||||
|
|
|
|||
|
|
@ -6,23 +6,43 @@ import { check } from 'meteor/check';
|
|||
import urlEnc from '/imports/modules/url-encode';
|
||||
import { Promise } from 'meteor/promise';
|
||||
import FiresCollection from '../Fires';
|
||||
import NodeGeocoder from 'node-geocoder';
|
||||
import { gmapServerKey } from '/imports/startup/server/IPGeocoder';
|
||||
|
||||
function findFire(unsealed) {
|
||||
const fire = FiresCollection.find({ ourid: { type: 'Point', coordinates: [unsealed.lon, unsealed.lat] } });
|
||||
return fire;
|
||||
}
|
||||
|
||||
const options = {
|
||||
provider: 'google',
|
||||
// Optional depending on the providers
|
||||
httpAdapter: 'https', // Default
|
||||
apiKey: gmapServerKey, // for Mapquest, OpenCage, Google Premier
|
||||
formatter: null // 'gpx', 'string', ...
|
||||
};
|
||||
|
||||
const geocoder = NodeGeocoder(options);
|
||||
|
||||
Meteor.publish('fireFromHash', function fireFromHash(fireEnc) {
|
||||
check(fireEnc, String);
|
||||
try {
|
||||
// console.log(fireEnc);
|
||||
const unsealed = Promise.await(urlEnc.decrypt(fireEnc));
|
||||
const w = unsealed.when;
|
||||
// console.log(w);
|
||||
unsealed.when = new Date(w);
|
||||
// console.log(unsealed);
|
||||
FiresCollection.schema.validate(unsealed);
|
||||
const fire = findFire(unsealed);
|
||||
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.error(reve);
|
||||
}
|
||||
if (fire.count() === 0) {
|
||||
const result = FiresCollection.upsert({ ourid: unsealed.ourid }, { $set: unsealed }, { multi: false, upsert: true });
|
||||
console.log(JSON.stringify(result));
|
||||
|
|
|
|||
42
imports/startup/client/comments.js
Normal file
42
imports/startup/client/comments.js
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/* global Comments */
|
||||
/* eslint-disable import/no-absolute-path */
|
||||
|
||||
import i18n from '/imports/startup/client/i18n';
|
||||
import '/imports/startup/common/comments';
|
||||
|
||||
import './comments.scss';
|
||||
|
||||
i18n.init((err, t) => {
|
||||
Comments.ui.setContent({
|
||||
title: ' ', // i18n.t('Comentarios'),
|
||||
save: t('Guardar'),
|
||||
reply: t('Responder'),
|
||||
edit: t('Editar'),
|
||||
remove: t('Borrar'),
|
||||
'placeholder-textarea': t('Añadir un comentario'),
|
||||
'add-button-reply': t('Añadir una respuesta'),
|
||||
'add-button': t('Añadir comentario'),
|
||||
'you-need-to-login': t('Necesitas iniciar sesión para'),
|
||||
'add comments': t('añadir comentarios'),
|
||||
'like comments': t('puntuar comentarios'),
|
||||
'rate comments': t('puntuar comentarios'),
|
||||
'add replies': t('responder'),
|
||||
'load-more': t('Más comentarios')
|
||||
});
|
||||
|
||||
/* This in client side */
|
||||
Comments.ui.config({
|
||||
limit: 20, // default 10
|
||||
loadMoreCount: 20, // default 20
|
||||
generateAvatar: function genAvatar(user, isAnonymous) {
|
||||
if (isAnonymous) {
|
||||
return i18n.t('Anónimo');
|
||||
}
|
||||
return user.profile && user.profile.name && user.profile.name.first ? user.profile.name.first : null;
|
||||
},
|
||||
template: 'bootstrap', // default 'semantic-ui'
|
||||
// default 'http://s3.amazonaws.com/37assets/svn/765-default-avatar.png'
|
||||
defaultAvatar: '/default-avatar.png',
|
||||
markdown: false
|
||||
});
|
||||
});
|
||||
29
imports/startup/client/comments.scss
Normal file
29
imports/startup/client/comments.scss
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
.comments-section {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.comments-box {
|
||||
max-width: inherit;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
p.comment-content {
|
||||
/* white-space: pre-line; */
|
||||
}
|
||||
|
||||
/* remove comment btn danger style */
|
||||
|
||||
div.media-body.comment> div> div> div.btn.btn-danger.remove-action {
|
||||
background-color: white;
|
||||
border: 1px solid rgb(204, 204, 204);
|
||||
color: rgb(51, 51, 51);
|
||||
}
|
||||
|
||||
/* text-area height */
|
||||
.form-control .create-comment {
|
||||
height: 9em;
|
||||
}
|
||||
|
||||
.img-avatar {
|
||||
margin-right: 5px;
|
||||
}
|
||||
16
imports/startup/common/comments.js
Normal file
16
imports/startup/common/comments.js
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
/* global Comments */
|
||||
|
||||
// Client and Server
|
||||
Comments.config({
|
||||
rating: 'likes-and-dislikes',
|
||||
allowAnonymous: () => true,
|
||||
anonymousSalt: 'klasddl3lala0l3lasdlas0ol3lasdlao3lasdoaslaldal3lasdclasdlal3lasdladlaq',
|
||||
publishUserFields: {
|
||||
profile: 1
|
||||
},
|
||||
generateUsername: function genUser(user) {
|
||||
console.log(JSON.stringify(user));
|
||||
// FIXME
|
||||
return user.profile && user.profile.name && user.profile.name.first ? user.profile.name.first : '';
|
||||
}
|
||||
});
|
||||
|
|
@ -54,6 +54,9 @@ export function localize() {
|
|||
return { location: { latitude: 40.4146500, longitude: -3.7004000 } };
|
||||
}
|
||||
|
||||
export const gmapKey = process.env.GMAPS_KEY || Meteor.settings.gmaps.key;
|
||||
export const gmapServerKey = Meteor.settings.gmaps.serverKey;
|
||||
|
||||
Meteor.methods({
|
||||
geo: localize,
|
||||
getMapKey() {
|
||||
|
|
@ -61,6 +64,6 @@ Meteor.methods({
|
|||
// https://developers.google.com/maps/documentation/javascript/get-api-key
|
||||
// https://console.developers.google.com/
|
||||
// export GMAPS_KEY=SomeGMapsKey
|
||||
return process.env.GMAPS_KEY || Meteor.settings.gmaps.key;
|
||||
return gmapKey;
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -6,3 +6,4 @@ import './email';
|
|||
import './IPGeocoder';
|
||||
import './migrations';
|
||||
import './notificationsObserver';
|
||||
import '../common/comments';
|
||||
|
|
|
|||
|
|
@ -6,31 +6,22 @@ import React, { Fragment } from 'react';
|
|||
import PropTypes from 'prop-types';
|
||||
import { withTracker } from 'meteor/react-meteor-data';
|
||||
import { translate } from 'react-i18next';
|
||||
import { Col, Row } from 'react-bootstrap';
|
||||
import { Meteor } from 'meteor/meteor';
|
||||
import { Map, CircleMarker, Circle } from 'react-leaflet';
|
||||
import { Map, Circle } from 'react-leaflet';
|
||||
import moment from 'moment-timezone';
|
||||
import Blaze from 'meteor/gadicc:blaze-react-component';
|
||||
import DefMapLayers from '/imports/ui/components/Maps/DefMapLayers';
|
||||
import moment from 'moment';
|
||||
import FiresCollection from '/imports/api/Fires/Fires';
|
||||
import '/imports/startup/client/comments';
|
||||
|
||||
import './Fires.scss';
|
||||
|
||||
class Fire extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
};
|
||||
}
|
||||
|
||||
/* componentDidUpdate() {
|
||||
* const map = this.firemap.leafletElement;
|
||||
* map.invalidateSize();
|
||||
* } */
|
||||
|
||||
handleLeafletLoad(map) {
|
||||
console.log(map);
|
||||
if (map) {
|
||||
// map.leafletELement.invalidateSize();
|
||||
// map.invalidateSize();
|
||||
}
|
||||
// console.log(moment.tz.guess());
|
||||
}
|
||||
|
||||
render() {
|
||||
|
|
@ -40,50 +31,52 @@ class Fire extends React.Component {
|
|||
{!loading &&
|
||||
<Fragment>
|
||||
<h4 className="page-header">
|
||||
{t('Información sobre fuego detectado el día {{when}}', { when: moment(fire.when).format('LLLL') })}
|
||||
{fire.address ?
|
||||
t('Información adicional sobre fuego detectado en {{where}} el {{when}}', { where: fire.address, when: moment(fire.when).tz(moment.tz.guess()).format('LLLL (z)') }) :
|
||||
t('Información adicional sobre fuego detectado el {{when}}', { when: moment.utc(fire.when).format('LLLL') })}
|
||||
</h4>
|
||||
<Row>
|
||||
<Col xs={12} sm={6} md={6} lg={6} >
|
||||
{(fire.type === 'modis' || fire.type === 'virrs') &&
|
||||
<p>{t('Detectado por satélites de la NASA')}
|
||||
</p>
|
||||
}
|
||||
<h5>Comentarios</h5>
|
||||
<p>{t('Añade un comentario si tienes información adicional sobre este fuego (por ejemplo, si está aún activo cómo acceder a él, o si conoces el motivo por el que comenzó el fuego, o si quieres denunciar algún tipo de ilegalidad relacionada con el fuego)')}
|
||||
</p>
|
||||
</Col>
|
||||
<Col xs={12} sm={6} md={6} lg={6} >
|
||||
<Map
|
||||
ref={(map) => {
|
||||
this.fireMap = map;
|
||||
this.handleLeafletLoad(map);
|
||||
}}
|
||||
animate
|
||||
sleep={false}
|
||||
center={[fire.lat, fire.lon]}
|
||||
zoom={8}
|
||||
>
|
||||
<Fragment>
|
||||
<CircleMarker
|
||||
center={[fire.lat, fire.lon]}
|
||||
color="red"
|
||||
stroke={false}
|
||||
fillOpacity="1"
|
||||
fill
|
||||
radius={3}
|
||||
/>
|
||||
<Circle
|
||||
center={[fire.lat, fire.lon]}
|
||||
color="red"
|
||||
fillColor="red"
|
||||
fillOpacity={0.1}
|
||||
radius={fire.scan * 1000}
|
||||
/>
|
||||
</Fragment>
|
||||
<DefMapLayers />
|
||||
</Map>
|
||||
</Col>
|
||||
</Row>
|
||||
|
||||
<Map
|
||||
ref={(map) => {
|
||||
this.fireMap = map;
|
||||
}}
|
||||
animate
|
||||
sleep={false}
|
||||
center={[fire.lat, fire.lon]}
|
||||
className="fire-leaflet-container"
|
||||
zoom={8}
|
||||
>
|
||||
<Fragment>
|
||||
<Circle
|
||||
center={[fire.lat, fire.lon]}
|
||||
color="red"
|
||||
fillColor="red"
|
||||
fillOpacity={0.1}
|
||||
radius={fire.scan * 1000}
|
||||
/>
|
||||
</Fragment>
|
||||
<DefMapLayers />
|
||||
</Map>
|
||||
<p>{t('Coordenadas:')} {fire.lat}, {fire.lon}</p>
|
||||
{(fire.type === 'modis' || fire.type === 'virrs') &&
|
||||
<p>{t('Fuego detectado por satélites de la NASA {{when}}', { when: moment(fire.when).fromNow() })}</p>
|
||||
}
|
||||
{/* TODO: marcar tipo de fuego, industria, etc */}
|
||||
<h4>{t('Comentarios')}</h4>
|
||||
<div className="comments-info">
|
||||
{t('Puedes añadir un comentario si tienes información adicional sobre este fuego.')}
|
||||
{' '}
|
||||
{t('Por ejemplo:')}
|
||||
<ul>
|
||||
<li>{t('si conoces esta zona y cómo acceder a el fuego (esto puede de ser de ayuda para apagarlo si sigue activo o para investigarlo en un futuro)')}</li>
|
||||
<li>{t('si conoces el motivo por el que comenzó el fuego')}</li>
|
||||
<li>{t('si quieres denunciar algún tipo de ilegalidad, incluso anónimamente')}</li>
|
||||
<li>{t('etc')}</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div className="comments-section">
|
||||
<Blaze template="commentsBox" id={`fire-${fire._id}`} />
|
||||
</div>
|
||||
</Fragment>
|
||||
}
|
||||
</div>
|
||||
|
|
|
|||
29
imports/ui/pages/Fires/Fires.scss
Normal file
29
imports/ui/pages/Fires/Fires.scss
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
.fire-leaflet-container {
|
||||
min-height: 30vh;
|
||||
min-width: 40vw;
|
||||
width: 50%;
|
||||
margin: 0 0 10px 10px !important;
|
||||
display: flex;
|
||||
float: right !important;
|
||||
}
|
||||
|
||||
.ViewFire > h4.page-header {
|
||||
line-height: 1.5em;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.leaflet-container {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.comments-info {
|
||||
font-size: 14px;
|
||||
color: #818182;
|
||||
/* display: inline-flex; */
|
||||
/* background-color: #fefefe;
|
||||
border-color: #fdfdfe;
|
||||
padding: 10px;
|
||||
border-radius: 3px; */
|
||||
}
|
||||
|
|
@ -36,3 +36,8 @@
|
|||
.leaflet-control-layers-toggle {
|
||||
background-image: url(/images/layers.png);
|
||||
}
|
||||
|
||||
|
||||
.glyphicon .glyphicon-thumbs-up {
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue