Last active
July 8, 2022 12:50
-
-
Save boblitex/3098cd0d50bf09a800ecd5b7b45cafad to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* eslint-disable no-sequences */ | |
/* eslint-disable no-return-assign */ | |
/* eslint-disable no-empty */ | |
/* eslint-disable no-plusplus */ | |
/* eslint-disable no-unsafe-finally */ | |
/* eslint-disable no-undef */ | |
/* eslint-disable global-require */ | |
import React, { useState, useEffect, useRef, useCallback } from 'react'; | |
import { FlatList, View, Text, Pressable, Animated, Platform } from 'react-native'; | |
import NetInfo, { useNetInfo } from '@react-native-community/netinfo'; | |
import Ping from 'react-native-ping'; | |
import DevicesIcon from '../../../assets/svg_images/devices.svg'; | |
import Container from '../../../components/layout/Container.component'; | |
import { ScannedRowItem } from '../rowItems/ScannedRow.item'; | |
import Button from '../../../components/button/Button.component'; | |
import UploadToolsTest from '../../../components/uploadToolsTest/uploadToolsTest'; | |
import * as colors from '../../../constants/colors'; | |
import { styles } from './ScanNetwork.style'; | |
import { onStartShouldSetResponder } from '../../../hooks/onStartShouldSetResponder'; | |
export default function ScanNetworkScreen({ show = false, setNetworkScanner = () => {}, events, trigger = false }) { | |
const animation = useRef(new Animated.Value(0)); | |
const stop = useRef(false); | |
const { details: netInfo } = useNetInfo(); | |
const [idx, setIdx] = useState(0); | |
const [data, setData] = useState([]); | |
const [status, setStatus] = useState(false); | |
const [isLoading, setIsLoading] = useState(false); | |
const [type, setType] = useState(null); | |
const [showUploadModal, setShowUploadModal] = useState(false); | |
const [jsonData, setJsonData] = useState([]); | |
const [showButton, setShowButton] = useState(false); | |
const compareIPAddresses = (a, b) => { | |
const numA = Number( | |
a.name | |
.split('.') | |
.map((num, id) => num * Math.pow(2, (3 - id) * 8)) | |
.reduce((ip, v) => ((ip += v), ip), 0), | |
); | |
const numB = Number( | |
b.name | |
.split('.') | |
.map((num, id) => num * Math.pow(2, (3 - id) * 8)) | |
.reduce((ip, v) => ((ip += v), ip), 0), | |
); | |
return numA - numB; | |
}; | |
const scanNetwork = async () => { | |
const ip = netInfo?.ipAddress; | |
const substr = (ip ?? '---').lastIndexOf('.'); | |
const ipRange = (ip ?? '---').substring(0, substr + 1); | |
for (let i = 0; i < 256; i++) { | |
if (!stop.current) { | |
const tmpIP = !stop.current ? ipRange + i.toString() : ''; | |
try { | |
// let timeoutValue = 500; | |
// if (Platform.OS === 'ios') { | |
// timeoutValue = 1000; | |
// } | |
const tmpMS = !stop.current && (await Ping.start(tmpIP, { timeout: 300 })); | |
!stop.current | |
? setData((prev) => [ | |
...prev, | |
{ | |
id: i, | |
image: DevicesIcon, | |
name: tmpIP, | |
pingms: tmpMS, | |
value: '---', | |
}, | |
]) | |
: null; | |
} catch (error) { | |
// | |
} finally { | |
!stop.current ? setIdx((prev) => prev + 1) : null; | |
} | |
} else { | |
break; | |
} | |
} | |
}; | |
useEffect(() => () => (stop.current = true), []); | |
useEffect(() => { | |
NetInfo.fetch().then((state) => { | |
setType(state.type); | |
}); | |
return () => null; | |
}, [type]); | |
const runTest = () => { | |
setIsLoading(true); | |
scanNetwork(); | |
setStatus(true); | |
stop.current = false; | |
}; | |
const stopTest = async () => { | |
setStatus(false); | |
setIsLoading(false); | |
stop.current = true; | |
}; | |
const search = () => { | |
if (idx === 0 && !status && netInfo && !isLoading) { | |
runTest(); | |
} else if ((idx !== 0 && stop.current) || (idx >= 255 && !stop.current)) { | |
setIdx(0); | |
setData([]); | |
setShowButton(false); | |
stop.current = false; | |
setTimeout(() => runTest(), 0); | |
} else if (idx !== 0 && status && isLoading && !stop.current) { | |
stopTest(); | |
} | |
}; | |
const sendDataToServer = useCallback(() => { | |
const info = data.map(({ id, image, value, ...rest }) => ({ | |
ipAddress: rest.name, | |
pingResponse: rest.pingms, | |
})); | |
// show the Upload Tools Test Modal | |
setShowUploadModal(true); | |
// set the data to upload | |
setJsonData(info); | |
}, []); | |
const percentage = | |
((idx / 256) * 100).toFixed(2).split('.')[1] !== '00' | |
? `${((idx / 256) * 100).toFixed(2)}%` | |
: `${((idx / 256) * 100).toFixed(0)}%`; | |
useEffect(() => { | |
Animated.timing(animation.current, { | |
toValue: 100, | |
duration: 500, | |
useNativeDriver: false, // <-- Add this | |
}).start(); | |
}, []); | |
useEffect(() => { | |
if (idx === 255) { | |
setIsLoading(false); | |
setNetworkScanner(true); | |
setShowButton(true); | |
stop.current = false; | |
} | |
return () => null; | |
}, [idx, netInfo]); | |
useEffect(() => { | |
if (trigger && events) { | |
events.shareScanNetworkResult = sendDataToServer; | |
} | |
}, [trigger]); | |
return ( | |
<Container style={{ flex: 1, backgroundColor: !show ? colors.brandSuperLightGrey : colors.bgWhite }}> | |
<View | |
onStartShouldSetResponder={onStartShouldSetResponder} | |
style={[ | |
styles.card, | |
{ | |
shadowColor: !show ? colors.textBlack : colors.bgWhite, | |
margin: !show ? 16 : 15, | |
paddingVertical: !show ? 32 : 15, | |
}, | |
]} | |
> | |
<UploadToolsTest | |
showUploadModal={showUploadModal} | |
data={JSON.stringify(jsonData)} | |
tagFrom="scannetwork" | |
setShowUploadModal={(val) => setShowUploadModal(val)} | |
/> | |
<Pressable | |
onPress={() => type === 'wifi' && search()} | |
style={[ | |
styles.btn, | |
{ | |
opacity: type !== 'wifi' ? 0.3 : 1.0, | |
borderColor: type === 'wifi' ? colors.brandGreenLight : colors.brandGrayLight, | |
}, | |
]} | |
> | |
<View | |
style={[styles.btnContainer, { borderColor: type === 'wifi' ? colors.brandGreen : colors.brandMediumGrey }]} | |
> | |
<Text style={styles.btnText}>{!isLoading ? 'Start' : 'Stop'}</Text> | |
</View> | |
</Pressable> | |
{idx > 0 || showButton ? ( | |
<> | |
<Text style={styles.cardText}>{percentage}</Text> | |
<View style={styles.progressBar}> | |
<Animated.View | |
style={[styles.progressBarFill, { backgroundColor: colors.brandDarkBlue, width: percentage }]} | |
/> | |
</View> | |
<Text style={styles.cardSubtext}> | |
{data.length > 0 && !isLoading ? 'Discovery completed.' : null} | |
{isLoading ? 'Discovering devices now...' : null} | |
</Text> | |
</> | |
) : null} | |
</View> | |
<View | |
style={[ | |
styles.card, | |
{ | |
shadowColor: !show ? colors.textBlack : colors.bgWhite, | |
margin: !show ? 16 : 0, | |
padding: 16, | |
flex: 1, | |
display: data.length > 0 ? 'flex' : 'none', | |
}, | |
]} | |
> | |
<FlatList | |
style={styles.list} | |
data={data.sort(compareIPAddresses)} | |
renderItem={({ item }) => <ScannedRowItem item={item} />} | |
keyExtractor={(item) => item.id} | |
/> | |
{showButton && !show ? ( | |
<Button | |
width={100} | |
theme="#00b4b0" | |
mode="contained" | |
label="Share with Mweb" | |
onPress={sendDataToServer} | |
style={{ marginTop: 10, marginBottom: 0 }} | |
/> | |
) : null} | |
</View> | |
</Container> | |
); | |
} |
If you're still having issues, feel free to put together an MRE or give me temporary access to your repo -- and I'll try to run and debug on my end.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
okay thanks, Ryan, let me give these suggestions a shot and see.