Passed
Push — dev ( dc7ede...6b529c )
by Kasper
05:04 queued 01:55
created

QrScanner.tsx ➔ QrScanner   C

Complexity

Conditions 7

Size

Total Lines 94
Code Lines 75

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 75
dl 0
loc 94
rs 6.4181
c 0
b 0
f 0
cc 7

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
import React, { useState, useEffect } from 'react';
2
import { Text, View, StyleSheet, Button, Modal, Pressable, TextInput } from 'react-native';
3
import { BarCodeScanner } from 'expo-barcode-scanner';
4
import Icon from 'react-native-vector-icons/Octicons';
5
import scooterModel from '../../models/scooter';
6
import { showMessage, hideMessage } from "react-native-flash-message";
7
8
export default function QrScanner({navigation, cameraVisible, setCameraVisible, scooter, setModalVisible, currentCity, setCurrentScooter}) {
9
  const [hasPermission, setHasPermission] = useState(null);
10
  const [scanned, setScanned] = useState(false);
11
  const [code, setCode] = useState(null);
12
13
    useEffect(() => {
14
      const getBarCodeScannerPermissions = async () => {
15
        const { status } = await BarCodeScanner.requestPermissionsAsync();
16
        setHasPermission(status === 'granted');
17
      };
18
19
      getBarCodeScannerPermissions();
20
    }, []);
21
22
    async function handleBarCodeScanned({ type, data }) {
23
      setScanned(true);
24
25
      await startScooter(data);
26
      // alert(`Bar code with type ${type} and data ${data} has been scanned!`);
27
    };
28
29
    if (hasPermission === null) {
30
      return <Text>Requesting for camera permission</Text>;
31
    }
32
    if (hasPermission === false) {
33
      return <Text>No access to camera</Text>;
34
    }
35
36
    async function startScooter(scooter): Promise<void> {
37
      // Check if QR code is a valid scooter
38
      const result = await scooterModel.checkIfValidScooter(scooter, currentCity);
39
40
      
41
      if (result) {
42
        showMessage({
43
          message: 'Scooter scanned!',
44
          type: 'success'
45
        });
46
47
        setCameraVisible(!cameraVisible);
48
        setModalVisible(true);
49
        setCurrentScooter(result);
50
      } else {
51
        showMessage({
52
          message: 'Not a scooter!',
53
          type: 'danger'
54
        })
55
      }
56
57
      
58
    }
59
60
  return (
61
    <Modal
62
        animationType="slide"
63
        transparent={true}
64
        visible={cameraVisible}
65
        onRequestClose={() => {
66
        setCameraVisible(!cameraVisible);
67
        }}
68
    >
69
        <View style={[styles.container, styles.shadowProp]}>
70
            <Pressable style={[styles.backButton, styles.shadowProp]} onPress={() => setCameraVisible(!cameraVisible)}>
71
                <Icon 
72
                    name='x' 
73
                    size={25} 
74
                    color='black'
75
                />
76
            </Pressable>
77
            
78
            <Text style={styles.title}>Scan the QR-code</Text>
79
            <TextInput
80
            placeholder="or enter code manually"
81
            style={styles.input}
82
            onChangeText={(content: string) => {
83
                setCode(content)
84
            }}
85
            onSubmitEditing={() => startScooter(code)}
86
            />
87
        <BarCodeScanner
88
            onBarCodeScanned={scanned ? undefined : handleBarCodeScanned}
89
            style={styles.viewFinder}
90
        />
91
92
        <Pressable style={[styles.cameraButton, styles.shadowProp]} onPress={() => setScanned(false)} >
93
            <Icon 
94
                name='screen-full' 
95
                size={24} 
96
                color='black'
97
            />
98
        </Pressable>
99
        </View>
100
    </Modal>
101
102
  );
103
}
104
105
const styles = StyleSheet.create({
106
    container: {
107
    //   flex: 1,
108
      width: '100%',
109
      alignItems: 'center',
110
      backgroundColor: 'white',
111
      height: '80%',
112
      top: '20%',
113
      borderTopRightRadius: 25,
114
      borderTopLeftRadius: 25
115
116
    },
117
118
    viewFinder: {
119
        flex: 1,
120
        width: '70%',
121
    },
122
123
124
    shadowProp: {
125
        elevation: 5,
126
        shadowColor: 'black'
127
    },
128
    
129
    backButton: {
130
        position: 'absolute',
131
        width: 40,
132
        height: 40, 
133
        left: 20,
134
        backgroundColor: 'white',
135
        top: 20,
136
        borderRadius: 25,
137
        borderWidth: 1,
138
        borderColor: 'gray',
139
        alignItems: 'center',
140
        justifyContent: 'center'
141
    },
142
143
    cameraButton: {
144
        // position: 'absolute',
145
        width: 60,
146
        height: 60, 
147
        // left: 20,
148
        backgroundColor: 'white',
149
        bottom: 50,
150
        borderRadius: 50,
151
        borderWidth: 1,
152
        borderColor: 'gray',
153
        alignItems: 'center',
154
        justifyContent: 'center'
155
    },
156
157
    title: {
158
        position: 'absolute',
159
        fontWeight: 'bold',
160
        fontSize: 20,
161
        marginTop: 30
162
    },
163
164
    subTitle: {
165
      position: 'absolute',
166
      // fontWeight: 'bold',
167
      fontSize: 12,
168
      marginTop: 55,
169
      color: 'gray'
170
  },
171
172
    input: {
173
      width: '60%',
174
      marginBottom: 30,
175
      borderRadius: 10,
176
      height: 50,
177
      padding: 10,
178
      borderBottomWidth: 2,
179
      borderColor: 'gray',
180
      marginTop: 60,
181
      textAlign: 'center'
182
    }
183
})