|
@@ -8,8 +8,8 @@
|
|
import { FontAwesome } from "@expo/vector-icons";
|
|
import { FontAwesome } from "@expo/vector-icons";
|
|
import * as ImagePicker from 'expo-image-picker';
|
|
import * as ImagePicker from 'expo-image-picker';
|
|
import { ImageInfo } from "expo-image-picker/build/ImagePicker.types";
|
|
import { ImageInfo } from "expo-image-picker/build/ImagePicker.types";
|
|
-import React, { memo, useEffect, useState } from "react";
|
|
|
|
-import { ActivityIndicator, Dimensions, Image, Platform, SafeAreaView, Text, TextInput, TouchableOpacity, View, ImageSourcePropType} from 'react-native';
|
|
|
|
|
|
+import React, { memo, useEffect, useState, useRef } from "react";
|
|
|
|
+import { ActivityIndicator, Dimensions, Image, Platform, SafeAreaView, Text, TextInput, TouchableOpacity, View, ImageSourcePropType, Share, } from 'react-native';
|
|
import { ScrollView } from "react-native-gesture-handler";
|
|
import { ScrollView } from "react-native-gesture-handler";
|
|
import Modal from 'react-native-modal';
|
|
import Modal from 'react-native-modal';
|
|
import { checkMultiple, PERMISSIONS, RESULTS } from "react-native-permissions";
|
|
import { checkMultiple, PERMISSIONS, RESULTS } from "react-native-permissions";
|
|
@@ -19,10 +19,11 @@ import { colors, getMediaPermissions, lmTypes } from "../../../utils/GlobalUtils
|
|
import { IconButton, SecondaryButton } from "../../Buttons";
|
|
import { IconButton, SecondaryButton } from "../../Buttons";
|
|
import { PhotoPicker } from "../../PhotoPicker";
|
|
import { PhotoPicker } from "../../PhotoPicker";
|
|
import TouchOpaq from "./LandmarkDetailsPanel/TouchOpaq";
|
|
import TouchOpaq from "./LandmarkDetailsPanel/TouchOpaq";
|
|
-import {Svg , Rect, Image as ImageSVG} from 'react-native-svg'
|
|
|
|
|
|
+import { Svg, Rect, Image as ImageSVG, Circle } from 'react-native-svg'
|
|
import ReactDOMServer from 'react-dom/server'; //npm i --save-dev @types/react-dom
|
|
import ReactDOMServer from 'react-dom/server'; //npm i --save-dev @types/react-dom
|
|
|
|
|
|
import IndoorFloor from "../IndoorFloor";
|
|
import IndoorFloor from "../IndoorFloor";
|
|
|
|
+import ViewShot from "react-native-view-shot";
|
|
|
|
|
|
/**
|
|
/**
|
|
* Props for the {@link AddLandmarkPanel} component.
|
|
* Props for the {@link AddLandmarkPanel} component.
|
|
@@ -31,7 +32,7 @@ export interface AddLandmarkProps {
|
|
/**
|
|
/**
|
|
* Whether the landmark is being added at the current users location
|
|
* Whether the landmark is being added at the current users location
|
|
*/
|
|
*/
|
|
- landmarkAtCurrentLocation?: boolean;
|
|
|
|
|
|
+ landmarkAtCurrentLocation?: boolean;
|
|
/**
|
|
/**
|
|
* The {@link landmark} object to be added.
|
|
* The {@link landmark} object to be added.
|
|
*/
|
|
*/
|
|
@@ -52,18 +53,20 @@ export interface AddLandmarkProps {
|
|
* @component
|
|
* @component
|
|
* @category Map
|
|
* @category Map
|
|
*/
|
|
*/
|
|
-const AddLandmarkPanel: React.FC<AddLandmarkProps> = ({newLandmark, setNewLandmark, setVisible, visible}) => {
|
|
|
|
|
|
+const AddLandmarkPanel: React.FC<AddLandmarkProps> = ({ newLandmark, setNewLandmark, setVisible, visible }) => {
|
|
const [photos, setPhotos] = useState<LMPhoto[]>([])
|
|
const [photos, setPhotos] = useState<LMPhoto[]>([])
|
|
const [photoSourceMenuOpened, togglePhotoSourceMenu] = useState<boolean>(false)
|
|
const [photoSourceMenuOpened, togglePhotoSourceMenu] = useState<boolean>(false)
|
|
|
|
|
|
|
|
+ const capture: any = useRef();
|
|
|
|
+
|
|
const imgWidth = 346
|
|
const imgWidth = 346
|
|
const imgHeight = 443
|
|
const imgHeight = 443
|
|
- const imageDim = 5
|
|
|
|
|
|
+ const imageDim = 27
|
|
|
|
|
|
- const {
|
|
|
|
- addLandmarkAsync,
|
|
|
|
- resetAddLm,
|
|
|
|
- addLandmarkStatus,
|
|
|
|
|
|
+ const {
|
|
|
|
+ addLandmarkAsync,
|
|
|
|
+ resetAddLm,
|
|
|
|
+ addLandmarkStatus,
|
|
} = useLandmarks();
|
|
} = useLandmarks();
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
@@ -86,78 +89,91 @@ const AddLandmarkPanel: React.FC<AddLandmarkProps> = ({newLandmark, setNewLandma
|
|
|
|
|
|
|
|
|
|
|
|
|
|
-
|
|
|
|
const renderIndoorLandmarkPin = (landmark: Landmark) => {
|
|
const renderIndoorLandmarkPin = (landmark: Landmark) => {
|
|
return (
|
|
return (
|
|
<ImageSVG
|
|
<ImageSVG
|
|
- x={landmark.longitude * imgWidth}
|
|
|
|
- y={landmark.latitude * imgHeight}
|
|
|
|
- width={imageDim}
|
|
|
|
- height={imageDim}
|
|
|
|
- href={lmTypes[landmark.landmark_type]['image'] as ImageSourcePropType} />
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- // const renderLandmarkSvg = (floor: number) => {
|
|
|
|
- // return (
|
|
|
|
- // <Svg height={imgHeight} width={imgWidth}>
|
|
|
|
- // <IndoorFloor floorNum={floor} />
|
|
|
|
- // {renderIndoorLandmarkPin(newLandmark)}
|
|
|
|
- // </Svg>
|
|
|
|
- // )
|
|
|
|
|
|
+ x={landmark.longitude * imgWidth}
|
|
|
|
+ y={landmark.latitude * imgHeight}
|
|
|
|
+ width={imageDim}
|
|
|
|
+ height={imageDim}
|
|
|
|
+ href={lmTypes[landmark.landmark_type]['image'] as ImageSourcePropType} />
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ const renderLandmarkSvg = (floor: number) => {
|
|
|
|
+ return (
|
|
|
|
+ <Svg height="100%" width="100%">
|
|
|
|
+ {renderIndoorLandmarkPin(newLandmark)}
|
|
|
|
+ <IndoorFloor floorNum={floor} />
|
|
|
|
+ </Svg>
|
|
|
|
+ )
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // function renderLandmarkSvg(floor) {
|
|
|
|
+ // return (
|
|
|
|
+ // // <svg height="100%" width="100%" style="background-color:#33AAFF" preserveAspectRatio="xMidYMid meet"><rect x="50" y="50" width="50" height="50" fill="#3399ff" stroke-width="3" stroke="rgb(0,0,0)"></rect></svg>
|
|
|
|
+ // // style={{backgroundColor:'#33AAFF'}}
|
|
|
|
+ // <Svg height="100%" width="100%" style={{ backgroundColor: '#33AAFF' }}>
|
|
|
|
+ // <Rect
|
|
|
|
+ // x="50"
|
|
|
|
+ // y="50"
|
|
|
|
+ // width="50"
|
|
|
|
+ // height="50"
|
|
|
|
+ // fill="#3399ff"
|
|
|
|
+ // strokeWidth="3"
|
|
|
|
+ // stroke="rgb(0,0,0)"
|
|
|
|
+ // />
|
|
|
|
+ // <Circle cx="200" cy="75" r="20" fill="pink" />
|
|
|
|
+ // </Svg>
|
|
|
|
+ // )
|
|
// }
|
|
// }
|
|
|
|
|
|
|
|
+ // const childToWeb = (child: any) => {
|
|
|
|
+ // const { type, props } = child;
|
|
|
|
+ // const name = type && type.displayName;
|
|
|
|
+ // const webName = name && name[0].toLowerCase() + name.slice(1);
|
|
|
|
+ // const Tag = webName ? webName : type;
|
|
|
|
+ // return <Tag {...props}>{toWeb(props.children)}</Tag>;
|
|
|
|
+ // };
|
|
|
|
|
|
|
|
+ // const toWeb = (children: any) => React.Children.map(children, childToWeb);
|
|
|
|
|
|
- const childToWeb = (child: any) => {
|
|
|
|
- const { type, props } = child;
|
|
|
|
- const name = type && type.displayName;
|
|
|
|
- const webName = name && name[0].toLowerCase() + name.slice(1);
|
|
|
|
- const Tag = webName ? webName : type;
|
|
|
|
- return <Tag {...props}>{toWeb(props.children)}</Tag>;
|
|
|
|
- };
|
|
|
|
-
|
|
|
|
- const toWeb = (children: any) => React.Children.map(children, childToWeb);
|
|
|
|
-
|
|
|
|
- function renderLandmarkSvg(floor) {
|
|
|
|
- return (
|
|
|
|
- // <svg height="100%" width="100%" style="background-color:#33AAFF" preserveAspectRatio="xMidYMid meet"><rect x="50" y="50" width="50" height="50" fill="#3399ff" stroke-width="3" stroke="rgb(0,0,0)"></rect></svg>
|
|
|
|
- // style={{backgroundColor:'#33AAFF'}}
|
|
|
|
- <Svg height="100%" width="100%" style={{ backgroundColor: '#33AAFF' }}>
|
|
|
|
- <Rect
|
|
|
|
- x="50"
|
|
|
|
- y="50"
|
|
|
|
- width="50"
|
|
|
|
- height="50"
|
|
|
|
- fill="#3399ff"
|
|
|
|
- strokeWidth="3"
|
|
|
|
- stroke="rgb(0,0,0)"
|
|
|
|
- />
|
|
|
|
- </Svg>
|
|
|
|
- )
|
|
|
|
- }
|
|
|
|
|
|
|
|
- function serialize() {
|
|
|
|
- const element = renderLandmarkSvg(newLandmark.floor);
|
|
|
|
- const webJsx = toWeb(element);
|
|
|
|
- const svgString = ReactDOMServer.renderToStaticMarkup(webJsx);
|
|
|
|
- console.log(svgString)
|
|
|
|
- return svgString
|
|
|
|
- }
|
|
|
|
|
|
+ // function serialize() {
|
|
|
|
+ // const element = renderLandmarkSvg(newLandmark.floor);
|
|
|
|
+ // const webJsx = toWeb(element);
|
|
|
|
+ // const svgString = ReactDOMServer.renderToStaticMarkup(webJsx);
|
|
|
|
+ // console.log(svgString)
|
|
|
|
+ // return svgString
|
|
|
|
+ // }
|
|
|
|
|
|
/**
|
|
/**
|
|
* Calls {@link addLandmarkAsync} from {@link useLandmarks} to initate the process of adding a landmark, then closes the modal.
|
|
* Calls {@link addLandmarkAsync} from {@link useLandmarks} to initate the process of adding a landmark, then closes the modal.
|
|
*/
|
|
*/
|
|
const submit = async () => {
|
|
const submit = async () => {
|
|
- // create svg content here, then pass it to addLandmarkAsync as the value of indoorLmLocImg
|
|
|
|
- if(typeof newLandmark.floor === 'number'){
|
|
|
|
- let rectangle = serialize()
|
|
|
|
- await addLandmarkAsync({landmarkValue: newLandmark, photos: photos, indoorLmLocImg: rectangle }); // pass it in here
|
|
|
|
|
|
+
|
|
|
|
+ if (typeof newLandmark.floor === 'number') {
|
|
|
|
+ // let imageURI = await capture.current.capture()
|
|
|
|
+ let imageURI = "string"
|
|
|
|
+ console.log("*AddLandmarkPanel* imageURI is " + imageURI)
|
|
|
|
+ await addLandmarkAsync({ landmarkValue: newLandmark, photos: photos, indoorLmLocImg: imageURI }); // pass it in here
|
|
}
|
|
}
|
|
- else{
|
|
|
|
- await addLandmarkAsync({landmarkValue: newLandmark, photos: photos });
|
|
|
|
|
|
+ else {
|
|
|
|
+ await addLandmarkAsync({ landmarkValue: newLandmark, photos: photos });
|
|
}
|
|
}
|
|
-
|
|
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ // create svg content here, then pass it to addLandmarkAsync as the value of indoorLmLocImg
|
|
|
|
+ // if (typeof newLandmark.floor === 'number') {
|
|
|
|
+ // let rectangle = serialize()
|
|
|
|
+ // await addLandmarkAsync({ landmarkValue: newLandmark, photos: photos, indoorLmLocImg: rectangle }); // pass it in here
|
|
|
|
+ // }
|
|
|
|
+ // else {
|
|
|
|
+ // await addLandmarkAsync({ landmarkValue: newLandmark, photos: photos });
|
|
|
|
+ // }
|
|
|
|
+
|
|
close()
|
|
close()
|
|
}
|
|
}
|
|
|
|
|
|
@@ -173,7 +189,7 @@ const AddLandmarkPanel: React.FC<AddLandmarkProps> = ({newLandmark, setNewLandma
|
|
|
|
|
|
const addPhoto = (result: ImageInfo) => {
|
|
const addPhoto = (result: ImageInfo) => {
|
|
togglePhotoSourceMenu(false)
|
|
togglePhotoSourceMenu(false)
|
|
- const photo: LMPhoto = {id: '', image_b64: 'data:image/png;base64,' + result.base64, height: result.height, width: result.width, landmark: ''}
|
|
|
|
|
|
+ const photo: LMPhoto = { id: '', image_b64: 'data:image/png;base64,' + result.base64, height: result.height, width: result.width, landmark: '' }
|
|
setPhotos([...photos, photo])
|
|
setPhotos([...photos, photo])
|
|
}
|
|
}
|
|
|
|
|
|
@@ -182,112 +198,131 @@ const AddLandmarkPanel: React.FC<AddLandmarkProps> = ({newLandmark, setNewLandma
|
|
}
|
|
}
|
|
|
|
|
|
return (
|
|
return (
|
|
|
|
+
|
|
<Modal
|
|
<Modal
|
|
useNativeDriver={true}
|
|
useNativeDriver={true}
|
|
useNativeDriverForBackdrop={true}
|
|
useNativeDriverForBackdrop={true}
|
|
-
|
|
|
|
|
|
+
|
|
testID="addLMModal"
|
|
testID="addLMModal"
|
|
avoidKeyboard={photos.length == 0}
|
|
avoidKeyboard={photos.length == 0}
|
|
onBackdropPress={close}
|
|
onBackdropPress={close}
|
|
- style={{justifyContent: "flex-end", height: '100%', margin: 0}}
|
|
|
|
|
|
+ style={{ justifyContent: "flex-end", height: '100%', margin: 0 }}
|
|
isVisible={visible} >
|
|
isVisible={visible} >
|
|
- <SafeAreaView style={{backgroundColor: colors.red, height: photos.length>0 ? Dimensions.get('window').height * .8 : Dimensions.get('window').height * .6}}>
|
|
|
|
|
|
+ <SafeAreaView style={{ backgroundColor: colors.red, height: photos.length > 0 ? Dimensions.get('window').height * .8 : Dimensions.get('window').height * .6 }}>
|
|
{addLandmarkStatus == 'idle' ?
|
|
{addLandmarkStatus == 'idle' ?
|
|
- <>
|
|
|
|
- <View style={{
|
|
|
|
- justifyContent: 'space-between',
|
|
|
|
- alignItems: 'center',
|
|
|
|
- flexDirection: "row",
|
|
|
|
- marginBottom: 15,
|
|
|
|
- borderBottomWidth: 1,
|
|
|
|
- borderBottomColor: 'white',
|
|
|
|
- paddingHorizontal: 20,
|
|
|
|
- paddingVertical: 10}}>
|
|
|
|
- <Text style={{color: 'white', fontSize: 15}}>Add landmark here?</Text>
|
|
|
|
- <TouchOpaq
|
|
|
|
- func={close}
|
|
|
|
- name={"close"}
|
|
|
|
- size={25}
|
|
|
|
- col={"white"}
|
|
|
|
- />
|
|
|
|
-
|
|
|
|
- </View>
|
|
|
|
- <ScrollView>
|
|
|
|
- <View style={{paddingHorizontal: 20, paddingBottom: 20 }}>
|
|
|
|
- <TextInput
|
|
|
|
- returnKeyType="done"
|
|
|
|
- blurOnSubmit={true}
|
|
|
|
- multiline={true}
|
|
|
|
- style={{backgroundColor: 'white', textAlignVertical: 'top', paddingHorizontal: 10, paddingTop: 10, paddingBottom: 10, marginBottom: 20, height: 150}}
|
|
|
|
- placeholder="Description"
|
|
|
|
- onChangeText={value => setNewLandmark({...newLandmark, description: value})}>
|
|
|
|
- {newLandmark?.description}
|
|
|
|
- </TextInput>
|
|
|
|
- <View style={{flexDirection: 'row'}}>
|
|
|
|
- <Picker
|
|
|
|
- style={{
|
|
|
|
- inputIOS: {color: 'white'},
|
|
|
|
- inputAndroid: {color: 'white'},
|
|
|
|
- viewContainer: {marginVertical: 5, flex: 1}, placeholder: {color: 'white'}}}
|
|
|
|
- textInputProps={{placeholderTextColor: 'white', selectionColor: 'white'}}
|
|
|
|
- Icon={() => <FontAwesome name="chevron-down" color='white' size={20} />}
|
|
|
|
- placeholder={{label: "Select a landmark type...", value: 0}}
|
|
|
|
- value={newLandmark?.landmark_type}
|
|
|
|
- onValueChange={(value) => {
|
|
|
|
- if (value) {
|
|
|
|
- setNewLandmark({...newLandmark, landmark_type: value, title: lmTypes[value].label})
|
|
|
|
- }
|
|
|
|
- else {
|
|
|
|
- setNewLandmark({...newLandmark, landmark_type: undefined, title: 'no title'})
|
|
|
|
- }
|
|
|
|
- }}
|
|
|
|
- useNativeAndroidPickerStyle={true}
|
|
|
|
- items={Object.keys(lmTypes)?.map(icon => {
|
|
|
|
- return (
|
|
|
|
- {label: lmTypes[parseInt(icon)]?.label.toUpperCase(), value: icon, key: icon}
|
|
|
|
- )})}
|
|
|
|
- />
|
|
|
|
- {newLandmark?.landmark_type ? <Image style={{marginLeft: 20}} source={lmTypes[newLandmark.landmark_type].image}/>
|
|
|
|
- : null}
|
|
|
|
- </View>
|
|
|
|
|
|
+ <>
|
|
|
|
+ <View style={{
|
|
|
|
+ justifyContent: 'space-between',
|
|
|
|
+ alignItems: 'center',
|
|
|
|
+ flexDirection: "row",
|
|
|
|
+ marginBottom: 15,
|
|
|
|
+ borderBottomWidth: 1,
|
|
|
|
+ borderBottomColor: 'white',
|
|
|
|
+ paddingHorizontal: 20,
|
|
|
|
+ paddingVertical: 10
|
|
|
|
+ }}>
|
|
|
|
+ <Text style={{ color: 'white', fontSize: 15 }}>Add landmark here?</Text>
|
|
|
|
+ <TouchOpaq
|
|
|
|
+ func={close}
|
|
|
|
+ name={"close"}
|
|
|
|
+ size={25}
|
|
|
|
+ col={"white"}
|
|
|
|
+ />
|
|
|
|
+
|
|
</View>
|
|
</View>
|
|
- {newLandmark?.landmark_type ?
|
|
|
|
- <View style={{justifyContent: 'flex-end', flexDirection: 'row', paddingHorizontal: 20, marginTop: 5}}>
|
|
|
|
- {newLandmark.description && newLandmark.title ?
|
|
|
|
- <View style={{flexDirection: 'row' }}>
|
|
|
|
- <TouchableOpacity onPress={async () => await submit()}><Text style={{color: 'white', marginRight: 25}}>Add</Text></TouchableOpacity>
|
|
|
|
- <TouchableOpacity onPress={close}><Text style={{color: 'white', marginRight: 25}}>Cancel</Text></TouchableOpacity>
|
|
|
|
- {photos.length == 0 ? <TouchableOpacity onPress={() => togglePhotoSourceMenu(true)}><Text style={{color: 'white'}}>Include photos</Text></TouchableOpacity> : null }
|
|
|
|
- </View> : null}
|
|
|
|
- </View> : null}
|
|
|
|
- {photos?.length ?
|
|
|
|
- <View>
|
|
|
|
- <ScrollView style={{borderTopWidth: 1, borderColor: 'lightgray', paddingTop: 20, marginHorizontal: 20, flexDirection: 'row', marginBottom: 5, marginTop: 30}} horizontal={true}>
|
|
|
|
- {photos.map((photo, i) => {
|
|
|
|
- return (
|
|
|
|
- <View key={i} style={{marginHorizontal: 1, padding: 15}}>
|
|
|
|
- <IconButton style={{position: 'absolute', top: 0, right: 0, zIndex: 10, }} icon="times-circle" color="lightgray" size={20} onPress={() => deletePhoto(i)} />
|
|
|
|
- <Image style={{borderWidth: 1, alignSelf: 'center', height: 200, width: 200 * photo.width / photo.height}} source={{uri: photo.image_b64}} />
|
|
|
|
- </View>
|
|
|
|
- )
|
|
|
|
- })}
|
|
|
|
- {photos.length < 5 ? <IconButton style={{alignSelf: 'center', padding: 10, opacity: .5, marginLeft: 10}} color='white' size={30} icon="plus" onPress={() => togglePhotoSourceMenu(true)} /> : null}
|
|
|
|
- </ScrollView>
|
|
|
|
- </View> : null}
|
|
|
|
- </ScrollView>
|
|
|
|
- </> :
|
|
|
|
- <View style={{height: '100%', justifyContent: "space-evenly", alignItems: "center"}}>
|
|
|
|
- <Text style={{color: 'white', fontSize: 20}}>{
|
|
|
|
- addLandmarkStatus == "loading" ? 'Uploading landmark...' :
|
|
|
|
- addLandmarkStatus == "error" ? 'Something went wrong when trying to upload the landmark.' : null }
|
|
|
|
- </Text>
|
|
|
|
- {
|
|
|
|
- addLandmarkStatus == "loading" ? <ActivityIndicator color='white' size="large"/> :
|
|
|
|
- addLandmarkStatus == "error" ? <SecondaryButton text="Okay" onPress={close}/> : null
|
|
|
|
- }
|
|
|
|
- </View> }
|
|
|
|
|
|
+ <ScrollView>
|
|
|
|
+ <View style={{ paddingHorizontal: 20, paddingBottom: 20 }}>
|
|
|
|
+ <TextInput
|
|
|
|
+ returnKeyType="done"
|
|
|
|
+ blurOnSubmit={true}
|
|
|
|
+ multiline={true}
|
|
|
|
+ style={{ backgroundColor: 'white', textAlignVertical: 'top', paddingHorizontal: 10, paddingTop: 10, paddingBottom: 10, marginBottom: 20, height: 150 }}
|
|
|
|
+ placeholder="Description"
|
|
|
|
+ onChangeText={value => setNewLandmark({ ...newLandmark, description: value })}>
|
|
|
|
+ {newLandmark?.description}
|
|
|
|
+ </TextInput>
|
|
|
|
+ <View style={{ flexDirection: 'row' }}>
|
|
|
|
+ <Picker
|
|
|
|
+ style={{
|
|
|
|
+ inputIOS: { color: 'white' },
|
|
|
|
+ inputAndroid: { color: 'white' },
|
|
|
|
+ viewContainer: { marginVertical: 5, flex: 1 }, placeholder: { color: 'white' }
|
|
|
|
+ }}
|
|
|
|
+ textInputProps={{ placeholderTextColor: 'white', selectionColor: 'white' }}
|
|
|
|
+ Icon={() => <FontAwesome name="chevron-down" color='white' size={20} />}
|
|
|
|
+ placeholder={{ label: "Select a landmark type...", value: 0 }}
|
|
|
|
+ value={newLandmark?.landmark_type}
|
|
|
|
+ onValueChange={(value) => {
|
|
|
|
+ if (value) {
|
|
|
|
+ setNewLandmark({ ...newLandmark, landmark_type: value, title: lmTypes[value].label })
|
|
|
|
+ }
|
|
|
|
+ else {
|
|
|
|
+ setNewLandmark({ ...newLandmark, landmark_type: undefined, title: 'no title' })
|
|
|
|
+ }
|
|
|
|
+ }}
|
|
|
|
+ useNativeAndroidPickerStyle={true}
|
|
|
|
+ items={Object.keys(lmTypes)?.map(icon => {
|
|
|
|
+ return (
|
|
|
|
+ { label: lmTypes[parseInt(icon)]?.label.toUpperCase(), value: icon, key: icon }
|
|
|
|
+ )
|
|
|
|
+ })}
|
|
|
|
+ />
|
|
|
|
+ {newLandmark?.landmark_type ? <Image style={{ marginLeft: 20 }} source={lmTypes[newLandmark.landmark_type].image} />
|
|
|
|
+ : null}
|
|
|
|
+ </View>
|
|
|
|
+ </View>
|
|
|
|
+ {newLandmark?.landmark_type ?
|
|
|
|
+ <View style={{ justifyContent: 'flex-end', flexDirection: 'row', paddingHorizontal: 20, marginTop: 5 }}>
|
|
|
|
+ {newLandmark.description && newLandmark.title ?
|
|
|
|
+ <View style={{ flexDirection: 'row' }}>
|
|
|
|
+ <TouchableOpacity onPress={async () => await submit()}><Text style={{ color: 'white', marginRight: 25 }}>Add</Text></TouchableOpacity>
|
|
|
|
+ <TouchableOpacity onPress={close}><Text style={{ color: 'white', marginRight: 25 }}>Cancel</Text></TouchableOpacity>
|
|
|
|
+ {photos.length == 0 ? <TouchableOpacity onPress={() => togglePhotoSourceMenu(true)}><Text style={{ color: 'white' }}>Include photos</Text></TouchableOpacity> : null}
|
|
|
|
+ </View> : null}
|
|
|
|
+ </View> : null}
|
|
|
|
+ {photos?.length ?
|
|
|
|
+ <View>
|
|
|
|
+ <ScrollView style={{ borderTopWidth: 1, borderColor: 'lightgray', paddingTop: 20, marginHorizontal: 20, flexDirection: 'row', marginBottom: 5, marginTop: 30 }} horizontal={true}>
|
|
|
|
+ {photos.map((photo, i) => {
|
|
|
|
+ return (
|
|
|
|
+ <View key={i} style={{ marginHorizontal: 1, padding: 15 }}>
|
|
|
|
+ <IconButton style={{ position: 'absolute', top: 0, right: 0, zIndex: 10, }} icon="times-circle" color="lightgray" size={20} onPress={() => deletePhoto(i)} />
|
|
|
|
+ <Image style={{ borderWidth: 1, alignSelf: 'center', height: 200, width: 200 * photo.width / photo.height }} source={{ uri: photo.image_b64 }} />
|
|
|
|
+ </View>
|
|
|
|
+ )
|
|
|
|
+ })}
|
|
|
|
+ {photos.length < 5 ? <IconButton style={{ alignSelf: 'center', padding: 10, opacity: .5, marginLeft: 10 }} color='white' size={30} icon="plus" onPress={() => togglePhotoSourceMenu(true)} /> : null}
|
|
|
|
+ </ScrollView>
|
|
|
|
+ </View> : null}
|
|
|
|
+ </ScrollView>
|
|
|
|
+ </> :
|
|
|
|
+ <View style={{ height: '100%', justifyContent: "space-evenly", alignItems: "center" }}>
|
|
|
|
+ <Text style={{ color: 'white', fontSize: 20 }}>{
|
|
|
|
+ addLandmarkStatus == "loading" ? 'Uploading landmark...' :
|
|
|
|
+ addLandmarkStatus == "error" ? 'Something went wrong when trying to upload the landmark.' : null}
|
|
|
|
+ </Text>
|
|
|
|
+ {
|
|
|
|
+ addLandmarkStatus == "loading" ? <ActivityIndicator color='white' size="large" /> :
|
|
|
|
+ addLandmarkStatus == "error" ? <SecondaryButton text="Okay" onPress={close} /> : null
|
|
|
|
+ }
|
|
|
|
+ </View>}
|
|
</SafeAreaView>
|
|
</SafeAreaView>
|
|
<PhotoPicker multiple={true} menuType='alert' photoSourceMenuOpened={photoSourceMenuOpened} onReceivedPhotoResult={result => addPhoto(result)} cancel={() => togglePhotoSourceMenu(false)} />
|
|
<PhotoPicker multiple={true} menuType='alert' photoSourceMenuOpened={photoSourceMenuOpened} onReceivedPhotoResult={result => addPhoto(result)} cancel={() => togglePhotoSourceMenu(false)} />
|
|
|
|
+
|
|
|
|
+ {/* <View style={{position:'absolute', zIndex:-1}}>
|
|
|
|
+ <ViewShot ref={capture} options={{format:'jpg'}}>
|
|
|
|
+ <Svg>
|
|
|
|
+ {renderIndoorLandmarkPin(newLandmark)}
|
|
|
|
+ <IndoorFloor floorNum={newLandmark.floor} />
|
|
|
|
+ Issue rn is that upon initial rendering, RN doesnt know what "newLandmark" is
|
|
|
|
+
|
|
|
|
+ <ImageSVG x={100} y={100} width={imageDim} height={imageDim} href={lmTypes[2]['image'] as ImageSourcePropType} />
|
|
|
|
+ <IndoorFloor floorNum={2} />
|
|
|
|
+ </Svg>
|
|
|
|
+ </ViewShot>
|
|
|
|
+ </View> */}
|
|
|
|
+
|
|
|
|
+
|
|
</Modal>
|
|
</Modal>
|
|
)
|
|
)
|
|
}
|
|
}
|