summaryrefslogblamecommitdiff
path: root/src/Components/Map.tsx
blob: 68698f4e727b370dc19932d3d6853a30e29363d7 (plain) (tree)





















                                                                               





                                                    




                               
                         

         







                                               
                          







                                                        
                                                 
                        



                                                                          
                        




                                                                          
                                 

                                            


                                           
     
 
                                        
                                        




                                                                        











                                                           



                                                     



                                                                                                    
 













                                                                                                       
                                                                     


                                                                                                           


                                                                  











                                                              


                                                               
import React, { Component } from 'react';
import { StyleSheet, View, Dimensions, ActivityIndicator } from 'react-native';
import MapView, { Marker, Region, UrlTile } 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 { getBottomSpace } from '../helper';
import actions from '../Actions/actions';
import { LatLng } from '../Api/interfaces';

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<Props, State> {
    static navigationOptions = ({ navigation }) => {
        return {
            title: 'Карта',
        };
    };
    refreshTimer: number | undefined
    map!: MapView;
    constructor(props: Props) {
        super(props)
        this.state = {
            user: undefined,
            region: null,
        }
    }
    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) => {
        this.setState({ 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) => {
        this.setState({ selectedPortal: { guid, coords } })
    }

    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 <View style={styles.spinnerContainer}><ActivityIndicator size={'large'} /></View>
        }

        return (
            <>
                <MapView
                    ref={r => (r != null) ? this.map = r : null}
                    style={styles.container}
                    initialRegion={{ ...this.state.user, latitudeDelta: 0.002, longitudeDelta: 0.002 }}
                    onRegionChangeComplete={this.onRegionChange}
                    showsCompass={false}
                    showsScale
                    showsUserLocation
                    showsMyLocationButton
                    loadingEnabled
                    type={'hybrid'}
                >
                    <MapObjects onPortalClick={this.onPortalClick} />
                    {this.state.selectedPortal && <Marker coordinate={this.state.selectedPortal.coords} />}
                </MapView>
                <MapOverlay
                    goToMe={this.goToMe}
                    refresh={this.refresh}
                    loading={this.props.entities.loadQueue.length}
                    selectedPortal={this.state.selectedPortal}
                    onOpenPortal={this.onOpenPortal}
                />
            </>
        );
    }
}

const styles = StyleSheet.create({
    container: {
        flex: 1,
    },
});

export default connect({ 'entities': 'entities' }, actions)(Map)