139 lines
4.3 KiB
TypeScript
139 lines
4.3 KiB
TypeScript
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<string>();
|
|
const dimensions = useWindowDimensions();
|
|
const webViewRef = useRef<WebView | null>();
|
|
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 (
|
|
<SafeAreaProvider>
|
|
<SafeAreaView style={styles.container}>
|
|
<WebView
|
|
ref={(currentRef) => (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}
|
|
/>
|
|
</SafeAreaView>
|
|
</SafeAreaProvider>
|
|
);
|
|
}
|