import React from "react" import { StyleSheet, View, Image, ScrollView, Text, TextInput, KeyboardAvoidingView, Platform, TouchableOpacity, } from "react-native" import MapView, { Marker } from "react-native-maps" import { FormBinder } from "react-form-binder" import { Icon, Header, BoundInput, BoundButton, BoundOptionStrip, BoundHeader, BoundPhotoPanel, FormStaticInput, } from "../ui" import { MessageModal, WaitModal, ProgressModal } from "../Modal" import { reactAutoBind } from "auto-bind2" import KeyboardSpacer from "react-native-keyboard-spacer" import { isIphoneX } from "react-native-iphone-x-helper" import { api } from "../API" import { formatLatLng, workItemTypeEnum } from "../util" import moment from "moment" import "url-search-params-polyfill" import { config } from "../config" import { FormStaticOptionStrip, FormStaticPhotoPanel } from "../ui" const styles = StyleSheet.create({ container: { flexGrow: 1, backgroundColor: "#DDDDDD", }, panel: { width: "94%", backgroundColor: "white", alignSelf: "center", marginTop: "3%", shadowColor: "gray", shadowOffset: { width: 2, height: 2 }, shadowRadius: 2, shadowOpacity: 0.5, padding: 10, }, label: { fontSize: 14, marginBottom: 4, }, }) export class Activity extends React.Component { static bindings = { header: { noValue: true, isDisabled: (r) => !(r.anyModified && r.allValid), }, resolution: { isValid: (r, v) => v !== "", }, notes: { isValid: (r, v) => v !== "", }, photos: { initValue: [], isValid: (r, v) => v && v.length > 0, }, status: { isValid: (r, v) => v !== "", alwaysGet: true, }, workItem: { isValid: true, alwaysGet: true, }, team: { isValid: true, alwaysGet: true, }, } constructor(props) { super(props) reactAutoBind(this) this.state = { binder: new FormBinder({}, Activity.bindings), waitModal: null, messageModal: null, progressModal: null, uploadPercent: 0, } this.region = null this.isMapReady = false this.goToRegionWhenReady = false } componentDidMount() { const { search } = this.props.location const params = search ? new URLSearchParams(search) : { get: () => null } const id = params.get("id") const workItemId = params.get("workItemId") const getWorkItem = (id) => { this.setState({ waitModal: { message: "Loading Work Item Details..." } }) api .getWorkItem(id) .then((workItem) => { this.setState({ waitModal: null }) if (workItem) { const [lng, lat] = workItem.location.coordinates this.setState({ binder: new FormBinder( { ...this.state.binder.originalObj, workItem: workItem._id, team: api.loggedInUser.team, }, Activity.bindings ), location: formatLatLng(lat, lng), dateTime: moment().format(), details: workItem.details, workItemType: workItem.workItemType, workItemPhotos: workItem.photos, }) this.region = { latitude: lat, longitude: lng, latitudeDelta: config.activityRegionDelta, longitudeDelta: config.activityRegionDelta, } } if (this.isMapReady) { this.mapView.animateToRegion(this.region) } else { this.goToRegionWhenReady = true } }) .catch((err) => { this.setState({ waitModal: null, messageModal: { icon: "hand", message: "Unable to get work item details", detail: err.message, back: true, }, }) }) } if (id) { this.setState({ waitModal: { message: "Loading Activity..." } }) api .getActivity(id) .then((activity) => { this.setState({ waitModal: null }) if (activity) { this.setState({ binder: new FormBinder(activity, Activity.bindings), }) return getWorkItem(activity.workItem) } }) .catch((err) => { this.setState({ waitModal: null, messageModal: { icon: "hand", message: "Unable to get activity details", detail: err.message, back: true, }, }) }) } else { if (workItemId) { getWorkItem(workItemId) } else { this.handleBackPress() } } } handleOnMapReady() { if (this.goToRegionWhenReady) { this.mapView.animateToRegion(this.region) this.goToRegionWhenReady = false } this.isMapReady = true } handleMessageDismiss() { const back = this.state.messageModal.back this.setState({ messageModal: null }) if (back) { this.handleBackPress() } } handleBackPress() { const { history } = this.props if (history.length > 1) { history.goBack() } else { history.replace("/home") } } handleDonePress() { const { binder } = this.state let obj = binder.getModifiedBindingValues() if (!obj._id) { api .createActivity(obj) .then((activity) => { this.handleBackPress() }) .catch((error) => { this.setState({ messageModal: { icon: "hand", message: "Unable to create activity", detail: error.message, }, }) }) } else { api .updateActivity(obj) .then((activity) => { this.handleBackPress() }) .catch((error) => { this.setState({ messageModal: { icon: "hand", message: "Unable to update activity", detail: error.message, }, }) }) } } handleUploadStarted() { this.setState({ progressModal: { message: "Uploading Photo..." }, uploadPercent: 0, }) } handleUploadProgress(uploadData) { if (this.state.progressModal) { this.setState({ uploadPercent: Math.round( (uploadData.uploadedChunks / uploadData.numberOfChunks) * 100 ), }) return true } else { return false } } handleUploadEnded(successful, uploadData) { this.setState({ progressModal: null }) } handleUploadCanceled() { this.setState({ progressModal: null }) } render() { const { binder, messageModal, progressModal, waitModal, dateTime, location, details, workItemType, uploadPercent, workItemPhotos, } = this.state return ( (this.mapView = ref)} style={{ flexDirection: "column", justifyContent: "center", width: "100%", height: 400, marginTop: 10, }} zoomControlEnabled={false} zoomEnabled={false} scrollEnabled={false} rotateEnabled={false} pitchEnabled={false} showsIndoors={false} showsTraffic={false} showsCompass={false} showsScale={false} showsUserLocation cacheEnabled initialRegion={config.initialRegion} onMapReady={this.handleOnMapReady} /> {isIphoneX ? : null} {Platform.OS === "ios" && } ) } }