import { useState, useRef, useEffect } from "react"; import { useWindowDimensions, Alert, StyleSheet } from "react-native"; import { SafeAreaProvider, SafeAreaView } from "react-native-safe-area-context"; import WebView, { WebViewMessageEvent } from "react-native-webview"; import { useAssets } from "expo-asset"; import * as Location from "expo-location"; import { useNavigation, router } from "expo-router"; export default function () { const [assets] = useAssets([require("../assets/index.html")]); const [htmlString, setHtmlString] = useState(); const dimensions = useWindowDimensions(); const webViewRef = useRef(); const navigation = useNavigation(); const messageHandler = (event: WebViewMessageEvent) => { if (typeof event.nativeEvent.data == "string") { const message = event.nativeEvent.data; if (message === "new pin start") { Alert.alert( "New Pin", `Please select location for new pin then press "OK"`, [ { text: "OK", onPress: () => { // makes injectable javascript string const str = `window.placePin(); true()`; // passes string to webview - there it is handled by OpenLayers to change the current location webViewRef.current?.injectJavaScript(str); }, }, ] ); } else if (message.startsWith(`create@`)) { const coords = message.slice(7).split(","); router.push({ pathname: "./store/new/[coords]", params: { coords: `${coords[0]}+${coords[1]}`, }, }); } else if (message.startsWith(`open@`)) { const coords = message.slice(5).split(","); router.push({ pathname: "./store/[coords]", params: { coords: `${coords[0]}+${coords[1]}`, }, }); } else if (message.startsWith(`search@`)) { const chunks = message.slice(7).split(":"); const coords = chunks[0].split(","); router.push({ pathname: "./search/[slug]", params: { slug: `${coords[0]}+${coords[1]}+${chunks[1]}`, }, }); } } }; const getLocation = async () => { const { status } = await Location.requestForegroundPermissionsAsync(); if (status !== "granted") return; const location = await Location.getCurrentPositionAsync({ distanceInterval: 0, // for IOS accuracy: Location.Accuracy.High, timeInterval: 3000, // for Android }); // makes injectable javascript string const str = `window.passLocation(${location.coords.longitude}, ${location.coords.latitude}); true()`; // passes string to webview - there it is handled by OpenLayers to change the current location webViewRef.current?.injectJavaScript(str); }; // refresh on navigating back to this page useEffect(() => { // remove header navigation.setOptions({ headerShown: false }); const focusHandler = navigation.addListener("focus", () => { webViewRef.current?.reload(); getLocation(); }); return focusHandler; }, [navigation]); // loads assets useEffect(() => { if (assets) { fetch(assets[0].localUri || "") .then((res) => res.text()) .then((html) => setHtmlString(html)); } }, [assets]); // exits if no map passed in if (!htmlString) { return <>; } const styles = StyleSheet.create({ container: { flex: 1, alignItems: "center", justifyContent: "center", }, }); return ( (webViewRef.current = currentRef)} injectedJavascript="" source={{ html: htmlString, }} javaScriptEnabled style={{ width: dimensions.width, height: dimensions.height, }} scrollEnabled={false} overScrollMode="never" showsVerticalScrollIndicator={false} showsHorizontalScrollIndicator={false} scalesPageToFit={false} containerStyle={{ flex: 1, }} onMessage={messageHandler} webviewDebuggingEnabled={true} /> ); }