Created a PWA frontend. This marks a major milestone in the project, as I will be dropping support of the cordova mobile app and rely entirely on the PWA for bluetooth connectivity going forward. Can't afford an Apple dev license I'll never use and don't want the trouble of maintaining mobile apps on the stores that maybe a handful of people will use. Check intval.sixteenmillimeter.com for this site deployed as an app.

This commit is contained in:
mmcwilliams 2019-06-19 19:23:20 -04:00
parent 7f6f05ef70
commit 6f6dabca5b
5 changed files with 379 additions and 263 deletions

View File

@ -13,6 +13,7 @@
<div id="overlay"> <div id="overlay">
<div id="spinner"></div> <div id="spinner"></div>
<div id="msg"></div> <div id="msg"></div>
<div id="tap">Tap to Connect</div>
</div> </div>
<div id="app" class="page selected"> <div id="app" class="page selected">
<h2>INTVAL3</h2> <h2>INTVAL3</h2>
@ -175,6 +176,7 @@
<script src="static/js/intval.core.js"></script> <script src="static/js/intval.core.js"></script>
<script src="static/js/intval.web.js"></script> <script src="static/js/intval.web.js"></script>
<script src="static/js/intval.mobile.js"></script> <script src="static/js/intval.mobile.js"></script>
<script src="static/js/intval.pwa.js"></script>
<!--<script src="static/js/intval.mscript.js"></script>--> <!--<script src="static/js/intval.mscript.js"></script>-->
<script src="static/js/index.js"></script> <script src="static/js/index.js"></script>
</body> </body>

View File

@ -255,8 +255,8 @@ footer{
} }
footer .icon { footer .icon {
width: 33.33%; /*width: 33.33%;*/
/*width: 50%;*/ width: 50%;
height: 50px; height: 50px;
float: left; float: left;
box-sizing: border-box; box-sizing: border-box;
@ -428,3 +428,16 @@ body.mobile footer{
#msg.active{ #msg.active{
display: block; display: block;
} }
#tap{
display: none;
width: 100%;
height: 100vh;
position: fixed;
left: 0;
top: 0;
color: #fff;
text-align: center;
line-height: 100vh;
text-shadow: 1px 1px 0px #000;
font-size: 24px;
}

View File

@ -22,7 +22,11 @@ var app = {
document.addEventListener('deviceready', this.onDeviceReady.bind(this), false); document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
document.addEventListener('resume', this.onDeviceResume.bind(this), false); document.addEventListener('resume', this.onDeviceResume.bind(this), false);
document.addEventListener('DOMContentLoaded', event => { document.addEventListener('DOMContentLoaded', event => {
if (typeof cordova === 'undefined') { if (typeof navigator.bluetooth !== 'undefined' && typeof cordova === 'undefined') {
init();
pwa.init();
//getState();
} else if (typeof cordova === 'undefined') {
init(); init();
web.init(); web.init();
getState(); getState();
@ -37,6 +41,7 @@ var app = {
onDeviceReady: function() { onDeviceReady: function() {
init(); init();
mobile.init(); mobile.init();
getState();
}, },
onDeviceResume : function () { onDeviceResume : function () {
getState(); getState();

View File

@ -155,7 +155,7 @@ mobile.init = function () {
} }
UI.spinner.init() UI.spinner.init()
mobile.ble.scan(); mobile.ble.scan();
mobile.cameraValues(); //mobile.cameraValues();
}; };

View File

@ -3,9 +3,9 @@
'use strict'; 'use strict';
var mobile = {}; var pwa = {};
mobile.wble = { pwa.wble = {
BLENO_DEVICE_NAME : 'intval3', BLENO_DEVICE_NAME : 'intval3',
DEVICE_ID : 'intval3', DEVICE_ID : 'intval3',
SERVICE_ID : '149582bd-d49d-4b5c-acd1-1ae503d09e7a', SERVICE_ID : '149582bd-d49d-4b5c-acd1-1ae503d09e7a',
@ -13,11 +13,15 @@ mobile.wble = {
WIFI_ID : '3fe7d9cf-7bd2-4ff0-97c5-ebe87288c2cc', //wifi only WIFI_ID : '3fe7d9cf-7bd2-4ff0-97c5-ebe87288c2cc', //wifi only
devices : [], devices : [],
device : {}, device : {},
peripheral : {},
service : {},
characteristics : {},
descriptors : {},
connected : false, connected : false,
active : false active : false
}; };
mobile.wifi = { pwa.wifi = {
current : 'null', current : 'null',
available : [], available : [],
ip : null ip : null
@ -29,59 +33,76 @@ async function delay (ms) {
}) })
} }
mobile.wble.scan = async function () { pwa.wble.scan = async function () {
let device; let device;
UI.spinner.show('Scanning for INTVAL3...'); UI.spinner.show('Scanning for INTVAL3...');
UI.overlay.show(); UI.overlay.show();
document.getElementById('tap').style.display = 'none';
pwa.wble.devices = [];
try { try {
device = await navigator.bluetooth.requestDevice({ device = await navigator.bluetooth.requestDevice({
filters: [{ services: [ mobile.wble.SERVICE_ID ] }], filters: [{
//optionalServices: optionalServices name : pwa.wble.DEVICE_ID
}],
optionalServices: [ pwa.wble.SERVICE_ID ]
}); });
mobile.wble.onDiscover(device);
} catch (err) { } catch (err) {
mobile.wble.onError(err); console.error(err);
pwa.wble.onError(err.message);
}
if (device) {
pwa.wble.onDiscover(device);
} }
//ble.scan([], 5, mobile.wble.onDiscover, mobile.wble.onError);
mobile.wble.devices = [];
await delay(5000); await delay(5000);
UI.spinner.hide(); UI.spinner.hide();
UI.overlay.hide(); UI.overlay.hide();
if (!mobile.wble.connected) { if (!pwa.wble.connected) {
mobile.alert('No devices found.') pwa.alert('No devices found.')
settingsPage(); settingsPage();
} }
}; };
mobile.wble.onDiscover = function (device) { pwa.wble.onDiscover = function (device) {
if (device && device.name && device.name.indexOf('intval3') !== -1) { if (device && device.name && device.name.indexOf('intval3') !== -1) {
console.log('BLE - Discovered INTVAL3'); console.log('BLE - Discovered INTVAL3');
console.dir(device); //console.dir(device);
mobile.wble.devices.push(device); pwa.wble.devices.push(device);
if (!mobile.wble.connected) { if (!pwa.wble.connected) {
mobile.wble.connect(device); pwa.wble.connect(device);
} }
} else { } else {
//console.log(`BLE - Discovered Other ${device.id}`); //console.log(`BLE - Discovered Other ${device.id}`);
} }
}; };
mobile.wble.connect = async function (device) { pwa.wble.connect = async function (device) {
console.log(`BLE - Connecting to ${device.id}`); console.log(`BLE - Connecting to ${device.id}`);
let peripheral;
let service;
try { try {
await device.gatt.connect() peripheral = await device.gatt.connect();
} catch (err) { } catch (err) {
mobile.wble.onError(err); pwa.wble.onError(err);
} }
ble.connect(device.id, (peripheral) => { try {
mobile.wble.onConnect(peripheral, device); service = await peripheral.getPrimaryService(pwa.wble.SERVICE_ID);
}, mobile.wble.onError); } catch (err) {
console.error(err);
pwa.wble.onError(err.message);
return false;
}
pwa.wble.onConnect(peripheral, device, service);
}; };
mobile.wble.onConnect = function (peripheral, device) { pwa.wble.onConnect = function (peripheral, device, service) {
const elem = document.getElementById('bluetooth'); const elem = document.getElementById('bluetooth');
const option = document.createElement('option'); const option = document.createElement('option');
const disconnect = document.getElementById('disconnect'); const disconnect = document.getElementById('disconnect');
@ -89,12 +110,15 @@ mobile.wble.onConnect = function (peripheral, device) {
UI.spinner.hide(); UI.spinner.hide();
UI.overlay.hide(); UI.overlay.hide();
console.log(`BLE - Connected to ${device.id}`);
console.log(peripheral);
console.dir(device);
mobile.wble.device = device; console.log(`BLE - Connected to ${device.id}`);
mobile.wble.connected = true; //console.dir(peripheral);
//console.dir(device);
pwa.wble.peripheral = peripheral;
pwa.wble.device = device;
pwa.wble.service = service;
pwa.wble.connected = true;
elem.innerHTML = ''; elem.innerHTML = '';
option.text = device.name; option.text = device.name;
@ -105,22 +129,22 @@ mobile.wble.onConnect = function (peripheral, device) {
scan.classList.remove('active'); scan.classList.remove('active');
getState(); getState();
mobile.getWifi(); pwa.getWifi();
}; };
mobile.wble.disconnect = function () { pwa.wble.disconnect = function () {
const elem = document.getElementById('bluetooth'); const elem = document.getElementById('bluetooth');
const option = document.createElement('option'); const option = document.createElement('option');
const disconnect = document.getElementById('disconnect'); const disconnect = document.getElementById('disconnect');
const scan = document.getElementById('scan'); const scan = document.getElementById('scan');
let device; let device;
if (!mobile.wble.connected) { if (!pwa.wble.connected) {
console.warn('Not connected to any device'); console.warn('Not connected to any device');
return false; return false;
} }
device = mobile.wble.device; device = pwa.wble.device;
console.log(`BLE - Disconnecting from ${device.id}`); console.log(`BLE - Disconnecting from ${device.id}`);
//ble.disconnect(device.id, mobile.wble.onDisconnect, mobile.wble.onDisconnect); //ble.disconnect(device.id, pwa.wble.onDisconnect, pwa.wble.onDisconnect);
elem.innerHTML = ''; elem.innerHTML = '';
option.text = 'N/A'; option.text = 'N/A';
@ -132,234 +156,314 @@ mobile.wble.disconnect = function () {
UI.overlay.hide(); UI.overlay.hide();
}; };
mobile.wble.onDisconnect = function (res) { pwa.wble.onDisconnect = function (res) {
console.log(`BLE - Disconnected from ${res}`); console.log(`BLE - Disconnected from ${res}`);
mobile.wble.connected = false; pwa.wble.connected = false;
mobile.wble.device = {}; pwa.wble.device = {};
}; };
mobile.wble.onError = function (err) { pwa.wble.onError = function (err) {
if (err.errorMessage && err.errorMessage === 'Peripheral Disconnected') { if (err.errorMessage && err.errorMessage === 'Peripheral Disconnected') {
console.log('Device disconnected'); console.log('Device disconnected');
mobile.wble.disconnect() pwa.wble.disconnect()
} else { } else {
mobile.alert(JSON.stringify(err)); pwa.alert(JSON.stringify(err));
} }
/*
Object
errorDescription: "The specified device has disconnected from us."
errorMessage: "Peripheral Disconnected"
id: "E8EF4B8B-0B5E-4E96-B337-E878DB1E3C4B"
name: "intval3_b827ebc7461d"
*/
}; };
mobile.init = function () { pwa.wble.read = async function (characteristicId) {
const decoder = new TextDecoder('utf-8');
let characteristic;
let value;
let json;
if (typeof pwa.wble.characteristics[characteristicId] === 'undefined') {
try {
characteristic = await pwa.wble.service.getCharacteristic(characteristicId);
pwa.wble.characteristics[characteristicId] = characteristic;
} catch (err) {
console.error(err);
pwa.wble.onError(err.message);
return false;
}
} else {
characteristic = pwa.wble.characteristics[characteristicId]
}
try {
value = await characteristic.readValue();
} catch (err) {
console.error(err);
pwa.wble.onError(err.message);
}
json = decoder.decode(value);
return JSON.parse(json);
}
pwa.wble.write = async function ( characteristicId, json) {
const encoder = new TextEncoder('utf-8');
let characteristic;
let value;
if (typeof pwa.wble.characteristics[characteristicId] === 'undefined') {
try {
characteristic = await pwa.wble.service.getCharacteristic(characteristicId);
pwa.wble.charactersitics[characteristicId] = characteristic;
} catch (err) {
console.error(err);
pwa.wble.onError(err.message);
return false;
}
} else {
characteristic = pwa.wble.characteristics[characteristicId];
}
value = JSON.stringify(json);
encoder.encode(value);
try {
await characteristic.writeValue(encoder.encode(value))
} catch (err) {
console.error(err);
pwa.wble.onError(err.message);
return false;
}
return true;
}
pwa.init = function () {
const bleInputs = document.querySelectorAll('.ble'); const bleInputs = document.querySelectorAll('.ble');
const bolIso = document.querySelector('.iso'); const bolIso = document.querySelector('.iso');
const bolF = document.querySelector('.fstop'); const bolF = document.querySelector('.fstop');
const tap = document.getElementById('tap');
document.querySelector('body').classList.add('mobile'); //document.querySelector('body').classList.add('mobile');
window.frame = mobile.frame; window.frame = pwa.frame;
window.getState = mobile.getState; window.getState = pwa.getState;
window.setDir = mobile.setDir; window.setDir = pwa.setDir;
window.setExposure = mobile.setExposure; window.setExposure = pwa.setExposure;
window.setDelay = mobile.setDelay; window.setDelay = pwa.setDelay;
window.setCounter = mobile.setCounter; window.setCounter = pwa.setCounter;
window.sequence = mobile.sequence; window.sequence = pwa.sequence;
window.reset = mobile.reset; window.reset = pwa.reset;
window.restart = mobile.restart; window.restart = pwa.restart;
window.update = mobile.update; window.update = pwa.update;
//show ble-specific fields in settings //show ble-specific fields in settings
for (let i of bleInputs) { for (let i of bleInputs) {
i.classList.add('active'); i.classList.add('active');
} }
UI.spinner.init() UI.spinner.init();
mobile.wble.scan(); UI.overlay.show();
mobile.cameraValues();
tap.onclick = pwa.wble.scan;
tap.style.display = 'block';
//pwa.cameraValues();
}; };
mobile.getState = function () { pwa.pairInteraction = function () {
if (!mobile.wble.connected) { pwa.wble.scan();
//returning here will prevent error alert }
pwa.getState = async function () {
let state;
if (!pwa.wble.connected) {
return false
} }
/*ble.read(mobile.wble.device.id, try {
mobile.wble.SERVICE_ID, state = await pwa.wble.read(pwa.wble.CHAR_ID);
mobile.wble.CHAR_ID, } catch (err) {
mobile.stateSuccess, console.error(err);
mobile.wble.onError);*/ pwa.wble.onError(err.message);
}; return false;
mobile.stateSuccess = function (data) { }
let str = bytesToString(data); setState(state);
let res = JSON.parse(str);
setState(res);
}; };
mobile.frame = function () { pwa.frame = async function () {
const opts = { const opts = {
type : 'frame' type : 'frame'
}; };
if (!mobile.wble.connected) { if (!pwa.wble.connected) {
return mobile.alert('Not connected to an INTVAL3 device.'); return pwa.alert('Not connected to an INTVAL3 device.');
} }
if (mobile.wble.active) { if (pwa.wble.active) {
return false; return false;
} }
/*ble.write(mobile.wble.device.id,
mobile.wble.SERVICE_ID,
mobile.wble.CHAR_ID,
stringToBytes(JSON.stringify(opts)), //check length?
mobile.frameSuccess,
mobile.wble.onError);*/
document.getElementById('frame').classList.add('focus'); document.getElementById('frame').classList.add('focus');
mobile.wble.active = true; pwa.wble.active = true;
try {
await pwa.wble.write(pwa.wble.CHAR_ID, opts);
} catch (err) {
console.error(err);
pwa.wble.onError(err.message);
return false;``
}
pwa.frameSuccess();
}; };
mobile.frameSuccess = function () { pwa.frameSuccess = function () {
if (STATE.exposure < 5000) { if (STATE.exposure < 5000) {
console.log('Frame finished, getting state.'); console.log('Frame finished, getting state.');
mobile.wble.active = false; pwa.wble.active = false;
document.getElementById('frame').classList.remove('focus'); document.getElementById('frame').classList.remove('focus');
mobile.getState(); pwa.getState();
} else { } else {
setTimeout(() => { setTimeout(() => {
console.log('Frame finished, getting state.'); console.log('Frame finished, getting state.');
mobile.wble.active = false; pwa.wble.active = false;
document.getElementById('frame').classList.remove('focus'); document.getElementById('frame').classList.remove('focus');
mobile.getState(); pwa.getState();
}, STATE.exposure + 500) }, STATE.exposure + 500)
} }
} }
mobile.setDir = function () { pwa.setDir = async function () {
const opts = { const opts = {
type : 'dir', type : 'dir',
dir : !document.getElementById('dir').checked dir : !document.getElementById('dir').checked
}; };
/*ble.write(mobile.wble.device.id, try {
mobile.wble.SERVICE_ID, await pwa.wble.write(pwa.wble.CHAR_ID, opts);
mobile.wble.CHAR_ID, } catch (err) {
stringToBytes(JSON.stringify(opts)), //check length? console.error(err);
mobile.dirSuccess, pwa.wble.onError(err.message);
mobile.wble.onError);*/ return false;
}
pwa.dirSuccess();
}; };
mobile.dirSuccess = function () { pwa.dirSuccess = function () {
console.log('Set direction'); console.log('Set direction');
mobile.getState(); pwa.getState();
setTimeout(() => { setTimeout(() => {
setDirLabel(STATE.dir); setDirLabel(STATE.dir);
}, 50); }, 50);
}; };
mobile.setExposure = function () {
let exposure = document.getElementById('exposure').value; pwa.setExposure = async function () {
let scaledExposure; const opts = {
let opts = {
type : 'exposure' type : 'exposure'
}; };
let exposure = document.getElementById('exposure').value;
let scaledExposure;
if (exposure === '' || exposure === null) { if (exposure === '' || exposure === null) {
exposure = 0; exposure = 0;
} }
scaledExposure = scaleTime(exposure, STATE.scale); scaledExposure = scaleTime(exposure, STATE.scale);
opts.exposure = scaledExposure; opts.exposure = scaledExposure;
/*ble.write(mobile.wble.device.id,
mobile.wble.SERVICE_ID, try {
mobile.wble.CHAR_ID, await pwa.wble.write(pwa.wble.CHAR_ID, opts);
stringToBytes(JSON.stringify(opts)), //check length? } catch (err) {
mobile.exposureSuccess, console.error(err);
mobile.wble.onError);*/ pwa.wble.onError(err.message);
}; return false;
mobile.exposureSuccess = function () { }
console.log('Set exposure'); pwa.exposureSuccess();
mobile.getState();
}; };
mobile.setDelay = function () { pwa.exposureSuccess = function () {
console.log('Set exposure');
pwa.getState();
};
pwa.setDelay = async function () {
const delay = document.getElementById('delay').value; const delay = document.getElementById('delay').value;
const scaledDelay = scaleTime(delay, STATE.delayScale); const scaledDelay = scaleTime(delay, STATE.delayScale);
let opts = { const opts = {
type : 'delay', type : 'delay',
delay : scaledDelay delay : scaledDelay
}; };
/*ble.write(mobile.wble.device.id,
mobile.wble.SERVICE_ID, try {
mobile.wble.CHAR_ID, await pwa.wble.write(pwa.wble.CHAR_ID, opts);
stringToBytes(JSON.stringify(opts)), //check length? } catch (err) {
mobile.delaySuccess, console.error(err);
mobile.wble.onError);*/ pwa.wble.onError(err.message);
return false;
}
pwa.delaySuccess();
} }
mobile.delaySuccess = function () { pwa.delaySuccess = function () {
console.log('Set delay'); console.log('Set delay');
mobile.getState(); pwa.getState();
}; };
mobile.setCounter = function () { pwa.setCounter = async function () {
let opts = { const opts = {
type : 'counter', type : 'counter',
counter : null counter : null
}; };
const counter = document.getElementById('counter').value; const counter = document.getElementById('counter').value;
function counterPrompt (results) { const change = prompt(`Change counter value?`, counter);
let change = results.input1
if (results.buttonIndex === 1) { if (change === null || !isNumeric(change)) return false;
if (change === null || !isNumeric(change)) return false;
opts.counter = change; if (change === counter) return true;
/*ble.write(mobile.wble.device.id,
mobile.wble.SERVICE_ID, opts.counter = change;
mobile.wble.CHAR_ID, try {
stringToBytes(JSON.stringify(opts)), //check length? await pwa.wble.write(pwa.wble.CHAR_ID, opts);
mobile.counterSuccess, } catch (err) {
mobile.wble.onError);*/ console.error(err);
} pwa.wble.onError(err.message);
return false;
} }
navigator.notification.prompt( pwa.counterSuccess();
`Change counter value?`,
counterPrompt,
'INTVAL3',
['Okay', 'Cancel'],
counter);
}; };
mobile.counterSuccess = function () { pwa.counterSuccess = function () {
console.log('Set counter'); console.log('Set counter');
mobile.getState(); pwa.getState();
}; };
mobile.sequence = function () { pwa.sequence = async function () {
const opts = { const opts = {
type : 'sequence' type : 'sequence'
}; };
const elem = document.getElementById('seq'); const elem = document.getElementById('seq');
if (!mobile.wble.connected) { if (!pwa.wble.connected) {
return mobile.alert('Not connected to an INTVAL3 device.'); return pwa.alert('Not connected to an INTVAL3 device.');
} }
/*ble.write(mobile.wble.device.id, try {
mobile.wble.SERVICE_ID, await pwa.wble.write(pwa.wble.CHAR_ID, opts);
mobile.wble.CHAR_ID, } catch (err) {
stringToBytes(JSON.stringify(opts)), //check length? console.error(err);
mobile.sequenceSuccess, pwa.wble.onError(err.message);
mobile.wble.onError);*/ return false;
}
pwa.sequenceSuccess();
if (!elem.classList.contains('focus')) { if (!elem.classList.contains('focus')) {
elem.classList.add('focus'); elem.classList.add('focus');
} }
mobile.wble.active = true; pwa.wble.active = true;
}; };
mobile.sequenceSuccess = function () { pwa.sequenceSuccess = function () {
console.log('Sequence state changed'); console.log('Sequence state changed');
mobile.getState(); pwa.getState();
setTimeout(() => { setTimeout(() => {
if (STATE.sequence) { if (STATE.sequence) {
mobile.wble.active = true; pwa.wble.active = true;
seqState(true); seqState(true);
} else { } else {
mobile.wble.active = false; pwa.wble.active = false;
seqState(false); seqState(false);
} }
}, 20); }, 20);
@ -368,25 +472,28 @@ mobile.sequenceSuccess = function () {
//retreive object with list of available Wifi APs, //retreive object with list of available Wifi APs,
//and state of current connection, if available //and state of current connection, if available
mobile.getWifi = function () { pwa.getWifi = async function () {
let wifiRes;
UI.spinner.show('Refreshing WIFI...'); UI.spinner.show('Refreshing WIFI...');
UI.overlay.show(); UI.overlay.show();
/*ble.read(mobile.wble.device.id, try {
mobile.wble.SERVICE_ID, wifiRes = await pwa.wble.read(pwa.wble.WIFI_ID);
mobile.wble.WIFI_ID, } catch (err) {
mobile.getWifiSuccess, console.error(err);
mobile.wble.onError);*/ pwa.wble.onError(err.message);
return false
}
pwa.getWifiSuccess(wifiRes);
}; };
mobile.getWifiSuccess = function (data) { pwa.getWifiSuccess = function (res) {
const elem = document.getElementById('available'); const elem = document.getElementById('available');
const wifi = document.getElementById('wifi'); const wifi = document.getElementById('wifi');
const password = document.getElementById('password'); const password = document.getElementById('password');
const ip = document.getElementById('ip'); const ip = document.getElementById('ip');
let option = document.createElement('option'); let option = document.createElement('option');
let str = bytesToString(data);
let res = JSON.parse(str);
UI.spinner.hide(); UI.spinner.hide();
UI.overlay.hide(); UI.overlay.hide();
@ -436,12 +543,12 @@ mobile.getWifiSuccess = function (data) {
ip.classList.remove('active'); ip.classList.remove('active');
} }
} }
mobile.wifi.current = res.current; pwa.wifi.current = res.current;
mobile.wifi.available = res.available; pwa.wifi.available = res.available;
mobile.wifi.ip = res.ip; pwa.wifi.ip = res.ip;
}; };
mobile.editWifi = function () { pwa.editWifi = function () {
const available = document.getElementById('available'); const available = document.getElementById('available');
const wifi = document.getElementById('wifi'); const wifi = document.getElementById('wifi');
const password = document.getElementById('password'); const password = document.getElementById('password');
@ -452,12 +559,12 @@ mobile.editWifi = function () {
password.classList.add('active'); password.classList.add('active');
} }
password.focus(); password.focus();
if (available.value !== mobile.wifi.current && available.classList.contains('active')) { if (available.value !== pwa.wifi.current && available.classList.contains('active')) {
available.classList.remove('active'); available.classList.remove('active');
} }
}; };
mobile.setWifi = function () { pwa.setWifi = async function () {
const ssid = document.getElementById('available').value; const ssid = document.getElementById('available').value;
const pwd = document.getElementById('password').value; const pwd = document.getElementById('password').value;
const opts = { const opts = {
@ -468,50 +575,53 @@ mobile.setWifi = function () {
UI.overlay.show(); UI.overlay.show();
if (ssid === '' || ssid === null || ssid === undefined) { if (ssid === '' || ssid === null || ssid === undefined) {
return mobile.alert('Cannot set wireless credentials with a blank SSID'); return pwa.alert('Cannot set wireless credentials with a blank SSID');
} }
if (pwd === '' || pwd === null || pwd === undefined) { if (pwd === '' || pwd === null || pwd === undefined) {
return mobile.alert('Cannot set wireless credentials with a blank passphrase'); return pwa.alert('Cannot set wireless credentials with a blank passphrase');
} }
if (pwd.length < 8 || pwd.length > 63) { if (pwd.length < 8 || pwd.length > 63) {
return mobile.alert('Passphrase must be 8..63 characters'); return pwa.alert('Passphrase must be 8..63 characters');
} }
/*ble.write(mobile.wble.device.id, try {
mobile.wble.SERVICE_ID, await pwa.wble.write(pwa.wble.WIFI_ID, opts);
mobile.wble.WIFI_ID, } catch (err) {
stringToBytes(JSON.stringify(opts)), console.error(err);
mobile.setWifiSuccess, pwa.wble.onError(err.message);
mobile.wble.onError);*/ return false;
}
pwa.setWifiSuccess();
}; };
mobile.setWifiSuccess = function () { pwa.setWifiSuccess = function () {
UI.spinner.hide(); UI.spinner.hide();
UI.overlay.hide(); UI.overlay.hide();
console.log('Set new wifi credentials'); console.log('Set new wifi credentials');
setTimeout(mobile.getWifi, 100); setTimeout(pwa.getWifi, 100);
}; };
mobile.exif = {} /*
pwa.exif = {}
mobile.getCamera = function () { pwa.getCamera = function () {
const opts = { const opts = {
quality: 30, quality: 30,
sourceType: Camera.PictureSourceType.CAMERA, sourceType: Camera.PictureSourceType.CAMERA,
destinationType: Camera.DestinationType.FILE_URI destinationType: Camera.DestinationType.FILE_URI
}; };
navigator.camera.getPicture(mobile.cameraSuccess, mobile.cameraError, opts); navigator.camera.getPicture(pwa.cameraSuccess, pwa.cameraError, opts);
}; };
mobile.cameraSuccess = function (result) { pwa.cameraSuccess = function (result) {
const thisResult = JSON.parse(result); const thisResult = JSON.parse(result);
const metadata = JSON.parse(thisResult.json_metadata); const metadata = JSON.parse(thisResult.json_metadata);
mobile.cameraExposure(metadata.Exif); pwa.cameraExposure(metadata.Exif);
}; };
mobile.cameraError = function (err) { pwa.cameraError = function (err) {
console.error(err); console.error(err);
mobile.alert(JSON.stringify(err)); pwa.alert(JSON.stringify(err));
}; };
mobile.cameraExposure = function (exif) { pwa.cameraExposure = function (exif) {
const cam_exp = document.getElementById('cam_exp'); const cam_exp = document.getElementById('cam_exp');
const cam_f = document.getElementById('cam_f'); const cam_f = document.getElementById('cam_f');
const cam_iso = document.getElementById('cam_iso'); const cam_iso = document.getElementById('cam_iso');
@ -546,7 +656,7 @@ mobile.cameraExposure = function (exif) {
let e1; let e1;
let e2; let e2;
mobile.exif = exif; pwa.exif = exif;
//Determine if fstop of phone camera "f" //Determine if fstop of phone camera "f"
if (target !== f) { if (target !== f) {
@ -606,7 +716,7 @@ mobile.cameraExposure = function (exif) {
); );
} }
/*
{ {
"Exif": { "Exif": {
"DateTimeOriginal": "2018:02:02 16:59:13", "DateTimeOriginal": "2018:02:02 16:59:13",
@ -650,107 +760,93 @@ mobile.cameraExposure = function (exif) {
"MeteringMode": 5 "MeteringMode": 5
} }
} }
*/
}; };
mobile.refreshExposure = function () { pwa.refreshExposure = function () {
if (typeof mobile.exif.ExposureTime !== 'undefined') { if (typeof pwa.exif.ExposureTime !== 'undefined') {
mobile.cameraExposure(mobile.exif); pwa.cameraExposure(pwa.exif);
} }
}; };
mobile.EV = function (fstop, shutter) { pwa.EV = function (fstop, shutter) {
const sec = shutter / 1000; //shutter in ms => seconds const sec = shutter / 1000; //shutter in ms => seconds
const square = Math.pow(fstop, 2); const square = Math.pow(fstop, 2);
return Math.log(square / sec); return Math.log(square / sec);
}; };*/
mobile.reset = function () { pwa.reset = async function () {
let opts = { const opts = {
type : 'reset' type : 'reset'
}; };
function resetConfirm (index) { const cont = confirm(`Reset INTVAL3 to default settings and clear counter?`);
if (index === 1) { if (cont) {
/*ble.write(mobile.wble.device.id, try {
mobile.wble.SERVICE_ID, await pwa.wble.write(pwa.wble.CHAR_ID, opts);
mobile.wble.CHAR_ID, } catch (err) {
stringToBytes(JSON.stringify(opts)), console.error(err);
mobile.resetSuccess, pwa.wble.onError(err.message);
mobile.wble.onError);*/ return false;
} }
pwa.resetSuccess();
} }
navigator.notification.confirm(
`Reset INTVAL3 to default settings and clear counter?`,
resetConfirm,
'INTVAL3',
['Okay', 'Cancel']
);
}; };
mobile.resetSuccess = function () { pwa.resetSuccess = function () {
console.log('Reset to default settings'); console.log('Reset to default settings');
setTimeout(() => { setTimeout(() => {
mobile.getState(); pwa.getState();
}, 100) }, 100)
}; };
mobile.update = function () { pwa.update = async function () {
let opts = { const opts = {
type : 'update' type : 'update'
}; };
function updateConfirm (index) { const cont = confirm(`Check for updates? You will be disconnected from the INTVAL3 during this process.`);
if (index === 1) { if (cont) {
UI.spinner.show('Updating INTVAL3...'); UI.spinner.show('Updating INTVAL3...');
UI.overlay.show(); UI.overlay.show();
/*ble.write(mobile.wble.device.id, try {
mobile.wble.SERVICE_ID, await pwa.wble.write(pwa.wble.CHAR_ID, opts);
mobile.wble.CHAR_ID, } catch (err) {
stringToBytes(JSON.stringify(opts)), console.error(err);
mobile.updateSuccess, pwa.wble.onError(err.message);
mobile.wble.onError);*/ return false;
} }
pwa.updateSuccess();
} }
navigator.notification.confirm(
`Check for updates? You will be disconnected from the INTVAL3 during this process.`,
updateConfirm,
'INTVAL3',
['Okay', 'Cancel']
);
}; };
mobile.updateSuccess = function () { pwa.updateSuccess = function () {
console.log('Finished updating firmware, restarting...'); console.log('Finished updating firmware, restarting...');
}; };
mobile.restart = function () { pwa.restart = async function () {
let opts = { const opts = {
type : 'restart' type : 'restart'
}; };
function restartConfirm (index) { const cont = confirm(`Restart the INTVAL3? You will be disconnected from it during this process.`);
if (index === 1) { if (cont) {
UI.spinner.show('Restarting INTVAL3...'); UI.spinner.show('Restarting INTVAL3...');
UI.overlay.show(); UI.overlay.show();
/*ble.write(mobile.wble.device.id, try {
mobile.wble.SERVICE_ID, await pwa.wble.write(pwa.wble.CHAR_ID, opts);
mobile.wble.CHAR_ID, } catch (err) {
stringToBytes(JSON.stringify(opts)), console.error(err);
mobile.restartSuccess, pwa.wble.onError(err.message);
mobile.wble.onError);*/ return false;
} }
pwa.restartSuccess();
} }
navigator.notification.confirm(
`Restart the INTVAL3? You will be disconnected from it during this process.`,
restartConfirm,
'INTVAL3',
['Okay', 'Cancel']
);
}; };
mobile.restartSuccess = function () { pwa.restartSuccess = function () {
console.log('Restarting... '); console.log('Restarting... ');
} }
mobile.alert = function (msg) { pwa.alert = function (msg) {
if (navigator && navigator.notification) { if (typeof navigator !== 'undefined' && typeof navigator.notification !== 'undefined') {
navigator.notification.alert( navigator.notification.alert(
msg, msg,
() => {}, () => {},