import React, { Component } from 'react'; import { StyleSheet, View, Dimensions, ActivityIndicator, StatusBar } from 'react-native'; import MapView, { Marker, Region } from 'react-native-maps'; import { connect } from 'redux-su'; import { NavigationActions } from 'react-navigation'; import MapOverlay from './MapOverlay'; import MapObjects from './MapObjects'; import PortalPanel from './PortalPanel'; import debounce, { getBottomSpace } from '../helper'; import actions from '../Actions/actions'; import { LatLng } from '../Api/interfaces'; import { getZoomByRegion, getDataZoomForMapZoom } from '../Api/api'; const { width, height } = Dimensions.get("screen") const draggableRange = { top: height / 1.75, bottom: 120 + getBottomSpace() } type Props = any type State = any class Map extends Component { static navigationOptions = ({ navigation }) => { return { title: 'Карта', }; }; refreshTimer: number | undefined map!: MapView; constructor(props: Props) { super(props) this.state = { user: undefined, region: null, dataZoom: 15, } this.load = debounce(this.load, 300) } componentDidMount() { this.refreshTimer = setInterval(() => { this.refresh() }, 30000) } componentWillUnmount() { clearInterval(this.refreshTimer) } componentWillMount() { const setPosition = (position) => { this.setState({ user: { latitude: position.coords.latitude, longitude: position.coords.longitude }, }); } navigator.geolocation.getCurrentPosition( setPosition, error => alert(error.message), { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 } ); navigator.geolocation.watchPosition( setPosition, error => alert(error.message), { enableHighAccuracy: true, timeout: 20000, maximumAge: 1000 } ) } onRegionChange = (region: Region) => { const zoom = getZoomByRegion(width, region) const dataZoom = getDataZoomForMapZoom(zoom); this.setState({ region, dataZoom }) this.props.actions.setRegion(region) setImmediate(() => this.load(false)) } refresh = () => { setImmediate(() => this.load(true)) } load = async (refresh: boolean) => { if (this.state.region != null) { this.props.actions.update(this.state.region, width, refresh) } return null } onPortalClick = (guid: string, coords: LatLng) => { if (this.state.selectedPortal && this.state.selectedPortal.guid == guid) { this.setState({ selectedPortal: false }) } else { this.setState({ selectedPortal: { guid, coords } }) } } onPortalDismiss = () => { this.setState({ selectedPortal: false }) } onOpenPortal = (guid: string, coords: LatLng) => { const navigateAction = NavigationActions.navigate({ routeName: 'Portal', params: { guid, coords }, }); this.props.navigation.dispatch(navigateAction); } goToMe = () => { this.map.animateToCoordinate(this.state.user) } render() { if (!this.state.user) { return } const initialRegion = this.props.settings.region || { ...this.state.user, latitudeDelta: 0.002, longitudeDelta: 0.002 } return ( <> (r != null) ? this.map = r : null} style={styles.container} initialRegion={initialRegion} onRegionChangeComplete={this.onRegionChange} showsCompass={false} showsScale showsUserLocation userLocationAnnotationTitle="" showsMyLocationButton loadingEnabled type={'hybrid'} shouldRasterizeIOS renderToHardwareTextureAndroid > ); } } const styles = StyleSheet.create({ container: { flex: 1, }, }); export default connect({ 'entities': 'entities', 'settings': 'settings' }, actions)(Map)