Skip to content

Instantly share code, notes, and snippets.

@boblitex
Last active July 8, 2022 12:50
Show Gist options
  • Save boblitex/3098cd0d50bf09a800ecd5b7b45cafad to your computer and use it in GitHub Desktop.
Save boblitex/3098cd0d50bf09a800ecd5b7b45cafad to your computer and use it in GitHub Desktop.
/* 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>
);
}
@techrah
Copy link

techrah commented Jul 8, 2022

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