From d98ad66aa91a1740ca897762a1f57aef6b4c33c1 Mon Sep 17 00:00:00 2001 From: GabrielTrettel Date: Sun, 13 Jun 2021 20:58:36 -0300 Subject: [PATCH] Fixing invariant hook errors while rendering markers in OSM --- src/app/components/MapMarker.js | 81 ++------------- src/app/components/MapMarkerList.js | 36 +++---- src/app/components/MapModal.js | 29 ++++-- src/app/components/SelfClosingModal.js | 5 +- src/app/components/map/LeafLetMap.js | 12 +-- src/app/components/map/OpenStreetMap.js | 62 +++++++++--- src/app/hooks/selectFromDB.js | 125 ++++++++++++------------ src/app/screens/MapFeedScreen.js | 15 ++- 8 files changed, 171 insertions(+), 194 deletions(-) diff --git a/src/app/components/MapMarker.js b/src/app/components/MapMarker.js index 8fddbd0..ac41b77 100644 --- a/src/app/components/MapMarker.js +++ b/src/app/components/MapMarker.js @@ -1,76 +1,15 @@ -import React, { useState } from "react"; -import { View, StyleSheet, Image } from "react-native"; -import MapView from "react-native-maps"; -import colors from "../config/colors"; -import { dimensions } from "../config/dimensions"; +import React, { useState, useEffect } from "react"; +import { View } from "react-native"; import MapModal from "./MapModal"; -const imageScale = 0.025; -const markerSizeWidth = Math.floor(1667 * imageScale); -const markerSizeHeigth = Math.floor(2501 * imageScale); - -export default function MapMarker(props) { - const [isModalVisible, setIsModalVisible] = useState(false); - +export default function MapMarker(markerListener, setMarkerListener, markers) { return ( - setIsModalVisible(!isModalVisible)} - > - - - - - - + + + ); } - -const styles = StyleSheet.create({ - title: { - fontWeight: "bold", - fontSize: dimensions.text.secondary, - alignSelf: "center", - paddingBottom: dimensions.spacing.minimal_padding, - }, - description: { - fontSize: dimensions.text.default, - }, - arrow: { - alignSelf: "center", - borderTopWidth: 15, - borderRightWidth: 10, - borderBottomWidth: 0, - borderLeftWidth: 10, - borderTopColor: colors.lightGray, - borderRightColor: "transparent", - borderBottomColor: "transparent", - borderLeftColor: "transparent", - paddingBottom: 5, - }, - - container: { - flexDirection: "column", - alignSelf: "center", - backgroundColor: colors.lightestGray, - borderColor: colors.lightGray, - borderRadius: 6, - borderWidth: 4, - borderTopWidth: 2, - padding: dimensions.spacing.minimal_padding, - width: 200, - }, - markerPoint: { - alignSelf: "center", - height: markerSizeHeigth, - width: markerSizeWidth, - }, -}); diff --git a/src/app/components/MapMarkerList.js b/src/app/components/MapMarkerList.js index 75c2d46..21a0cc0 100644 --- a/src/app/components/MapMarkerList.js +++ b/src/app/components/MapMarkerList.js @@ -1,6 +1,4 @@ -import React from "react"; import useMarkers from "../hooks/selectFromDB"; -import MapMarker from "../components/MapMarker"; function isRequestedValue( item, @@ -28,25 +26,21 @@ function MapMarkerList({ renderOfficialPluviometer = true, }) { const markers = useMarkers(reload); - console.log(markers.markers.size); - return ( - <> - {[...markers.markers] - .filter((item) => - isRequestedValue( - item, - renderRain, - renderFlood, - renderRiver, - renderPluviometer, - renderOfficialPluviometer - ) - ) - .map(({ ID, ...val }) => { - return ; - })} - - ); + + // FIXME: Resolve this later!!! + return markers.markers; + + // return [...markers.markers].filter(([k, item]) => { + // isRequestedValue( + // item, + // renderRain, + // renderFlood, + // renderRiver, + // renderPluviometer, + // renderOfficialPluviometer + // ) + // } + // ); } export { MapMarkerList }; diff --git a/src/app/components/MapModal.js b/src/app/components/MapModal.js index 7069095..c3a1c67 100644 --- a/src/app/components/MapModal.js +++ b/src/app/components/MapModal.js @@ -24,7 +24,7 @@ function notImplemented() { }); } -function topBar(props) { +function topBar(setMarkerToRender) { return ( props.setIsVisible(!props.isVisible)} + onPress={() => setMarkerToRender(null)} > - {topBar(props)} - {componentBody(props)} - {isPluviometer(props.name) ? moreInfo(props) : null} - {!isPluviometer(props.name) ? reviews(props) : null} + {topBar(setMarkerToRender)} + {componentBody(currentMarker)} + {isPluviometer(currentMarker.name) ? moreInfo(currentMarker) : null} + {!isPluviometer(currentMarker.name) ? reviews(currentMarker) : null} - ); + );} + else { + return null; + } } const styles = StyleSheet.create({ diff --git a/src/app/components/SelfClosingModal.js b/src/app/components/SelfClosingModal.js index 65ceacc..3819d98 100644 --- a/src/app/components/SelfClosingModal.js +++ b/src/app/components/SelfClosingModal.js @@ -8,15 +8,16 @@ import { import { screen_height, screen_width } from "../config/dimensions"; export default function SelfClosingModal(props) { + return ( props.setVisible(!props.visible)} + onPress={() => props.setMarkerToRender(null)} > diff --git a/src/app/components/map/LeafLetMap.js b/src/app/components/map/LeafLetMap.js index fa2dbe6..56e239e 100644 --- a/src/app/components/map/LeafLetMap.js +++ b/src/app/components/map/LeafLetMap.js @@ -56,12 +56,12 @@ function handleEvent(event) { return code_to_function[payload.code](payload); } -async function insertMarker(mapRef, ID, cords, icon) { - var iconSvg = icon; +async function insertMarker(mapRef, ID, coordinate, icon) { + var iconSvg = ` `; - if (typeof icon !== 'string' && !(icon instanceof String)) { - iconSvg = await loadLocalAsset(icon); - } + // if (typeof icon !== 'string' && !(icon instanceof String)) { + // iconSvg = await loadLocalAsset(icon); + // } mapRef.injectJavaScript(` var customIcon = L.divIcon({ @@ -73,7 +73,7 @@ async function insertMarker(mapRef, ID, cords, icon) { // Check if there is no other marker with same ID already in map if (!(${ID} in markers)) { // Creates marker object - markers[${ID}] = L.marker([${cords.lat}, ${cords.long}], {icon: customIcon, ID: ${ID}}); + markers[${ID}] = L.marker([${coordinate.latitude}, ${coordinate.longitude}], {icon: customIcon, ID: ${ID}}); // Add marker to map and bing callback event to its function markers[${ID}].addTo(map).on('click', onPopupClick); diff --git a/src/app/components/map/OpenStreetMap.js b/src/app/components/map/OpenStreetMap.js index 0ae06a6..2937eea 100644 --- a/src/app/components/map/OpenStreetMap.js +++ b/src/app/components/map/OpenStreetMap.js @@ -1,5 +1,5 @@ -import React, { useState } from "react"; -import { View } from "react-native"; +import React, { useState, useEffect } from "react"; +import { View, StyleSheet, Text } from "react-native"; import WebView from "react-native-webview"; import { loadHTMLFile, @@ -7,14 +7,20 @@ import { insertMarker, goToRegion, } from "./LeafLetMap"; +import MapModal from "../MapModal"; -function bindEventsToListeners(event, clickListener, markerListener, moveEndListener) { +function bindEventsToListeners( + event, + clickListener, + setMarkerListener, + moveEndListener +) { switch (event.object) { case "click": clickListener && clickListener(event.cords); break; case "marker": - markerListener && markerListener(event.id); + setMarkerListener(event.id); break; case "moveend": moveEndListener && moveEndListener(event.id); @@ -24,25 +30,29 @@ function bindEventsToListeners(event, clickListener, markerListener, moveEndList } } +function notEmpy(lista) { + return lista && lista.size > 0; +} + export default function OpenStreetMap({ markersList, animateToPosition, clickListener, - markerListener, moveEndListener, }) { const [mapRef, setMapRef] = useState(null); const [webviewContent, setWebviewContent] = useState(null); + const [markerListener, setMarkerListener] = useState(null); if (mapRef != null) { animateToPosition != null && goToRegion(mapRef, animateToPosition); - - markersList != null && - markersList.length > 0 && - markersList.map(({ ID, cords, icon }) => - insertMarker(mapRef, ID, cords, icon) - ); } + markersList && + mapRef && + notEmpy(markersList) && + markersList.forEach((val, key) => { + insertMarker(mapRef, val.ID, val.coordinate, val.icon); + }); loadHTMLFile() .then((html) => setWebviewContent(html)) @@ -58,13 +68,39 @@ export default function OpenStreetMap({ bindEventsToListeners( handleEvent(event), clickListener, - markerListener, - moveEndListener, + setMarkerListener, + moveEndListener ); }} javaScriptEnabled={true} source={{ html: webviewContent }} /> + + + + + + {markerListener} + ); } + +const styles = StyleSheet.create({ + callback: { + position: "absolute", + top: 30, + alignSelf: "center", + alignItems: "center", + backgroundColor: "gray", + width: "80%", + padding: 10, + }, + txt: { + color: "white", + }, +}); diff --git a/src/app/hooks/selectFromDB.js b/src/app/hooks/selectFromDB.js index d456137..a51eb8f 100644 --- a/src/app/hooks/selectFromDB.js +++ b/src/app/hooks/selectFromDB.js @@ -194,21 +194,22 @@ function genericSelect(queriesToParsersMapper, dispatch, isFocused) { }, [isFocused]); } -const initialState = { markers: new Set() }; +const initialState = { markers: new Map() }; function reducer(state = initialState, action) { // NOTE: removing old pluviometer value to new data can be displayed - state.markers.forEach((m) => { + state.markers.forEach((m, key) => { if (m.name == "pluviometer" || m.name == "officialPluviometer") { - state.markers.delete(m); + state.markers.delete(key); } }); action.increment.map((val) => { - state.markers.add(val); + if (!state.markers.has(val.ID)) { + state.markers.set(val.ID, val); + } }); - console.log(state.markers); return { markers: state.markers, }; @@ -278,71 +279,71 @@ function useMarkers(isFocused) { const location = context.currentCoordinates; const addr = context.currentLocation; - const parseOfficialPluviometers = () => { - return buildRandonData(location, addr); - }; - - const parsePluviometer = (db_result) => { - // if (db_result.rows.length <= 0) return []; - const points = []; - - const info = { - pictures: "[]", - description: "", - date: "", - }; - - for (let i = 0; i < db_result.rows.length; ++i) { - var row = db_result.rows.item(i); - - description = row["Description"] ? "\n\n" + row["Description"] : ""; - info.date = row["Date"]; - info.description = - row["Precipitation"] + "mm" + ", " + row["Date"] + description; - info.pictures = row["Images"]; - - points.push([row["Date"].slice(0, 5), parseInt(row["Precipitation"])]); - } - - latestPoints = points.sort(compare).slice(-7); - if (latestPoints.length == 0) { - var labels = []; - var values = []; - } - var labels = latestPoints.map((i) => { - return i[0]; - }); - var values = latestPoints.map((i) => { - return i[1]; - }); - - const result = { - image: custom_assets_pin.pluviometer, - logo: custom_assets.pluviometer, - ID: ++ID, - name: "pluviometer", - title: "Pluviometro 1", - coordinate: location, - address: addr, - data: { - labels: labels, - values: values, - }, - ...info, - }; - - return [result, ...parseOfficialPluviometers()]; - }; + // const parseOfficialPluviometers = () => { + // return buildRandonData(location, addr); + // }; + + // const parsePluviometer = (db_result) => { + // // if (db_result.rows.length <= 0) return []; + // const points = []; + + // const info = { + // pictures: "[]", + // description: "", + // date: "", + // }; + + // for (let i = 0; i < db_result.rows.length; ++i) { + // var row = db_result.rows.item(i); + + // description = row["Description"] ? "\n\n" + row["Description"] : ""; + // info.date = row["Date"]; + // info.description = + // row["Precipitation"] + "mm" + ", " + row["Date"] + description; + // info.pictures = row["Images"]; + + // points.push([row["Date"].slice(0, 5), parseInt(row["Precipitation"])]); + // } + + // latestPoints = points.sort(compare).slice(-7); + // if (latestPoints.length == 0) { + // var labels = []; + // var values = []; + // } + // var labels = latestPoints.map((i) => { + // return i[0]; + // }); + // var values = latestPoints.map((i) => { + // return i[1]; + // }); + + // const result = { + // image: custom_assets_pin.pluviometer, + // logo: custom_assets.pluviometer, + // ID: ++ID, + // name: "pluviometer", + // title: "Pluviometro 1", + // coordinate: location, + // address: addr, + // data: { + // labels: labels, + // values: values, + // }, + // ...info, + // }; + + // return [result, ...parseOfficialPluviometers()]; + // }; const queriesToParsersMapper = [ ["SELECT * FROM FloodZones;", parseFloodZones, false], ["SELECT * FROM RiverLevel;", parseRiverLevel, false], ["SELECT * FROM RainLevel;", parseRainLevel, false], - ["SELECT * FROM PluviometerData;", parsePluviometer, true], + // ["SELECT * FROM PluviometerData;", parsePluviometer, true], ]; genericSelect(queriesToParsersMapper, dispatch, isFocused); - + return state; } diff --git a/src/app/screens/MapFeedScreen.js b/src/app/screens/MapFeedScreen.js index 42359ae..cd31632 100644 --- a/src/app/screens/MapFeedScreen.js +++ b/src/app/screens/MapFeedScreen.js @@ -1,15 +1,17 @@ import React, { useState, useEffect, useContext } from "react"; -import { StyleSheet, Text, TouchableOpacity, View } from "react-native"; +import { StyleSheet, Text, View } from "react-native"; import OpenStreetMap from "../components/map/OpenStreetMap"; import { CurrentLocationContext } from "../context/CurrentLocationContext"; +import attachFocusToQuery from "../hooks/useFocus"; +import {MapMarkerList} from "../components/MapMarkerList"; export default function MapFeedScreen() { const [position, setPosition] = useState(null); - const [clickListener, setClickListener] = useState(""); - const [markerListener, setMarkerListener] = useState(""); const context = useContext(CurrentLocationContext); const location = context.currentCoordinates; + const focusChanged = attachFocusToQuery(); + useEffect(() => { setPosition({ @@ -23,15 +25,10 @@ export default function MapFeedScreen() { return ( - - {JSON.stringify(clickListener)} - {JSON.stringify(markerListener)} - ); }