From 04767b94d94f8df54b0cda57c4ccb15ef1d2627f Mon Sep 17 00:00:00 2001 From: David Peer Date: Tue, 6 Sep 2022 20:37:23 +0200 Subject: [PATCH] Improved handling of async data --- apps/bwclk/ChangeLog | 1 + apps/bwclk/app.js | 114 ++++++++++++++++++++++----------------- apps/bwclk/metadata.json | 2 +- 3 files changed, 67 insertions(+), 50 deletions(-) diff --git a/apps/bwclk/ChangeLog b/apps/bwclk/ChangeLog index 5ff1eb90e..81aab5050 100644 --- a/apps/bwclk/ChangeLog +++ b/apps/bwclk/ChangeLog @@ -17,3 +17,4 @@ 0.17: Fix - Step count was no more shown in the menu. 0.18: Set timer for an agenda entry by simply clicking in the middle of the screen. Only one timer can be set. 0.19: Fix - Compatibility with "Digital clock widget" +0.20: Better handling of async data such as getPressure. \ No newline at end of file diff --git a/apps/bwclk/app.js b/apps/bwclk/app.js index 9c113b5b4..0a955cf7f 100644 --- a/apps/bwclk/app.js +++ b/apps/bwclk/app.js @@ -13,11 +13,6 @@ const TIMER_AGENDA_IDX = "bwclk_agenda"; const W = g.getWidth(); const H = g.getHeight(); -/************ - * Global data - */ -var pressureData; - /************ * Settings */ @@ -209,7 +204,7 @@ var menu = [ function(){ return [ E.getBattery() + "%", Bangle.isCharging() ? imgCharging() : imgBattery() ] }, function(){ return [ getSteps(), imgSteps() ] }, function(){ return [ Math.round(Bangle.getHealthStatus("last").bpm) + " bpm", imgBpm()] }, - function(){ return [ getAltitude(), imgMountain() ]}, + function(){ return [ measureAltitude, imgMountain() ]}, ] ] @@ -346,7 +341,22 @@ function getMenuEntry(){ // could be larger than infoArray.length... settings.menuPosX = settings.menuPosX % menu.length; settings.menuPosY = settings.menuPosY % menu[settings.menuPosX].length; - return menu[settings.menuPosX][settings.menuPosY](); + var menuEntry = menu[settings.menuPosX][settings.menuPosY](); + + if(menuEntry[0] == null){ + return menuEntry; + } + + // For the first entry we always convert it into a callback function + // such that the menu is compatible with async functions such as + // measuring the pressure, altitude or sending http requests... + if(typeof menuEntry[0] !== 'function'){ + var value = menuEntry[0]; + menuEntry[0] = function(callbackFun){ + callbackFun(String(value), settings.menuPosX, settings.menuPosY); + } + } + return menuEntry; } @@ -380,14 +390,6 @@ function getSteps() { } -function getAltitude(){ - if(pressureData && pressureData.altitude){ - return Math.round(pressureData.altitude) + "m"; - } - return "???"; -} - - function getWeather(){ var weatherJson; @@ -479,12 +481,20 @@ function decreaseAlarm(idx){ } -function handleAsyncData(){ +function measureAltitude(callbackFun){ + var oldX = settings.menuPosX; + var oldY = settings.menuPosY; try{ Bangle.getPressure().then(data=>{ - pressureData = data + if(data && data.altitude && data.altitude > -100){ + callbackFun(Math.round(data.altitude) + "m", oldX, oldY); + } else { + callbackFun("???", oldX, oldY); + } }); - }catch(ex){ } + }catch(ex){ + callbackFun("err", oldX, oldY); + } } @@ -495,9 +505,6 @@ function draw() { // Queue draw again queueDraw(); - // Now lets measure some data.. - handleAsyncData(); - // Draw clock drawDate(); drawTime(); @@ -557,46 +564,55 @@ function drawTime(){ y += parseInt((H - y)/2) + 5; var menuEntry = getMenuEntry(); - var menuName = String(menuEntry[0]); + var menuTextFun = menuEntry[0]; var menuImg = menuEntry[1]; var printImgLeft = settings.menuPosY != 0; // Show large or small time depending on info entry - if(menuName == null){ + if(menuTextFun == null){ g.setLargeFont(); + g.drawString(timeStr, W/2, y); + return; } else { y -= 15; g.setMediumFont(); - } - g.drawString(timeStr, W/2, y); - - // Draw menu if set - if(menuName == null){ - return; + g.drawString(timeStr, W/2, y); } - y += 35; - g.setFontAlign(0,0); + // Async set the menu (could be that some data is async fetched) + menuTextFun((menuText, oldX, oldY) => { - if(menuName.split('\n').length > 1){ - g.setMiniFont(); - } else { - g.setSmallFont(); - } + // We display the text IFF the user did not change the menu + if(settings.menuPosX != oldX || settings.menuPosY != oldY){ + return; + } - var imgWidth = 0; - if(menuImg !== undefined){ - imgWidth = 24.0; - var strWidth = g.stringWidth(menuName); - var scale = imgWidth / menuImg.width; - g.drawImage( - menuImg, - W/2 + (printImgLeft ? -strWidth/2-4 : strWidth/2+4) - parseInt(imgWidth/2), - y - parseInt(imgWidth/2), - { scale: scale } - ); - } - g.drawString(menuName, printImgLeft ? W/2 + imgWidth/2 + 2 : W/2 - imgWidth/2 - 2, y+3); + // As its a callback, we have to ensure that the color + // font etc. is still correct... + g.setColor(g.theme.bg); + g.setFontAlign(0,0); + y += 35; + + if(menuText.split('\n').length > 1){ + g.setMiniFont(); + } else { + g.setSmallFont(); + } + + var imgWidth = 0; + if(menuImg !== undefined){ + imgWidth = 24.0; + var strWidth = g.stringWidth(menuText); + var scale = imgWidth / menuImg.width; + g.drawImage( + menuImg, + W/2 + (printImgLeft ? -strWidth/2-4 : strWidth/2+4) - parseInt(imgWidth/2), + y - parseInt(imgWidth/2), + { scale: scale } + ); + } + g.drawString(menuText, printImgLeft ? W/2 + imgWidth/2 + 2 : W/2 - imgWidth/2 - 2, y+3); + }); } diff --git a/apps/bwclk/metadata.json b/apps/bwclk/metadata.json index bc2bb37b6..919ecad13 100644 --- a/apps/bwclk/metadata.json +++ b/apps/bwclk/metadata.json @@ -1,7 +1,7 @@ { "id": "bwclk", "name": "BW Clock", - "version": "0.19", + "version": "0.20", "description": "A very minimalistic clock to mainly show date and time.", "readme": "README.md", "icon": "app.png",