Skip to content

Commit

Permalink
✨ Implement the two stage range after monitor process suggested by iOS
Browse files Browse the repository at this point in the history
Changes:
- in the monitor callback, launch the range call with the UUID that was found
- change the fake callback to call the range callback 500ms after the merge
  callback
- store the two results separately
- display the two results separately using different background colors
  • Loading branch information
shankari committed Mar 29, 2024
1 parent 022ccec commit 7c70840
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 12 deletions.
27 changes: 22 additions & 5 deletions www/js/bluetooth/BluetoothCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,17 +23,31 @@ const BluetoothCard = ({ device, isClassic, isScanningBLE }: Props) => {
bgColor = device.in_range ? `rgba(200,250,200,1)` : `rgba(250,200,200,1)`;
}

async function fakeCallback() {
async function fakeMonitorCallback() {
// If we don't do this, the results start accumulating in the device object
// first call, we put a result into the device
// second call, the device already has a result, so we put another one in...
const deviceWithoutResult = { ...device };
deviceWithoutResult.result = undefined;
deviceWithoutResult.monitorResult = undefined;
deviceWithoutResult.rangeResult = undefined;
window['cordova'].plugins.locationManager.getDelegate().didDetermineStateForRegion({
region: deviceWithoutResult,
eventType: 'didDetermineStateForRegion',
state: 'CLRegionStateInside',
});
let timer: ReturnType<typeof setTimeout> = setTimeout(fakeRangeCallback, 500);
}

async function fakeRangeCallback() {
// If we don't do this, the results start accumulating in the device object
// first call, we put a result into the device
// second call, the device already has a result, so we put another one in...
const deviceWithMajorMinor = { ...device, major: 1234, minor: 4567 };
window['cordova'].plugins.locationManager.getDelegate().didRangeBeaconsInRegion({
region: deviceWithMajorMinor,
eventType: 'didRangeBeaconsInRegion',
state: 'CLRegionStateInside',
});
}

return (
Expand All @@ -45,10 +59,13 @@ const BluetoothCard = ({ device, isClassic, isScanningBLE }: Props) => {
left={() => <List.Icon icon={device.in_range ? 'access-point' : 'access-point-off'} />}
/>
<Card.Content>
<Text style={{ borderColor: colors.primary }} variant="bodyMedium">
{device.result}
<Text style={{ backgroundColor: colors.primaryContainer }} variant="bodyMedium">
{device.monitorResult}
</Text>
<Text style={{ backgroundColor: colors.secondaryContainer }} variant="bodyMedium">
{device.rangeResult}
</Text>
<Button mode="elevated" onPress={fakeCallback}>
<Button mode="elevated" onPress={fakeMonitorCallback}>
Fake callback
</Button>
</Card.Content>
Expand Down
36 changes: 30 additions & 6 deletions www/js/bluetooth/BluetoothScanPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,17 +85,27 @@ const BluetoothScanPage = ({ ...props }: any) => {
}
}

function setRangeStatus(uuid: string, result: string, status: boolean) {
function setMonitorStatus(uuid: string, result: string, status: boolean) {
setSampleBLEDevices((prevDevices) => ({
...prevDevices,
[uuid]: {
...prevDevices[uuid],
result: result,
monitorResult: result,
in_range: status,
},
}));
}

function setRangeStatus(uuid: string, result: string) {
setSampleBLEDevices((prevDevices) => ({
...prevDevices,
[uuid]: {
...prevDevices[uuid],
rangeResult: result,
},
}));
}

// BLE LOGIC
async function startBeaconScanning() {
setIsScanningBLE(true);
Expand All @@ -108,15 +118,27 @@ const BluetoothScanPage = ({ ...props }: any) => {
const pluginResultStr = JSON.stringify(pluginResult, null, 2);
if (pluginResult.state == 'CLRegionStateInside') {
// need toUpperCase(), b/c callback returns with only lowercase values...
setRangeStatus(pluginResult.region.uuid.toUpperCase(), pluginResultStr, true);
setMonitorStatus(pluginResult.region.uuid.toUpperCase(), pluginResultStr, true);
} else if (pluginResult.state == 'CLRegionStateOutside') {
setRangeStatus(pluginResult.region.uuid.toUpperCase(), pluginResultStr, false);
setMonitorStatus(pluginResult.region.uuid.toUpperCase(), pluginResultStr, false);
}
logDebug('[BLE] didDetermineStateForRegion');
logDebug(pluginResultStr);
window['cordova'].plugins.locationManager.appendToDeviceLog(
'[DOM] didDetermineStateForRegion: ' + pluginResultStr,
);
const beaconRegion = new window['cordova'].plugins.locationManager.BeaconRegion(
STATIC_ID,
pluginResult.region.uuid,
pluginResult.region.major,
pluginResult.region.minor,
);
window['cordova'].plugins.locationManager
.startRangingBeaconsInRegion(beaconRegion)
.fail(function (e) {
logWarn(e);
})
.done();
};

delegate.didStartMonitoringForRegion = function (pluginResult) {
Expand All @@ -127,7 +149,9 @@ const BluetoothScanPage = ({ ...props }: any) => {
delegate.didRangeBeaconsInRegion = function (pluginResult) {
// Not seeing this called...
logDebug('[BLE] didRangeBeaconsInRegion');
logDebug(JSON.stringify(pluginResult));
const pluginResultStr = JSON.stringify(pluginResult, null, 2);
logDebug(pluginResultStr);
setRangeStatus(pluginResult.region.uuid.toUpperCase(), pluginResultStr);
};

window['cordova'].plugins.locationManager.setDelegate(delegate);
Expand Down Expand Up @@ -156,7 +180,7 @@ const BluetoothScanPage = ({ ...props }: any) => {
setIsScanningBLE(false);

beaconsToArray().forEach((sampleBeacon: BLEBeaconDevice) => {
setRangeStatus(sampleBeacon.uuid, false); // "zero out" the beacons
setMonitorStatus(sampleBeacon.uuid, false); // "zero out" the beacons
const beaconRegion = new window['cordova'].plugins.locationManager.BeaconRegion(
STATIC_ID,
sampleBeacon.uuid,
Expand Down
3 changes: 2 additions & 1 deletion www/js/types/BluetoothDevices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ export type BLEDeviceList = {
identifier: string;
minor: number;
major: number;
result: string;
monitorResult: string;
rangeResult: string;
in_range: boolean;
};
};
Expand Down

0 comments on commit 7c70840

Please sign in to comment.