Restored comments, and added share feature

This commit is contained in:
2024-07-07 16:38:44 +08:00
parent cdac16a723
commit 19a1230781
2 changed files with 65 additions and 13 deletions

View File

@@ -1,14 +1,16 @@
import React, { useEffect, useState } from 'react'; import React, { useEffect, useState } from 'react';
import { View, Text, StyleSheet, Image, TouchableOpacity, Modal } from 'react-native'; import { View, Text, StyleSheet, Image, TouchableOpacity, Modal, Share } from 'react-native';
import QRCode from 'react-native-qrcode-svg'; import QRCode from 'react-native-qrcode-svg';
import { Ionicons } from '@expo/vector-icons'; import { Ionicons } from '@expo/vector-icons';
// Define Props for ScannedDataBox component
interface ScannedDataBoxProps { interface ScannedDataBoxProps {
data: string; data: string;
dataType: string; dataType: string;
clearScanData: () => void; clearScanData: () => void;
} }
// Define ScanResult interface
interface ScanResult { interface ScanResult {
secureConnection: boolean; secureConnection: boolean;
virusTotalCheck: boolean; virusTotalCheck: boolean;
@@ -21,6 +23,7 @@ const ScannedDataBox: React.FC<ScannedDataBoxProps> = ({ data, dataType, clearSc
console.log("ScannedDataBox -> Data", data); console.log("ScannedDataBox -> Data", data);
console.log("DataType", dataType); console.log("DataType", dataType);
// Set scan result based on data
useEffect(() => { useEffect(() => {
// Assuming scanResult is directly related to data // Assuming scanResult is directly related to data
setScanResult({ setScanResult({
@@ -28,8 +31,10 @@ const ScannedDataBox: React.FC<ScannedDataBoxProps> = ({ data, dataType, clearSc
virusTotalCheck: !data.includes('danger'), // Example logic virusTotalCheck: !data.includes('danger'), // Example logic
redirects: data.includes('redirect') ? 1 : 0, // Example logic redirects: data.includes('redirect') ? 1 : 0, // Example logic
}); });
console.log("Scan result set:", scanResult);
}, [data]); }, [data]);
// Determine the result text based on scan result
const getResultText = () => { const getResultText = () => {
if (!scanResult) { if (!scanResult) {
return 'UNKNOWN'; return 'UNKNOWN';
@@ -43,6 +48,7 @@ const ScannedDataBox: React.FC<ScannedDataBoxProps> = ({ data, dataType, clearSc
} }
}; };
// Determine the result color based on result text
const getResultColor = () => { const getResultColor = () => {
const result = getResultText(); const result = getResultText();
if (result === 'DANGEROUS') { if (result === 'DANGEROUS') {
@@ -56,11 +62,26 @@ const ScannedDataBox: React.FC<ScannedDataBoxProps> = ({ data, dataType, clearSc
} }
}; };
// Handle sharing the data
const handleShare = async () => {
try {
await Share.share({
message: data,
});
console.log('Data shared:', data);
} catch (error) {
console.error('Error sharing the data:', error);
}
};
return ( return (
<View style={styles.dataBox}> <View style={styles.dataBox}>
{/* Close button */}
<TouchableOpacity style={styles.closeButton} onPress={clearScanData}> <TouchableOpacity style={styles.closeButton} onPress={clearScanData}>
<Ionicons name="close-circle-outline" size={18} color="#ff69b4" /> <Ionicons name="close-circle-outline" size={18} color="#ff69b4" />
</TouchableOpacity> </TouchableOpacity>
{/* Display scanned data */}
<View style={styles.row}> <View style={styles.row}>
<Image source={require('../assets/ScanIcon3.png')} style={styles.scan_icon} /> <Image source={require('../assets/ScanIcon3.png')} style={styles.scan_icon} />
<Text style={styles.payload}>{data}</Text> <Text style={styles.payload}>{data}</Text>
@@ -74,14 +95,20 @@ const ScannedDataBox: React.FC<ScannedDataBoxProps> = ({ data, dataType, clearSc
</Text> </Text>
</View> </View>
<View style={styles.divider} /> <View style={styles.divider} />
{/* Display data type */}
<Text style={styles.typeText}>Type: {dataType}</Text> <Text style={styles.typeText}>Type: {dataType}</Text>
<Text style={styles.blankLine}>{'\n'}</Text> <Text style={styles.blankLine}>{'\n'}</Text>
{/* Display scan checks */}
<Text style={styles.checksText}>Checks</Text> <Text style={styles.checksText}>Checks</Text>
<Text style={styles.checksText}>Secure Connection: {scanResult?.secureConnection ? '✔️' : '✘'}</Text> <Text style={styles.checksText}>Secure Connection: {scanResult?.secureConnection ? '✔️' : '✘'}</Text>
<Text style={styles.checksText}>Virus Total Check: {scanResult?.virusTotalCheck ? '✔️' : '✘'}</Text> <Text style={styles.checksText}>Virus Total Check: {scanResult?.virusTotalCheck ? '✔️' : '✘'}</Text>
<Text style={styles.checksText}>Redirects: {scanResult ? scanResult.redirects : 'N/A'}</Text> <Text style={styles.checksText}>Redirects: {scanResult ? scanResult.redirects : 'N/A'}</Text>
{/* Action buttons */}
<View style={styles.iconContainer}> <View style={styles.iconContainer}>
<TouchableOpacity style={styles.iconButton}> <TouchableOpacity style={styles.iconButton} onPress={handleShare}>
<Ionicons name="share-social" size={18} color="#2196F3" /> <Ionicons name="share-social" size={18} color="#2196F3" />
<Text style={styles.iconText}>Share</Text> <Text style={styles.iconText}>Share</Text>
</TouchableOpacity> </TouchableOpacity>
@@ -91,12 +118,16 @@ const ScannedDataBox: React.FC<ScannedDataBoxProps> = ({ data, dataType, clearSc
</TouchableOpacity> </TouchableOpacity>
</View> </View>
<View style={styles.divider} /> <View style={styles.divider} />
{/* More information button */}
<Text style={styles.moreInfoText}>More Information</Text> <Text style={styles.moreInfoText}>More Information</Text>
<TouchableOpacity style={styles.moreInfoButton} onPress={() => setIsModalVisible(true)}> <TouchableOpacity style={styles.moreInfoButton} onPress={() => setIsModalVisible(true)}>
<Ionicons name="shield-checkmark" size={18} color="#ff69b4" /> <Ionicons name="shield-checkmark" size={18} color="#ff69b4" />
<Text style={styles.moreInfoButtonText}>Security Headers</Text> <Text style={styles.moreInfoButtonText}>Security Headers</Text>
<Ionicons name="chevron-forward" size={18} color="#ff69b4" /> <Ionicons name="chevron-forward" size={18} color="#ff69b4" />
</TouchableOpacity> </TouchableOpacity>
{/* Modal for security headers */}
<Modal <Modal
visible={isModalVisible} visible={isModalVisible}
transparent={true} transparent={true}

View File

@@ -1,15 +1,20 @@
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert } from 'react-native'; import { View, Text, StyleSheet, ActivityIndicator, TouchableOpacity, Alert, Image } from 'react-native';
import { Camera, CameraView, scanFromURLAsync } from 'expo-camera'; import { Camera, CameraView, scanFromURLAsync } from 'expo-camera';
import { useDispatch } from 'react-redux';
import axios from 'axios'; // For URL calls import axios from 'axios'; // For URL calls
import { Ionicons } from '@expo/vector-icons'; // For icons import { Ionicons } from '@expo/vector-icons'; // For icons
import { useNavigation } from '@react-navigation/native'; import { useNavigation } from '@react-navigation/native';
import * as ImagePicker from 'expo-image-picker'; import * as ImagePicker from 'expo-image-picker';
import ScannedDataBox from '../components/ScannedDataBox'; import ScannedDataBox from '../components/ScannedDataBox';
import { useDispatch } from 'react-redux';
import { addQRCode } from '../actions/qrCodeActions'; import { addQRCode } from '../actions/qrCodeActions';
const QRScannerScreen: React.FC = () => { interface QRScannerScreenProps {
clearScanData: () => void;
}
// Main Function
const QRScannerScreen: React.FC<QRScannerScreenProps> = ({ clearScanData }) => {
const navigation = useNavigation(); // call Navigation bar const navigation = useNavigation(); // call Navigation bar
const [showSplash, setShowSplash] = useState<boolean>(true); // call splash screen const [showSplash, setShowSplash] = useState<boolean>(true); // call splash screen
const dispatch = useDispatch(); const dispatch = useDispatch();
@@ -20,45 +25,52 @@ const QRScannerScreen: React.FC = () => {
const [dataType, setDataType] = useState<string>(''); // State for data type const [dataType, setDataType] = useState<string>(''); // State for data type
const [enableTorch, setEnableTorch] = useState<boolean>(false); // State for torch const [enableTorch, setEnableTorch] = useState<boolean>(false); // State for torch
// Request Camera Permission and initialize the app
useEffect(() => { useEffect(() => {
const initializeApp = async () => { const initializeApp = async () => {
const { status } = await Camera.requestCameraPermissionsAsync(); const { status } = await Camera.requestCameraPermissionsAsync();
setHasPermission(status === 'granted'); setHasPermission(status === 'granted');
setShowSplash(false); setShowSplash(false);
console.log("Camera permissions initialized");
}; };
initializeApp(); initializeApp();
}, []); }, []);
// Clear Scan Data
const clearScanDataInternal = () => { const clearScanDataInternal = () => {
setScannedData(''); setScannedData('');
setScanned(false); setScanned(false);
setDataType(''); setDataType('');
console.log("Scan data cleared");
}; };
// Handle QR Code Payload
const handlePayload = async (payload: string) => { const handlePayload = async (payload: string) => {
setScanned(true); setScanned(true);
console.log("Scanning Competed payload is :", payload); console.log("Scanning Completed. Payload is:", payload);
const type = await sendToAPIServer(payload); const type = await sendToAPIServer(payload);
const qrCode = { const qrCode = {
data: payload, data: payload,
type, type,
bookmarked: false,
scanResult: { scanResult: {
secureConnection: true, // Placeholder, replace with actual logic secureConnection: true, // Placeholder, replace with actual logic
virusTotalCheck: true, // Placeholder, replace with actual logic virusTotalCheck: true, // Placeholder, replace with actual logic
redirects: 0 // Placeholder, replace with actual logic redirects: 0 // Placeholder, replace with actual logic
} },
bookmarked: false, // Add the bookmarked property
}; };
setScannedData(payload); setScannedData(payload);
console.log("handlePayload -> payload", payload); console.log("Payload received:", payload);
console.log("handlePayload -> type", type); console.log("Type received from server:", type);
setDataType(type); setDataType(type);
dispatch(addQRCode(qrCode)); dispatch(addQRCode(qrCode)); // Dispatch action to save QR code data
console.log("QR code data added to history");
}; };
// Send QR Code Data to Backend Server
const sendToAPIServer = async (payload: string): Promise<string> => { const sendToAPIServer = async (payload: string): Promise<string> => {
console.log('Sending QR code data to backend:', payload); console.log('Sending QR code data to backend:', payload);
@@ -78,17 +90,23 @@ const QRScannerScreen: React.FC = () => {
} }
}; };
// Toggle Torch (Flashlight)
const toggleTorch = () => { const toggleTorch = () => {
setEnableTorch((prev) => !prev); setEnableTorch((prev) => !prev);
console.log("Torch toggled:", enableTorch ? "off" : "on");
}; };
// Handle Test Scan
const handleTestScan = () => { const handleTestScan = () => {
handlePayload('TEST123'); handlePayload('TEST123');
console.log("Test scan executed");
}; };
// Read QR Code from Image
const readQRFromImage = async () => { const readQRFromImage = async () => {
clearScanDataInternal(); clearScanDataInternal();
console.log("readingQRFromImage"); console.log("Reading QR code from image");
const result = await ImagePicker.launchImageLibraryAsync({ const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ImagePicker.MediaTypeOptions.Images, mediaTypes: ImagePicker.MediaTypeOptions.Images,
allowsEditing: false, // Don't ask user to crop images allowsEditing: false, // Don't ask user to crop images
@@ -101,10 +119,11 @@ const QRScannerScreen: React.FC = () => {
if (scannedResult && scannedResult[0] && scannedResult[0].data) { if (scannedResult && scannedResult[0] && scannedResult[0].data) {
handlePayload(scannedResult[0].data); handlePayload(scannedResult[0].data);
// Not sure why scannedResult.data is undefined but access as array work, KIV // Not sure why scannedResult.data is undefined but access as array work, KIV
console.log('readingQRFromImage -> scannedResult[0].data:', scannedResult[0].data); console.log('QR code data from image:', scannedResult[0].data);
} else { } else {
setScannedData("No QR Code Found"); setScannedData("No QR Code Found");
setTimeout(() => setScannedData(""), 4000); setTimeout(() => setScannedData(""), 4000);
console.log("No QR code found in the selected image");
} }
} catch (error) { } catch (error) {
console.error('Error scanning QR code from image:', error); console.error('Error scanning QR code from image:', error);
@@ -113,9 +132,11 @@ const QRScannerScreen: React.FC = () => {
} }
}; };
// Clear scan data when screen is focused
useEffect(() => { useEffect(() => {
const unsubscribe = navigation.addListener('focus', () => { const unsubscribe = navigation.addListener('focus', () => {
clearScanDataInternal(); clearScanDataInternal();
console.log("Screen focused, scan data cleared");
}); });
return unsubscribe; return unsubscribe;
}, [navigation]); }, [navigation]);