From efa024e1312ef0ece408f777879d1700951ac59e Mon Sep 17 00:00:00 2001 From: GabrielTrettel Date: Thu, 27 May 2021 20:20:25 -0300 Subject: [PATCH] Organizing communication responsibility layers between React and the leaflet webview --- src/app/components/map/LeafLetMap.js | 55 ++++++++++++++++ src/app/components/map/Map.html | 2 +- src/app/components/map/OpenStreetMap.js | 84 ++++++++++--------------- src/app/screens/MapFeedScreen.js | 9 ++- 4 files changed, 95 insertions(+), 55 deletions(-) create mode 100644 src/app/components/map/LeafLetMap.js diff --git a/src/app/components/map/LeafLetMap.js b/src/app/components/map/LeafLetMap.js new file mode 100644 index 0000000..9e78933 --- /dev/null +++ b/src/app/components/map/LeafLetMap.js @@ -0,0 +1,55 @@ +import { Asset } from "expo-asset"; +import * as FileSystem from "expo-file-system"; + +const HTML_FILE_PATH = require(`./Map.html`); + +const loadHTMLFile = async () => { + try { + const [{ localUri }] = await Asset.loadAsync(HTML_FILE_PATH); + const fileString = await FileSystem.readAsStringAsync(localUri); + + return fileString; + } catch (error) { + console.warn(error); + console.warn("Unable to resolve index file"); + } +}; + +function goToPosition(mapRef, lat, long) { + mapRef.injectJavaScript(`map.setView([${lat}, ${long}], 13);`); +} + +const code_to_function = { + "1": clickCallback, + "2": markerCallback, +}; + +function clickCallback(payload) { + return { + object: "click", + cords: payload.content, + }; +} + +function markerCallback(payload) { + return { + object: "marker", + id: payload.content, + }; +} + +function parseInput(event) { + const payload = JSON.parse(event.nativeEvent.data); + return code_to_function[payload.code](payload); +} + +function insertMarker(mapRef, props) { + mapRef.injectJavaScript(` + if (!(${props.ID} in markers)) { + markers[${props.ID}] = L.marker([${props.cords.lat}, ${props.cords.long}], + {ID: ${props.ID}}); + markers[${props.ID}].addTo(map).on('click', onPopupClick); + } + `); +} +export { loadHTMLFile, parseInput, insertMarker, goToPosition }; diff --git a/src/app/components/map/Map.html b/src/app/components/map/Map.html index a2ce7a6..7f375b7 100644 --- a/src/app/components/map/Map.html +++ b/src/app/components/map/Map.html @@ -96,7 +96,7 @@ function onPopupClick(e) { var payload = { code: 2, - content: "marker selecionado " + this.options.ID, + content: this.options.ID, }; window.ReactNativeWebView.postMessage(JSON.stringify(payload)); } diff --git a/src/app/components/map/OpenStreetMap.js b/src/app/components/map/OpenStreetMap.js index 8c66fbe..6459345 100644 --- a/src/app/components/map/OpenStreetMap.js +++ b/src/app/components/map/OpenStreetMap.js @@ -1,62 +1,41 @@ import React, { useEffect, useState } from "react"; import { View } from "react-native"; import WebView from "react-native-webview"; -import { Asset } from "expo-asset"; -import * as FileSystem from "expo-file-system"; - -const HTML_FILE_PATH = require(`./Map.html`); - -const loadHTMLFile = async () => { - try { - const [{ localUri }] = await Asset.loadAsync(HTML_FILE_PATH); - const fileString = await FileSystem.readAsStringAsync(localUri); - - return fileString; - } catch (error) { - console.warn(error); - console.warn("Unable to resolve index file"); +import { + loadHTMLFile, + parseInput, + insertMarker, + goToPosition, +} from "./LeafLetMap"; + +function bindEventsToListeners(event, clickListener, markerListener) { + switch (event.object) { + case "click": + clickListener(event.cords); + break; + case "marker": + markerListener(event.id); + break; + default: + break; } -}; - -const code_to_function = { - "1": clickCallback, - "2": clickCallback, -}; - -function clickCallback(payload, props) { - console.log(payload.content); - props.clickListener(JSON.stringify(payload.content)); -} - -function parseInput(event, props) { - const payload = JSON.parse(event); - code_to_function[payload.code](payload, props); -} - -function insertMarker(mapRef, props) { - mapRef.injectJavaScript(` - markers[${props.ID}] = L.marker([${props.cords.lat}, ${props.cords.long}], - {ID: ${props.ID}}); - markers[${props.ID}].addTo(map).on('click', onPopupClick); - `); } -function goToPosition(mapRef, lat, long) { - mapRef.injectJavaScript(`map.setView([${lat}, ${long}], 13);`); -} - -export default function OpenStreetMap(props) { +export default function OpenStreetMap({ + markersList, + animateToPosition, + clickListener, + markerListener, +}) { const [mapRef, setMapRef] = useState(null); - const [finishedLoad, setFinishedLoad] = useState(false); const [webviewContent, setWebviewContent] = useState(null); if (mapRef != null) { - props.animateToPosition != null && - goToPosition(mapRef, ...props.animateToPosition); + animateToPosition != null && goToPosition(mapRef, ...animateToPosition); - props.markersList != null && - props.markersList.length > 0 && - props.markersList.map((m) => insertMarker(mapRef, m)); + markersList != null && + markersList.length > 0 && + markersList.map((m) => insertMarker(mapRef, m)); } loadHTMLFile() @@ -70,13 +49,14 @@ export default function OpenStreetMap(props) { setMapRef(webViewRef); }} onMessage={(event) => { - parseInput(event.nativeEvent.data, props); + bindEventsToListeners( + parseInput(event), + clickListener, + markerListener + ); }} javaScriptEnabled={true} source={{ html: webviewContent }} - onLoad={() => { - setFinishedLoad(true); - }} /> ); diff --git a/src/app/screens/MapFeedScreen.js b/src/app/screens/MapFeedScreen.js index 7108c3c..329a99f 100644 --- a/src/app/screens/MapFeedScreen.js +++ b/src/app/screens/MapFeedScreen.js @@ -5,6 +5,9 @@ import OpenStreetMap from "../components/map/OpenStreetMap"; export default function MapFeedScreen() { const [position, setPosition] = useState(null); const [clickListener, setClickListener] = useState(""); + const [markerListener, setMarkerListener] = useState(""); + + console.log(clickListener); const markers = [ { @@ -28,8 +31,9 @@ export default function MapFeedScreen() { @@ -53,7 +57,8 @@ export default function MapFeedScreen() { - {clickListener} + {JSON.stringify(clickListener)} + {JSON.stringify(markerListener)} );