With VT score and Clear History
This commit is contained in:
122
App.tsx
122
App.tsx
@@ -4,37 +4,97 @@ import { NavigationContainer } from '@react-navigation/native';
|
|||||||
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
import { createBottomTabNavigator } from '@react-navigation/bottom-tabs';
|
||||||
import { CameraView, Camera } from 'expo-camera';
|
import { CameraView, Camera } from 'expo-camera';
|
||||||
import { Ionicons } from '@expo/vector-icons';
|
import { Ionicons } from '@expo/vector-icons';
|
||||||
|
import axios from 'axios'; // Import Axios for HTTP requests
|
||||||
|
|
||||||
// Create a Context for QR code data
|
// Create a Context for QR code data
|
||||||
const QRCodeContext = createContext();
|
const QRCodeContext = createContext();
|
||||||
|
|
||||||
const Tab = createBottomTabNavigator();
|
const Tab = createBottomTabNavigator();
|
||||||
|
|
||||||
|
// Component for QR Scanner Screen
|
||||||
function QRScannerScreen() {
|
function QRScannerScreen() {
|
||||||
const { qrCodes, setQrCodes } = useContext(QRCodeContext); // Access context
|
const { qrCodes, setQrCodes } = useContext(QRCodeContext); // Access context
|
||||||
const [hasPermission, setHasPermission] = useState(null);
|
const [hasPermission, setHasPermission] = useState(null); // State for camera permission
|
||||||
const [scanned, setScanned] = useState(false);
|
const [scanned, setScanned] = useState(false); // State for scanned status
|
||||||
const [showSplash, setShowSplash] = useState(true);
|
const [showSplash, setShowSplash] = useState(true); // State for splash screen
|
||||||
const [scannedData, setScannedData] = useState('');
|
const [scannedData, setScannedData] = useState(''); // State for scanned data
|
||||||
|
const [scanResult, setScanResult] = useState(null); // State for VirusTotal scan result
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initializeApp = async () => {
|
const initializeApp = async () => {
|
||||||
const { status } = await Camera.requestCameraPermissionsAsync();
|
const { status } = await Camera.requestCameraPermissionsAsync(); // Request camera permissions
|
||||||
setHasPermission(status === 'granted');
|
setHasPermission(status === 'granted'); // Set permission status
|
||||||
setShowSplash(false); // Hide splash screen after initializing
|
setShowSplash(false); // Hide splash screen
|
||||||
};
|
};
|
||||||
|
|
||||||
initializeApp();
|
initializeApp(); // Initialize app
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const handleBarCodeScanned = ({ type, data }) => {
|
// Function to handle barcode scanned event
|
||||||
setScanned(true); // Mark as scanned
|
const handleBarCodeScanned = async ({ type, data }) => {
|
||||||
const newScannedData = `Type: ${type}\nData: ${data}`;
|
setScanned(true); // Mark as scanned
|
||||||
setScannedData(newScannedData); // Save scanned data
|
|
||||||
setQrCodes([...qrCodes, newScannedData]); // Add scanned data to history
|
// Determine the type of data (URL, text, or just numbers)
|
||||||
alert(`Bar code with type ${type} and data ${data} has been scanned!`); // Show an alert
|
let dataType;
|
||||||
|
if (/^(http|https):\/\//.test(data)) {
|
||||||
|
dataType = 'URL';
|
||||||
|
} else if (/^[0-9]+$/.test(data)) {
|
||||||
|
dataType = 'Numbers';
|
||||||
|
} else {
|
||||||
|
dataType = 'Text';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Construct the scanned data with the data type
|
||||||
|
let newScannedData = `Type: ${dataType}\nData: ${data}`; // Initialize with type and data
|
||||||
|
|
||||||
|
try {
|
||||||
|
const scanId = await scanWithVirusTotal(data); // Send data to VirusTotal and get scan ID
|
||||||
|
const positive = await getScanResult(scanId); // Get scan result and extract positive score
|
||||||
|
newScannedData += `\nScore: ${positive}`; // Append positive score to newScannedData
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error handling barcode scan:', error); // Handle error
|
||||||
|
}
|
||||||
|
|
||||||
|
setScannedData(newScannedData); // Save scanned data
|
||||||
|
setQrCodes([...qrCodes, newScannedData]); // Add scanned data to history
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to send data to VirusTotal and get the scan ID
|
||||||
|
const scanWithVirusTotal = async (data) => {
|
||||||
|
const apiKey = '3566a17933bb36dd97cb35e84d0446e5ab8ad623e6de968d34b655c79485251e'; // Replace with your VirusTotal API key
|
||||||
|
const url = 'https://www.virustotal.com/vtapi/v2/url/scan';
|
||||||
|
const params = {
|
||||||
|
apikey: apiKey,
|
||||||
|
url: data
|
||||||
};
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.post(url, null, { params }); // Send URL scan request
|
||||||
|
return response.data.scan_id; // Return scan ID
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error scanning with VirusTotal:', error); // Handle error
|
||||||
|
throw error; // Propagate error
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Function to get scan result from VirusTotal and return the positive score
|
||||||
|
const getScanResult = async (scanId) => {
|
||||||
|
const apiKey = '3566a17933bb36dd97cb35e84d0446e5ab8ad623e6de968d34b655c79485251e'; // Replace with your VirusTotal API key
|
||||||
|
const url = 'https://www.virustotal.com/vtapi/v2/url/report';
|
||||||
|
const params = {
|
||||||
|
apikey: apiKey,
|
||||||
|
resource: scanId
|
||||||
|
};
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await axios.get(url, { params }); // Get scan result
|
||||||
|
return response.data.positives; // Return positive score
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error getting scan result:', error); // Handle error
|
||||||
|
throw error; // Propagate error
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
if (showSplash) {
|
if (showSplash) {
|
||||||
return (
|
return (
|
||||||
<View style={styles.splashContainer}>
|
<View style={styles.splashContainer}>
|
||||||
@@ -67,21 +127,19 @@ function QRScannerScreen() {
|
|||||||
style={styles.camera} // Apply styles
|
style={styles.camera} // Apply styles
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
|
{/* Display scanned data */}
|
||||||
{/* Display scanned data */}
|
{scannedData !== '' && (
|
||||||
{scannedData !== '' && (
|
|
||||||
<View style={styles.dataBox}>
|
<View style={styles.dataBox}>
|
||||||
<Text style={styles.dataText}>{scannedData}</Text>
|
<Text style={styles.dataText}>{scannedData}</Text>
|
||||||
|
{scanResult && <Text style={styles.dataText}>{JSON.stringify(scanResult)}</Text>}
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Button to scan again */}
|
{/* Button to scan again */}
|
||||||
{scanned && (
|
{scanned && (
|
||||||
<TouchableOpacity style={styles.button} onPress={() => setScanned(false)}>
|
<TouchableOpacity style={styles.button} onPress={() => setScanned(false)}>
|
||||||
<Text style={styles.buttonText}>Tap to Scan Again</Text>
|
<Text style={styles.buttonText}>Tap to Scan Again</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Menu (Placeholder for additional menu items) */}
|
{/* Menu (Placeholder for additional menu items) */}
|
||||||
<View style={styles.menu}>
|
<View style={styles.menu}>
|
||||||
{/* Your existing menu items */}
|
{/* Your existing menu items */}
|
||||||
@@ -90,6 +148,7 @@ function QRScannerScreen() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Component for History Screen
|
||||||
function HistoryScreen() {
|
function HistoryScreen() {
|
||||||
const { qrCodes } = useContext(QRCodeContext); // Access context
|
const { qrCodes } = useContext(QRCodeContext); // Access context
|
||||||
|
|
||||||
@@ -97,26 +156,38 @@ function HistoryScreen() {
|
|||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.welcomeText}>History Screen</Text>
|
<Text style={styles.welcomeText}>History Screen</Text>
|
||||||
<FlatList
|
<FlatList
|
||||||
data={qrCodes}
|
data={qrCodes} // Data for FlatList
|
||||||
renderItem={({ item }) => (
|
renderItem={({ item }) => (
|
||||||
<View style={styles.dataBox}>
|
<View style={styles.dataBox}>
|
||||||
<Text style={styles.dataText}>{item}</Text>
|
<Text style={styles.dataText}>{item}</Text>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
keyExtractor={(item, index) => index.toString()}
|
keyExtractor={(item, index) => index.toString()} // Key extractor for FlatList
|
||||||
/>
|
/>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Component for Settings Screen
|
||||||
function SettingsScreen() {
|
function SettingsScreen() {
|
||||||
|
const { setQrCodes } = useContext(QRCodeContext); // Access context
|
||||||
|
|
||||||
|
// Function to clear history
|
||||||
|
const clearHistory = () => {
|
||||||
|
setQrCodes([]);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.welcomeText}>Settings Screen</Text>
|
<Text style={styles.welcomeText}>Settings Screen</Text>
|
||||||
|
<TouchableOpacity style={styles.button} onPress={clearHistory}>
|
||||||
|
<Text style={styles.buttonText}>Clear History</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Component for Profile Screen
|
||||||
function ProfileScreen() {
|
function ProfileScreen() {
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
@@ -235,4 +306,13 @@ const styles = StyleSheet.create({
|
|||||||
backgroundColor: "#ff69b4", // pink background
|
backgroundColor: "#ff69b4", // pink background
|
||||||
paddingVertical: 10,
|
paddingVertical: 10,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
||||||
|
// Additional styles for green and red boxes
|
||||||
|
greenBox: {
|
||||||
|
backgroundColor: '#00FF00', // Green color
|
||||||
|
},
|
||||||
|
redBox: {
|
||||||
|
backgroundColor: '#FF0000', // Red color
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
48
package-lock.json
generated
48
package-lock.json
generated
@@ -11,6 +11,7 @@
|
|||||||
"@expo/vector-icons": "^14.0.2",
|
"@expo/vector-icons": "^14.0.2",
|
||||||
"@react-navigation/bottom-tabs": "^6.5.20",
|
"@react-navigation/bottom-tabs": "^6.5.20",
|
||||||
"@react-navigation/native": "^6.1.17",
|
"@react-navigation/native": "^6.1.17",
|
||||||
|
"axios": "^1.7.2",
|
||||||
"expo": "~51.0.11",
|
"expo": "~51.0.11",
|
||||||
"expo-camera": "~15.0.10",
|
"expo-camera": "~15.0.10",
|
||||||
"expo-status-bar": "~1.12.1",
|
"expo-status-bar": "~1.12.1",
|
||||||
@@ -5997,6 +5998,29 @@
|
|||||||
"url": "https://github.com/sponsors/ljharb"
|
"url": "https://github.com/sponsors/ljharb"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/axios": {
|
||||||
|
"version": "1.7.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/axios/-/axios-1.7.2.tgz",
|
||||||
|
"integrity": "sha512-2A8QhOMrbomlDuiLeK9XibIBzuHeRcqqNOHp0Cyp5EoJ1IFDh+XZH3A6BkXtv0K4gFGCI0Y4BM7B1wOEi0Rmgw==",
|
||||||
|
"dependencies": {
|
||||||
|
"follow-redirects": "^1.15.6",
|
||||||
|
"form-data": "^4.0.0",
|
||||||
|
"proxy-from-env": "^1.1.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/axios/node_modules/form-data": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
|
||||||
|
"dependencies": {
|
||||||
|
"asynckit": "^0.4.0",
|
||||||
|
"combined-stream": "^1.0.8",
|
||||||
|
"mime-types": "^2.1.12"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 6"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/babel-core": {
|
"node_modules/babel-core": {
|
||||||
"version": "7.0.0-bridge.0",
|
"version": "7.0.0-bridge.0",
|
||||||
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
|
"resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz",
|
||||||
@@ -7853,6 +7877,25 @@
|
|||||||
"node": ">=0.4.0"
|
"node": ">=0.4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/follow-redirects": {
|
||||||
|
"version": "1.15.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
|
||||||
|
"integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "individual",
|
||||||
|
"url": "https://github.com/sponsors/RubenVerborgh"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=4.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"debug": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/fontfaceobserver": {
|
"node_modules/fontfaceobserver": {
|
||||||
"version": "2.3.0",
|
"version": "2.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz",
|
||||||
@@ -11549,6 +11592,11 @@
|
|||||||
"react-is": "^16.13.1"
|
"react-is": "^16.13.1"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/proxy-from-env": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||||
|
"integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="
|
||||||
|
},
|
||||||
"node_modules/pump": {
|
"node_modules/pump": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"@expo/vector-icons": "^14.0.2",
|
"@expo/vector-icons": "^14.0.2",
|
||||||
"@react-navigation/bottom-tabs": "^6.5.20",
|
"@react-navigation/bottom-tabs": "^6.5.20",
|
||||||
"@react-navigation/native": "^6.1.17",
|
"@react-navigation/native": "^6.1.17",
|
||||||
|
"axios": "^1.7.2",
|
||||||
"expo": "~51.0.11",
|
"expo": "~51.0.11",
|
||||||
"expo-camera": "~15.0.10",
|
"expo-camera": "~15.0.10",
|
||||||
"expo-status-bar": "~1.12.1",
|
"expo-status-bar": "~1.12.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user