Fixed HistoryScreen where data not shown on flatlist, and pass type to scannedDataBox properly
This commit is contained in:
@@ -3,12 +3,14 @@ import { View, Text, StyleSheet, Image, TouchableOpacity, Modal } from 'react-na
|
|||||||
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;
|
||||||
@@ -18,18 +20,21 @@ interface ScanResult {
|
|||||||
const ScannedDataBox: React.FC<ScannedDataBoxProps> = ({ data, dataType, clearScanData }) => {
|
const ScannedDataBox: React.FC<ScannedDataBoxProps> = ({ data, dataType, clearScanData }) => {
|
||||||
const [scanResult, setScanResult] = useState<ScanResult | null>(null);
|
const [scanResult, setScanResult] = useState<ScanResult | null>(null);
|
||||||
const [isModalVisible, setIsModalVisible] = useState(false);
|
const [isModalVisible, setIsModalVisible] = useState(false);
|
||||||
console.log("ScannedDataBox -> Data", data);
|
|
||||||
console.log("DataType", dataType);
|
|
||||||
|
|
||||||
|
console.log("ScannedDataBox -> Data:", data);
|
||||||
|
console.log("DataType:", dataType);
|
||||||
|
|
||||||
|
// Set scan result based on data
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Assuming scanResult is directly related to data
|
|
||||||
setScanResult({
|
setScanResult({
|
||||||
secureConnection: data.includes('https'), // Example logic
|
secureConnection: data.includes('https'), // Example logic
|
||||||
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') {
|
||||||
@@ -58,9 +64,12 @@ const ScannedDataBox: React.FC<ScannedDataBoxProps> = ({ data, dataType, clearSc
|
|||||||
|
|
||||||
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,12 +83,18 @@ 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}>
|
||||||
<Ionicons name="share-social" size={18} color="#2196F3" />
|
<Ionicons name="share-social" size={18} color="#2196F3" />
|
||||||
@@ -91,12 +106,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}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ const HistoryScreen: React.FC = () => {
|
|||||||
|
|
||||||
const [selectedData, setSelectedData] = useState<string | null>(null);
|
const [selectedData, setSelectedData] = useState<string | null>(null);
|
||||||
const [selectedScanResult, setSelectedScanResult] = useState<any | null>(null);
|
const [selectedScanResult, setSelectedScanResult] = useState<any | null>(null);
|
||||||
|
const [selectedType, setSelectedType] = useState<string | null>(null); // Add state for selectedType
|
||||||
const [showBookmarks, setShowBookmarks] = useState<boolean>(false);
|
const [showBookmarks, setShowBookmarks] = useState<boolean>(false);
|
||||||
const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
|
const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
|
||||||
const [indexToDelete, setIndexToDelete] = useState<number | null>(null);
|
const [indexToDelete, setIndexToDelete] = useState<number | null>(null);
|
||||||
@@ -21,6 +22,7 @@ const HistoryScreen: React.FC = () => {
|
|||||||
if (selectedData) {
|
if (selectedData) {
|
||||||
setSelectedData(null);
|
setSelectedData(null);
|
||||||
setSelectedScanResult(null);
|
setSelectedScanResult(null);
|
||||||
|
setSelectedType(null);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@@ -39,6 +41,7 @@ const HistoryScreen: React.FC = () => {
|
|||||||
const originalIndex = prev.length - 1 - index; // Compute the original index
|
const originalIndex = prev.length - 1 - index; // Compute the original index
|
||||||
const newQrCodes = [...prev];
|
const newQrCodes = [...prev];
|
||||||
newQrCodes[originalIndex].bookmarked = !newQrCodes[originalIndex].bookmarked;
|
newQrCodes[originalIndex].bookmarked = !newQrCodes[originalIndex].bookmarked;
|
||||||
|
console.log('Toggled bookmark for QR code at index:', originalIndex);
|
||||||
return newQrCodes;
|
return newQrCodes;
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -47,6 +50,7 @@ const HistoryScreen: React.FC = () => {
|
|||||||
if (indexToDelete !== null) {
|
if (indexToDelete !== null) {
|
||||||
setQrCodes((prev: QRCode[]) => {
|
setQrCodes((prev: QRCode[]) => {
|
||||||
const originalIndex = prev.length - 1 - indexToDelete; // Compute the original index
|
const originalIndex = prev.length - 1 - indexToDelete; // Compute the original index
|
||||||
|
console.log('Deleting QR code at index:', originalIndex);
|
||||||
return prev.filter((_, i) => i !== originalIndex);
|
return prev.filter((_, i) => i !== originalIndex);
|
||||||
});
|
});
|
||||||
setIndexToDelete(null);
|
setIndexToDelete(null);
|
||||||
@@ -59,20 +63,26 @@ const HistoryScreen: React.FC = () => {
|
|||||||
const handleItemPress = (item: any) => {
|
const handleItemPress = (item: any) => {
|
||||||
setSelectedData(item.data);
|
setSelectedData(item.data);
|
||||||
setSelectedScanResult(item.scanResult);
|
setSelectedScanResult(item.scanResult);
|
||||||
|
setSelectedType(item.type); // Set the selected type
|
||||||
|
console.log('Selected QR code data:', item.data);
|
||||||
|
console.log('Selected QR code type:', item.type);
|
||||||
};
|
};
|
||||||
|
|
||||||
const confirmDelete = (index: number) => {
|
const confirmDelete = (index: number) => {
|
||||||
setIndexToDelete(index);
|
setIndexToDelete(index);
|
||||||
setIsModalVisible(true);
|
setIsModalVisible(true);
|
||||||
|
console.log('Confirm delete for QR code at index:', index);
|
||||||
};
|
};
|
||||||
|
|
||||||
const clearSelectedData = () => {
|
const clearSelectedData = () => {
|
||||||
setSelectedData(null);
|
setSelectedData(null);
|
||||||
setSelectedScanResult(null);
|
setSelectedScanResult(null);
|
||||||
|
setSelectedType(null); // Clear the selected type
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
|
{/* Header for toggling between History and Bookmarks */}
|
||||||
<View style={styles.headerContainer}>
|
<View style={styles.headerContainer}>
|
||||||
<TouchableOpacity onPress={() => setShowBookmarks(false)}>
|
<TouchableOpacity onPress={() => setShowBookmarks(false)}>
|
||||||
<Text style={!showBookmarks ? styles.headerTextActive : styles.headerTextInactive}>History</Text>
|
<Text style={!showBookmarks ? styles.headerTextActive : styles.headerTextInactive}>History</Text>
|
||||||
@@ -81,16 +91,18 @@ const HistoryScreen: React.FC = () => {
|
|||||||
<Text style={showBookmarks ? styles.headerTextActive : styles.headerTextInactive}>Bookmarks</Text>
|
<Text style={showBookmarks ? styles.headerTextActive : styles.headerTextInactive}>Bookmarks</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
|
{/* Display scanned data details */}
|
||||||
{selectedData && (
|
{selectedData && (
|
||||||
<View style={styles.scannedDataBoxContainer}>
|
<View style={styles.scannedDataBoxContainer}>
|
||||||
<ScannedDataBox data={selectedData} scanResult={selectedScanResult} dataType="URL" clearScanData={clearSelectedData} />
|
<ScannedDataBox data={selectedData} scanResult={selectedScanResult} dataType={selectedType} clearScanData={clearSelectedData} />
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
|
{/* List of QR codes */}
|
||||||
<FlatList
|
<FlatList
|
||||||
data={filteredQrCodes}
|
data={filteredQrCodes}
|
||||||
renderItem={({ item, index }) => {
|
renderItem={({ item, index }) => {
|
||||||
console.log('item:', item); // Log the item data for debugging
|
console.log('Rendering QR code item:', item);
|
||||||
const itemData = item.data ? item.data.split('\n')[1]?.split('Data: ')[1] : 'Invalid data';
|
const itemData = item.data;
|
||||||
return (
|
return (
|
||||||
<View style={styles.itemContainer}>
|
<View style={styles.itemContainer}>
|
||||||
<View style={styles.itemLeft}>
|
<View style={styles.itemLeft}>
|
||||||
@@ -116,6 +128,7 @@ const HistoryScreen: React.FC = () => {
|
|||||||
keyExtractor={(item, index) => index.toString()}
|
keyExtractor={(item, index) => index.toString()}
|
||||||
contentContainerStyle={styles.flatListContent}
|
contentContainerStyle={styles.flatListContent}
|
||||||
/>
|
/>
|
||||||
|
{/* Modal for delete confirmation */}
|
||||||
<Modal
|
<Modal
|
||||||
transparent={true}
|
transparent={true}
|
||||||
visible={isModalVisible}
|
visible={isModalVisible}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ 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';
|
||||||
|
|
||||||
|
// Main Function
|
||||||
const QRScannerScreen: React.FC = () => {
|
const QRScannerScreen: React.FC = () => {
|
||||||
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
|
||||||
@@ -21,24 +22,30 @@ 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 Completed. Payload is:", payload);
|
||||||
const type = await sendToAPIServer(payload);
|
const type = await sendToAPIServer(payload);
|
||||||
|
|
||||||
const qrCode = {
|
const qrCode = {
|
||||||
@@ -52,18 +59,20 @@ const QRScannerScreen: React.FC = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
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);
|
||||||
setQrCodes([...qrCodes, qrCode]);
|
setQrCodes([...qrCodes, qrCode]);
|
||||||
|
console.log("QR code data added to history");
|
||||||
};
|
};
|
||||||
|
|
||||||
const sendToAPIServer = async (data: string): Promise<string> => {
|
// Send QR Code Data to Backend Server
|
||||||
console.log('Sending QR code data to backend:', data);
|
const sendToAPIServer = async (payload: string): Promise<string> => {
|
||||||
|
console.log('Sending QR code data to backend:', payload);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await axios.post('http://192.168.10.247:8080/v1/api/qrcodetypes/detect', {
|
const response = await axios.post('http://192.168.10.247:8080/v1/api/qrcodetypes/detect', {
|
||||||
data,
|
data: payload,
|
||||||
}, {
|
}, {
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
@@ -77,17 +86,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
|
||||||
@@ -100,10 +115,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);
|
||||||
@@ -112,9 +128,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]);
|
||||||
|
|||||||
Reference in New Issue
Block a user