Skip to content

Commit

Permalink
Merge pull request #19 from shankari/final_ui_fixes
Browse files Browse the repository at this point in the history
Final ui fixes
shankari authored Apr 6, 2020
2 parents 98205e4 + 7c0dcda commit 9500b79
Showing 6 changed files with 75 additions and 116 deletions.
2 changes: 1 addition & 1 deletion config.cordovabuild.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version='1.0' encoding='utf-8'?>
<widget android-versionCode="2" id="edu.berkeley.eecs.covid19" ios-CFBundleVersion="2" version="0.0.3" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<widget android-versionCode="3" id="edu.berkeley.eecs.covid19" ios-CFBundleVersion="3" version="0.0.4" xmlns="http://www.w3.org/ns/widgets" xmlns:android="http://schemas.android.com/apk/res/android" xmlns:cdv="http://cordova.apache.org/ns/1.0">
<name>cv-19-track</name>
<description>
Travel pattern tracker for COVID-19 risk estimation.
2 changes: 1 addition & 1 deletion package.cordovabuild.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "edu.berkeley.eecs.covid19",
"version": "0.0.3",
"version": "0.0.4",
"displayName": "cv-19-track",
"scripts": {
"setup-serve": "./bin/download_settings_controls.js",
Original file line number Diff line number Diff line change
@@ -10,10 +10,9 @@ import org.json.*

class ContactTracing : CordovaPlugin() {

private var scanContext: CallbackContext? = null
private var adContext: CallbackContext? = null
private var cenScanner: CENScanner? = null
private var cenAdvertiser: CENAdvertiser? = null
private var inMemoryCache: MutableList<JSONObject>? = mutableListOf();

@Throws(JSONException::class)
override fun execute(action: String, args: JSONArray, context: CallbackContext): Boolean {
@@ -43,39 +42,27 @@ class ContactTracing : CordovaPlugin() {
try {
when ( action ) {
"startScanner" -> {
scanContext?.let{ throw Exception( "Scanner is already started" ) }
scanContext = context
try { uuid = UUID.fromString( args.getString(0) ) } catch (e: Exception) { }
cenScanner!!.startScanning( arrayOf( uuid ), args.getLong(1) ?: 10 )
result.setKeepCallback( true )
context.sendPluginResult( result )
context.success();
}
"stopScanner" -> {
scanContext ?: throw Exception( "Scanner is already stopped" )
try { uuid = UUID.fromString( args.getString(0) ) } catch (e: Exception) { }
cenScanner!!.stopScanning()
scanContext!!.sendPluginResult( result )
scanContext = null
context.success()
context.success();
}
"startAdvertiser" -> {
adContext?.let{ throw Exception( "Advertiser is already started" ) }
adContext = context
try { uuid = UUID.fromString( args.getString(0) ) } catch (e: Exception) { }
cenAdvertiser!!.startAdvertiser( uuid )
result.setKeepCallback( true )
context.sendPluginResult( result )
context.success();
}
"stopAdvertiser" -> {
adContext ?: throw Exception( "Advertiser is already stopped" )
try { uuid = UUID.fromString( args.getString(0) ) } catch (e: Exception) { }
cenAdvertiser!!.stopAdvertiser()
adContext!!.sendPluginResult( result )
adContext = null
context.success()
context.success();
}
"updateCEN" -> {
adContext ?: throw Exception( "Advertiser must be started first" )
cenAdvertiser!!.updateCEN()
context.success()
context.success(JSONArray(inMemoryCache));
}
else -> throw Exception( "Invalid Action" )
}
@@ -89,23 +76,21 @@ class ContactTracing : CordovaPlugin() {

inner class ScanCENHandler : CENHandler {
override fun handleCEN(cen: CEN) {
scanContext ?: return
val contactEvent = JSONObject()
contactEvent.put( "cen", cen.toUUID().toString() )
val result = PluginResult(PluginResult.Status.OK, contactEvent)
result.setKeepCallback(true);
scanContext!!.sendPluginResult(result)
contactEvent.put( "number", cen.toUUID().toString() )
contactEvent.put( "ts", System.currentTimeMillis()/1000)
contactEvent.put( "type", "scan")
inMemoryCache!!.add(contactEvent);
}
}

inner class AdCENHandler : CENHandler {
override fun handleCEN(cen: CEN) {
adContext ?: return
val contactEvent = JSONObject()
contactEvent.put( "cen", cen.toUUID().toString() )
val result = PluginResult(PluginResult.Status.OK, contactEvent)
result.setKeepCallback(true);
adContext!!.sendPluginResult(result)
contactEvent.put( "number", cen.toUUID().toString() )
contactEvent.put( "ts", System.currentTimeMillis()/1000)
contactEvent.put("type", "advertise");
inMemoryCache!!.add(contactEvent);
}
}

72 changes: 43 additions & 29 deletions www/js/bluetooth/list.js
Original file line number Diff line number Diff line change
@@ -12,45 +12,59 @@ angular
zoomAnimation: true, touchZoom: false, scrollWheelZoom: false,
doubleClickZoom: false, boxZoom: false } } );

var startScanningContactEvents = _ => {
$scope.data = [];
var startScanPromise =
$window.cordova.plugins.contacttracing.startScanner( null, 10)
.then(ce => logContactEvent( ce, false ))
.catch(e => console.error( 'SCAN', e ));
var startAdvPromise =
$window.cordova.plugins.contacttracing.startAdvertiser( null )
.then( ce => logContactEvent( ce, true ))
.catch( e => console.error( 'AD', e ));

return Promise.all([startScanPromise, startAdvPromise]) .then(_ => {
Logger.log("successfully started scanning, launching CEN update");
$scope.update = $window.setInterval( $window.cordova.plugins.contacttracing.updateCEN,
60000 );
});
$scope.startAdvertiser = _ => {
$window.cordova.plugins.contacttracing.startAdvertiser( null )
.catch(err => Logger.displayError("Error while starting advertise", err));
}

var stopScanningContactEvents = _ => {
var stopScanPromise = $window.cordova.plugins.contacttracing.stopScanner();
var stopAdvPromise = $window.cordova.plugins.contacttracing.stopAdvertiser();
return Promise.all([stopScanPromise, stopAdvPromise]).then(_ => {
Logger.log("successfully stopped scanning");
console.log("About to clear interval" + $scope.update);
}).catch(err => {
Logger.displayError("stopping scan errored", err);
console.log("About to clear interval" + $scope.update);
});
$scope.stopAdvertiser = _ => {
$window.cordova.plugins.contacttracing.stopAdvertiser()
.catch(err => Logger.displayError("Error while stopping advertise", err));
}

$scope.refresh = _ => {
$scope.startScan = _ => {
$window.cordova.plugins.contacttracing.startScanner( null, 10 )
.catch(err => Logger.displayError("Error while starting scan", err));
}

$scope.stopScan = _ => {
$window.cordova.plugins.contacttracing.stopScanner()
.catch(err => Logger.displayError("Error while stopping scan", err));
}

$scope.pullRefresh = _ => {
if ($ionicScrollDelegate.getScrollPosition().top < 20) {
stopScanningContactEvents().then(startScanningContactEvents());
$scope.refresh();
return true;
}
}

$scope.formatTime = (ts_in_secs) => moment(ts_in_secs * 1000).format('LT')

$scope.refresh = _ => {
console.log("About to refresh CEN list");
$window.cordova.plugins.contacttracing.updateCEN().then(cenList => {
Logger.log("Retrieved list of size "+cenList.length);
$scope.$apply(_ => {
$scope.data = cenList.map(cen => {
if(cen.type == "advertise") {
cen.ad = true;
} else {
cen.ad = false;
}
return cen;
});;
});
}).catch(err => Logger.displayError("Error refreshing", err));
}

var logContactEvent = ( ce, ad ) => $scope.data.push(
{ time: new Date().toLocaleTimeString(), number: ce.cen.toUpperCase(), ad }
);

// $ionicPlatform.ready().then( startScanningContactEvents() );
$ionicPlatform.ready().then( $scope.update = $window.setInterval(
$scope.refresh(), 60000 ) );

$ionicPlatform.ready().then( $scope.testPeriodic = $window.setInterval(
console.log("Periodic call"), 60000 ) );
});
56 changes: 4 additions & 52 deletions www/js/services.js
Original file line number Diff line number Diff line change
@@ -179,61 +179,13 @@ angular.module('emission.services', ['emission.plugin.logger',
}
})
.service('UnifiedDataLoader', function($window, CommHelper, Logger) {
var combineWithDedup = function(list1, list2) {
var combinedList = list1.concat(list2);
return combinedList.filter(function(value, i, array) {
var firstIndexOfValue = array.findIndex(function(element, index, array) {
return element.metadata.write_ts == value.metadata.write_ts;
});
return firstIndexOfValue == i;
});
};

// TODO: generalize to iterable of promises
var combinedPromise = function(localPromise, remotePromise, combiner) {
return new Promise(function(resolve, reject) {
var localResult = [];
var localError = null;

var remoteResult = [];
var remoteError = null;

var localPromiseDone = false;
var remotePromiseDone = false;

var checkAndResolve = function() {
if (localPromiseDone && remotePromiseDone) {
// time to return from this promise
if (localError && remoteError) {
reject([localError, remoteError]);
} else {
Logger.log("About to dedup localResult = "+localResult.length
+"remoteResult = "+remoteResult.length);
var dedupedList = combiner(localResult, remoteResult);
Logger.log("Deduped list = "+dedupedList.length);
resolve(dedupedList);
}
}
};
return localPromise;
}

localPromise.then(function(currentLocalResult) {
localResult = currentLocalResult;
localPromiseDone = true;
}, function(error) {
localResult = [];
localError = error;
localPromiseDone = true;
}).then(checkAndResolve);

remotePromise.then(function(currentRemoteResult) {
remoteResult = currentRemoteResult;
remotePromiseDone = true;
}, function(error) {
remoteResult = [];
remoteError = error;
remotePromiseDone = true;
}).then(checkAndResolve);
})
var combineWithDedup = function(list1, list2) {
return list1;
}

// TODO: Generalize this to work for both sensor data and messages
12 changes: 10 additions & 2 deletions www/templates/bluetooth/list.html
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
<ion-view view-title="{{ 'bluetooth.title' | translate }}" ng-class="ion-view-background" translate-namespace="bluetooth">
<ion-view ng-class="ion-view-background" translate-namespace="bluetooth">
<ion-nav-buttons side="right">
<button class="button button-icon ion-refresh" ng-click="refresh()"></button>
<button class="button button-icon ion-play" ng-click="startScan()"></button>
Scan
<button class="button button-icon ion-stop" ng-click="stopScan()"></button>
</ion-nav-buttons>
<ion-nav-buttons side="left">
<button class="button button-icon ion-play" ng-click="startAdvertiser()"></button>
Advertise
<button class="button button-icon ion-stop" ng-click="stopAdvertiser()"></button>
</ion-nav-buttons>

<div style="background-color:transparent; border-left-style:solid; border-left-width:.5px; border-left-color:#212121; margin-left:10%; position:absolute; float:left; height:100%"></div>
@@ -9,7 +17,7 @@
<ion-refresher pulling-text="{{ 'pull-to-refresh' | translate }}" on-refresh="refresh()"></ion-refresher>
<ion-list>
<div collection-repeat="cen in data" style="margin-top:16px">
<div class="start-time-tag" style="top:20px; {{ cen.ad ? 'background:#ddd' : '' }}">{{ cen.time }}</div>
<div class="start-time-tag" style="top:20px; {{ cen.ad ? 'background:#ddd' : '' }}">{{ formatTime(cen.ts) }}</div>
<div style="padding-left:19%">
<ion-item id="bluetooth-item" class="list-item" style="background-color: transparent; border:none; height:auto; padding:8px 16px">
<div id="bluetooth-card" class="list card list-card" style="height:auto; width:100%; margin:0; background:{{ cen.ad ? '#f8f8f8' : '#eeffff' }}">

0 comments on commit 9500b79

Please sign in to comment.