Passed
Push — dev ( f9a638...08dce6 )
by Kasper
01:03 queued 13s
created

components/Map.tsx   A

Complexity

Total Complexity 8
Complexity/F 1.6

Size

Lines of Code 263
Function Count 5

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
wmc 8
eloc 196
mnd 3
bc 3
fnc 5
dl 0
loc 263
rs 10
bpm 0.6
cpm 1.6
noi 0
c 0
b 0
f 0

3 Functions

Rating   Name   Duplication   Size   Complexity  
C Map.tsx ➔ Map 0 162 5
A Map.tsx ➔ DrawerButton 0 10 1
A Map.tsx ➔ markerIcon 0 6 2
1
import { useState, useEffect } from 'react';
2
import { ScrollView, Image, Text, View, StyleSheet, StatusBar, Button, Pressable, InteractionManagerStatic } from 'react-native';
3
import MapView, { Marker, Circle, Polygon } from 'react-native-maps';
4
import * as Location from 'expo-location';
5
import React from 'react';
6
import mapModel from '../models/map';
7
import scooterModel from '../models/scooter';
8
import {API_KEY} from "@env";
9
import config from '../config/config.json';
10
import Icon from 'react-native-vector-icons/Octicons';
11
import ScooterModal from './modals/ScooterModal';
12
import NavBar from './drawer/NavBar';
13
import ZoneModal from './modals/ZoneModal';
14
import ScanScreen from './modals/QrScanner';
15
import QRCodeScanner from 'react-native-qrcode-scanner';
16
import QrScanner from './modals/QrScanner';
17
import JourneyModal from './modals/JourneyModal';
18
19
const marker = require('../assets/scooter_white.png');
20
const selectedMarker = require('../assets/scooter_blue.png');
21
22
function markerIcon(index, selected) {
23
    if (index === selected) {
24
        return selectedMarker;
25
    }
26
    return marker;
27
};
28
29
function DrawerButton({navigation}) {
30
    return (
31
      <Pressable style={[styles.drawer, styles.shadowProp]} onPress={() => navigation.openDrawer()}> 
32
        <Icon 
33
        name='three-bars' 
34
        size={30} 
35
        color='black'
36
        />
37
      </Pressable>
38
    );
39
};
40
41
export default function Map({navigation, API_KEY, position, setPosition, token}): any {
42
    const [locationMarker, setLocationMarker] = useState(null);
43
    const [currentCity, setCurrentCity] = useState(null);
44
    const [zones, setZones] = useState([]);
45
    const [scooters, setScooters] = useState([]);
46
    const [currentScooter, setCurrentScooter] = useState(null);
47
    const [modalVisible, setModalVisible] = useState(false);
48
    const [zoneModalVisible, setZoneModalVisible] = useState(false);
49
    const [currentZone, setCurrentZone] = useState(null);
50
    const [cameraVisible, setCameraVisible] = useState(false);
51
    const [journeyModal, setJourneyModal] = useState(false);
52
    const [toggleTimer, setToggleTimer] = useState(false);
53
    const [markerSelected, setMarkerSelected] = useState(null);
54
        
55
    /**
56
     * Set user position
57
     */
58
    useEffect(() => {
59
        async function fetchPosition(): Promise<void> {
60
            const { status } = await Location.requestForegroundPermissionsAsync();
61
62
            // if (status !== 'granted') {
63
            //     setErrorMessage('Permission to access location was denied');
64
            //     return;
65
            // }
66
67
            const currentLocation = await Location.getCurrentPositionAsync({});
68
69
            const userCoordinates = {
70
                //latlang hardcoded for testing
71
                // latitude: currentLocation.coords.latitude,
72
                // longitude: currentLocation.coords.longitude
73
                latitude: 56.161013580817986,
74
                longitude: 15.587742977884904
75
            };
76
77
    
78
            setPosition(userCoordinates);
79
            
80
            mapModel.getClosestCity(position);
81
82
            setLocationMarker(<Marker
83
                coordinate={{
84
                    //latlang hardcoded for testing
85
                    // latitude: currentLocation.coords.latitude,
86
                    // longitude: currentLocation.coords.longitude
87
                    latitude: 56.161013580817986,
88
                    longitude: 15.587742977884904
89
                }}
90
                title="My location"
91
                pinColor="blue"
92
                flat={false}
93
            />);
94
        };
95
96
97
        fetchPosition();
98
99
    }, []);
100
101
    /**
102
     * Set city to city that is closest to user and zones for that city
103
     */
104
    useEffect(() => {
105
        async function setUpMap(): Promise<void> {
106
            const city = await mapModel.getClosestCity(position);
107
            
108
            
109
            // Set city that is closest to user
110
            setCurrentCity(city);
111
                        
112
            /**
113
             * Set zones on map
114
             */
115
            const zones = mapModel.getZones(city);
116
            setZones(zones);
117
118
119
            /**
120
             * Get all scooters and create markers for them on the map
121
             */
122
            const result = await scooterModel.getScooters(API_KEY, city); 
123
124
            const scooters = result['cityScooters'];
125
            const sortedScooters = scooterModel.sortAvailableScooters(scooters);
126
            // console.log(scooters[0]);
127
            
128
            // console.log(sortedScooters[0]);
129
130
            setScooters(sortedScooters);
131
            
132
        };
133
        setUpMap();
134
    }, []);
135
136
137
    return (
138
        <View style={styles.container}>
139
            <MapView
140
                style={styles.map}
141
                region={{
142
                    latitude: position.latitude? position.latitude : 0,
143
                    longitude: position.longitude? position.longitude : 0,
144
                    latitudeDelta: 0.03,
145
                    longitudeDelta: 0.03,
146
                }}
147
                userInterfaceStyle={'dark'}
148
            >
149
                {locationMarker}
150
151
                {scooters.map((s, index) => 
152
                    <Marker
153
                        // title={s['name']}
154
                        // description={`Charge ${s['battery']}% ${s['status']}`}
155
                        coordinate={s['coordinates']}
156
                        icon={markerIcon(index, markerSelected)}
157
                        tappable={true}
158
                        key={index}
159
                        onPress={() => {
160
                            setCurrentScooter(s);
161
                            setModalVisible(true);
162
                            setMarkerSelected(index);
163
                        }}
164
                        >
165
                    </Marker>
166
                )}
167
                {zones.map((z, index) => (                    
168
                    <Polygon 
169
                        coordinates={z['coordinates']}
170
                        strokeColor={z['zoneColor']}
171
                        strokeWidth={3}
172
                        fillColor={z['zoneColor']}
173
                        key={index}
174
                        tappable={true}
175
                        onPress={() => {
176
                            setCurrentZone(z)
177
                            setZoneModalVisible(true)                            
178
                        }}
179
                    />
180
                ))}
181
            </MapView>
182
183
            <ScooterModal navigation={navigation} scooter={currentScooter} modalVisible={modalVisible} currentCity={currentCity} setModalVisible={setModalVisible} setJourneyModal={setJourneyModal} setToggleTimer={setToggleTimer}/> 
184
185
            <ZoneModal navigation={navigation} zone={currentZone} zoneModalVisible={zoneModalVisible} setZoneModalVisible={setZoneModalVisible} />
186
            
187
 
188
            <JourneyModal navigation={navigation} scooter={currentScooter} journeyModal={journeyModal} setJourneyModal={setJourneyModal} toggleTimer={toggleTimer} setToggleTimer={setToggleTimer}/>
189
190
            <Pressable onPress={() => {setCameraVisible(true)}} style={styles.googleLogin}>
191
                    <Icon 
192
                        name='screen-full' 
193
                        size={15} 
194
                        color='white'
195
                    />
196
                    <Text style={styles.googleText}>Scan to unlock</Text>
197
            </Pressable>
198
199
            <NavBar navigation={navigation} />
200
            <QrScanner navigation={navigation} cameraVisible={cameraVisible} setCameraVisible={setCameraVisible}/>
201
        </View>
202
        
203
    )
204
}
205
206
const styles = StyleSheet.create({
207
    container: {
208
        // flex: 1,
209
        height: '100%',
210
        alignItems: "center",
211
        width: '100%'
212
    },
213
214
    map: {
215
        position: 'absolute',
216
        top: 0,
217
        left: 0,
218
        bottom: 0,
219
        right: 0,
220
    },
221
222
    drawer: {
223
        position: 'absolute',
224
        width: 50,
225
        height: 50, 
226
        left: 50,
227
        backgroundColor: 'white',
228
        marginTop: 50,
229
        borderRadius: 25,
230
        justifyContent: 'center',
231
        alignItems: 'center'
232
    },
233
    
234
    shadowProp: {
235
        elevation: 5,
236
        shadowColor: 'black'
237
    },
238
239
    googleLogin: {
240
        backgroundColor: '#1A1A1A',
241
        width: '65%',
242
        height: 45,
243
        borderRadius: 25,
244
        display: 'flex',
245
        flexDirection: 'row',
246
        justifyContent: 'center',
247
        alignItems: 'center',
248
        marginBottom: 30
249
    },
250
251
    googleText: {
252
        color: 'white',
253
        fontWeight: 'bold',
254
        fontSize: 18,
255
        marginLeft: 10
256
    },
257
258
    googleIcon: {
259
        height: 20,
260
        width: 20
261
    }
262
});
263
264