import React from 'react';
import {Alert, StyleSheet, Button, Switch, ScrollView} from 'react-native';
import {ThemedText} from '@/components/themed-text';
import {ThemedView} from '@/components/themed-view';
import {useBleExplorer} from '@/hooks/useBleExplorer';
import {useBlePeripheral} from '@/hooks/useBlePeripheral';
import {BLE_UUIDS, PROTOCOL_VERSION} from '@/ble';
import ParallaxScrollView from '@/components/parallax-scroll-view';
import {IconSymbol} from '@/components/ui/icon-symbol';
export default function TabTwoScreen() {
const [deviceMode, setDeviceMode] = React.useState<'central' | 'peripheral'>('central');
const {
isScanning,
isConnected,
connectedDevice,
deviceInfo,
version,
isActivated,
transferProgress,
isTransferring,
discoveredDevices,
loading,
error,
startScan,
stopScan,
connectToDevice,
disconnectDevice,
queryActivationStatus,
queryDeviceVersion,
requestDeviceInfo,
updateActivationTime,
sendIdentityCheck,
transferSampleFile,
clearLogs,
} = useBleExplorer();
const {
isAdvertising,
connectedCentralCount,
logs: peripheralLogs,
deviceInfo: peripheralDeviceInfo,
loading: peripheralLoading,
error: peripheralError,
startAdvertising,
stopAdvertising,
getCharacteristicReadValue,
updateDeviceInfo,
resetDeviceInfo,
clearLogs: clearPeripheralLogs,
} = useBlePeripheral();
return (
}>
BLE Explorer
{/* Device Mode Selection */}
Device Mode
Central
{
if (value) {
// Switching to peripheral mode - stop central operations first
console.log('Switching to peripheral mode - stopping central operations');
if (isScanning) {
await stopScan();
// Add small delay to ensure cleanup
await new Promise(resolve => setTimeout(resolve, 500));
}
if (isConnected) {
await disconnectDevice();
// Add small delay to ensure cleanup
await new Promise(resolve => setTimeout(resolve, 500));
}
} else {
// Switching to central mode - stop peripheral operations first
console.log('Switching to central mode - stopping peripheral operations');
if (isAdvertising) {
await stopAdvertising();
// Add small delay to ensure cleanup
await new Promise(resolve => setTimeout(resolve, 500));
}
}
setDeviceMode(value ? 'peripheral' : 'central');
}}
disabled={isScanning || isConnected || isAdvertising || peripheralLoading.advertising}
/>
Peripheral
{deviceMode === 'central'
? 'Central mode: Scan for and connect to BLE peripherals'
: `Peripheral mode: Act as BLE receiver`}
{deviceMode === 'central' ? (
<>
{/* Connection Status */}
Connection Status
Scanning: {isScanning ? 'Yes' : 'No'}
Connected: {isConnected ? 'Yes' : 'No'}
Device: {connectedDevice?.name || 'None'}
{error && Error: {error}}
{/* Discovered Devices */}
Discovered Devices
Total devices
found: {discoveredDevices.length}
{discoveredDevices.length === 0 ? (
No devices discovered yet. Start scanning to find devices.
) : (
{discoveredDevices.map((item) => (
{item.name || 'Unknown Device'}
{item.id}
{item.serviceUUIDs && item.serviceUUIDs.length > 0 && (
Services: {item.serviceUUIDs.join(', ')}
)}
{item.connected && (
Connected
)}
))}
)}
{/* Device Info */}
Device Information
Activated: {isActivated ? 'Yes' : 'No'}
Version: {version || 'Unknown'}
{deviceInfo && (
<>
Name: {deviceInfo.devname}
Total Space: {deviceInfo.allspace} KB
Free Space: {deviceInfo.freespace} KB
Brand: {deviceInfo.brand}
>
)}
{/* Transfer Status */}
File Transfer
Transferring: {isTransferring ? 'Yes' : 'No'}
Progress: {transferProgress}%
{/* Control Buttons */}
Controls
>
) : (
<>
{/* Peripheral Status */}
Peripheral Status
Advertising: {isAdvertising ? 'Yes' : 'No'}
Connected Centrals: {connectedCentralCount}
{peripheralError && Error: {peripheralError}}
{/* Device Information */}
Device Information
Activated: {peripheralDeviceInfo.activated ? 'Yes' : 'No'}
Version: {peripheralDeviceInfo.version || 'Unknown'}
Name: {peripheralDeviceInfo.devname || 'Unknown Device'}
Total Space: {peripheralDeviceInfo.allspace || 0} KB
Free Space: {peripheralDeviceInfo.freespace || 0} KB
Brand: {peripheralDeviceInfo.brand || 'Unknown'}
{/* Peripheral Controls */}
Peripheral Controls
getCharacteristicReadValue(BLE_UUIDS.READ_CHARACTERISTIC)}
disabled={!isAdvertising}
/>
updateDeviceInfo({activated: !(peripheralDeviceInfo.activated ?? false)})}/>
updateDeviceInfo({freespace: Math.floor(Math.random() * 1024)})}/>
{/* Peripheral Logs */}
Peripheral Logs
{peripheralLogs.map((log, index) => (
{log}
))}
>
)}
{/* Protocol Info - Available in both modes */}
Protocol Information
Version: {PROTOCOL_VERSION}
Service UUID: {BLE_UUIDS.SERVICE}
Write UUID: {BLE_UUIDS.WRITE_CHARACTERISTIC}
Read UUID: {BLE_UUIDS.READ_CHARACTERISTIC}
);
}
const styles = StyleSheet.create({
headerImage: {
color: '#808080',
bottom: -90,
left: -35,
position: 'absolute',
},
titleContainer: {
flexDirection: 'row',
gap: 8,
},
section: {
gap: 8,
marginBottom: 8,
},
buttonRow: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 8,
gap: 8,
},
logHeader: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
marginBottom: 8,
},
logContainer: {
maxHeight: 200,
padding: 8,
borderRadius: 4,
},
logText: {
fontSize: 12,
marginBottom: 2,
},
deviceItem: {
padding: 12,
marginBottom: 8,
borderRadius: 8,
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
},
deviceInfo: {
flex: 1,
marginRight: 12,
},
deviceId: {
fontSize: 12,
opacity: 0.7,
},
deviceCount: {
fontSize: 14,
opacity: 0.8,
marginTop: 4,
marginBottom: 8,
fontWeight: '500',
},
serviceUuids: {
fontSize: 11,
opacity: 0.6,
marginTop: 2,
fontStyle: 'italic',
},
connectionStatus: {
fontSize: 12,
fontWeight: 'bold',
marginTop: 4,
},
connectedDevice: {
borderWidth: 1,
borderColor: '#4CAF50',
},
connectedDeviceText: {
fontWeight: 'bold',
},
errorText: {
marginTop: 8,
fontWeight: 'bold',
},
modeSwitchContainer: {
flexDirection: 'row',
alignItems: 'center',
justifyContent: 'center',
marginVertical: 12,
},
modeLabel: {
fontSize: 16,
marginHorizontal: 8,
},
modeDescription: {
fontSize: 12,
opacity: 0.7,
marginTop: 8,
},
});