diff --git a/apps.json b/apps.json index d57a617a5..7e7540581 100644 --- a/apps.json +++ b/apps.json @@ -42,7 +42,7 @@ "name": "Launcher (Default)", "shortName":"Launcher", "icon": "app.png", - "version":"0.06", + "version":"0.07", "description": "This is needed by Bangle.js to display a menu allowing you to choose your own applications. You can replace this with a customised launcher.", "tags": "tool,system,launcher,b2", "type":"launch", @@ -107,7 +107,7 @@ "name": "Fullscreen Notifications", "shortName":"Notifications", "icon": "notify.png", - "version":"0.11", + "version":"0.12", "description": "Provides a replacement for the `Notifications (default)` `notify` module. This version is used by applications to display notifications fullscreen. This may not fully restore the screen after on some apps. See `Notifications (default)` for more information about the notify module.", "tags": "widget,b2", "type": "notify", @@ -585,7 +585,7 @@ { "id": "weather", "name": "Weather", "icon": "icon.png", - "version":"0.08", + "version":"0.09", "description": "Show Gadgetbridge weather report", "readme": "readme.md", "tags": "widget,outdoors", @@ -1381,7 +1381,7 @@ { "id": "barclock", "name": "Bar Clock", "icon": "clock-bar.png", - "version":"0.07", + "version":"0.08", "description": "A simple digital clock showing seconds as a bar", "tags": "clock", "type":"clock", @@ -2058,7 +2058,7 @@ "name": "Find Phone", "shortName":"Find Phone", "icon": "app.png", - "version":"0.02", + "version":"0.03", "description": "Find your phone via Gadgetbridge. Click any button to let your phone ring. 📳 Note: The functionality is available even without this app, just go to Settings, App Settings, Gadgetbridge, Find Phone.", "tags": "tool,android", "readme": "README.md", diff --git a/apps/barclock/ChangeLog b/apps/barclock/ChangeLog index 9589a1902..c56967d3d 100644 --- a/apps/barclock/ChangeLog +++ b/apps/barclock/ChangeLog @@ -5,3 +5,4 @@ 0.05: Clock does not start if app Languages is not installed 0.06: Improve accuracy 0.07: Update to use Bangle.setUI instead of setWatch +0.08: Use theme colors, Layout library \ No newline at end of file diff --git a/apps/barclock/clock-bar.js b/apps/barclock/clock-bar.js index 5069faa39..c2b4bde12 100644 --- a/apps/barclock/clock-bar.js +++ b/apps/barclock/clock-bar.js @@ -3,167 +3,102 @@ * A simple digital clock showing seconds as a bar **/ // Check settings for what type our clock should be -const is12Hour = (require('Storage').readJSON('setting.json', 1) || {})['12hour'] -let locale = require('locale') +const is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"]; +let locale = require("locale"); { // add some more info to locale - let date = new Date() - date.setFullYear(1111) - date.setMonth(1, 3) // februari: months are zero-indexed - const localized = locale.date(date, true) - locale.dayFirst = /3.*2/.test(localized) + let date = new Date(); + date.setFullYear(1111); + date.setMonth(1, 3); // februari: months are zero-indexed + const localized = locale.date(date, true); + locale.dayFirst = /3.*2/.test(localized); - locale.hasMeridian = false - if(typeof locale.meridian === 'function') { // function does not exists if languages app is not installed - locale.hasMeridian = (locale.meridian(date) !== '') + locale.hasMeridian = false; + if (typeof locale.meridian==="function") { // function does not exist if languages app is not installed + locale.hasMeridian = (locale.meridian(date)!==""); } - } -const screen = { - width: g.getWidth(), - height: g.getWidth(), - middle: g.getWidth() / 2, - center: g.getHeight() / 2, +Bangle.loadWidgets(); +function renderBar(l) { + if (!this.fraction) { + // zero-size fillRect stills draws one line of pixels, we don't want that + return; + } + const width = this.fraction*l.w; + g.fillRect(l.x, l.y, width-1, l.y+l.height-1); } -// hardcoded "settings" -const settings = { - time: { - color: -1, - font: '6x8', - size: (is12Hour && locale.hasMeridian) ? 6 : 8, - middle: screen.middle, - center: screen.center, - ampm: { - color: -1, - font: '6x8', - size: 2, +const Layout = require("Layout"); +const layout = new Layout({ + type: "v", c: [ + { + type: "h", c: [ + {id: "time", label: "88:88", type: "txt", font: "6x8:5", bgCol: g.theme.bg}, // size updated below + {id: "ampm", label: " ", type: "txt", font: "6x8:2", bgCol: g.theme.bg}, + ], }, - }, - date: { - color: -1, - font: 'Vector', - size: 20, - middle: screen.height - 20, // at bottom of screen - center: screen.center, - }, - bar: { - color: -1, - top: 155, // just below time - thickness: 6, // matches 24h time "pixel" size - }, + {id: "bar", type: "custom", fraction: 0, fillx: 1, height: 6, col: g.theme.fg2, render: renderBar}, + {height: 40}, + {id: "date", type: "txt", font: "10%", valign: 1}, + ], +}, false, {lazy: true}); +// adjustments based on screen size and whether we display am/pm +let thickness; // bar thickness, same as time font "pixel block" size +if (is12Hour) { + // Maximum font size = ( - ) / (5chars * 6px) + thickness = Math.floor((g.getWidth()-24)/(5*6)); +} else { + layout.ampm.label = ""; + thickness = Math.floor(g.getWidth()/(5*6)); } +layout.bar.height = thickness+1; +layout.time.font = "6x8:"+thickness; +layout.update(); -const SECONDS_PER_MINUTE = 60 - -const timeText = function (date) { +function timeText(date) { if (!is12Hour) { - return locale.time(date, true) + return locale.time(date, true); } - const date12 = new Date(date.getTime()) - const hours = date12.getHours() - if (hours === 0) { - date12.setHours(12) - } else if (hours > 12) { - date12.setHours(hours - 12) + const date12 = new Date(date.getTime()); + const hours = date12.getHours(); + if (hours===0) { + date12.setHours(12); + } else if (hours>12) { + date12.setHours(hours-12); } - return locale.time(date12, true) + return locale.time(date12, true); } -const ampmText = function (date) { - return is12Hour ? locale.meridian(date) : '' +function ampmText(date) { + return (is12Hour && locale.hasMeridian)? locale.meridian(date) : ""; } - -const dateText = function (date) { +function dateText(date) { const dayName = locale.dow(date, true), month = locale.month(date, true), - day = date.getDate() - const dayMonth = locale.dayFirst ? `${day} ${month}` : `${month} ${day}` - return `${dayName} ${dayMonth}` + day = date.getDate(); + const dayMonth = locale.dayFirst ? `${day} ${month}` : `${month} ${day}`; + return `${dayName} ${dayMonth}`; } -const drawDateTime = function (date) { - const t = settings.time - g.setColor(t.color) - g.setFont(t.font, t.size) - g.setFontAlign(0, 0) // centered - g.drawString(timeText(date), t.center, t.middle, true) - if (is12Hour && locale.hasMeridian) { - const a = settings.time.ampm - g.setColor(a.color) - g.setFont(a.font, a.size) - g.setFontAlign(1, -1) // right top - // at right edge of screen, aligned with time bottom - const left = screen.width - a.size * 2, - top = t.middle + t.size - a.size - g.drawString(ampmText(date), left, top, true) - } +draw = function draw() { + if (!Bangle.isLCDOn()) {return;} // no drawing, also no new update scheduled + const date = new Date(); + layout.time.label = timeText(date); + layout.ampm.label = ampmText(date); + layout.date.label = dateText(date); + const SECONDS_PER_MINUTE = 60; + layout.bar.fraction = date.getSeconds()/SECONDS_PER_MINUTE; + layout.render(); + // schedule update at start of next second + const millis = date.getMilliseconds(); + setTimeout(draw, 1000-millis); +}; - const d = settings.date - g.setColor(d.color) - g.setFont(d.font, d.size) - g.setFontAlign(0, 0) // centered - g.drawString(dateText(date), d.center, d.middle, true) -} - -const drawBar = function (date) { - const b = settings.bar - const seconds = date.getSeconds() - if (seconds === 0) { - // zero-size rect stills draws one line of pixels, we don't want that - return - } - const fraction = seconds / SECONDS_PER_MINUTE, - width = fraction * screen.width - g.setColor(b.color) - g.fillRect(0, b.top, width, b.top + b.thickness) -} - -const clearScreen = function () { - g.setColor(0) - const timeTop = settings.time.middle - (settings.time.size * 4) - g.fillRect(0, timeTop, screen.width, screen.height) -} - -let lastSeconds, tTick -const tick = function () { - g.reset() - const date = new Date() - const seconds = date.getSeconds() - if (lastSeconds > seconds) { - // new minute - clearScreen() - drawDateTime(date) - } - // the bar only gets larger, so drawing on top of the previous one is fine - drawBar(date) - lastSeconds = seconds - // schedule next update - const millis = date.getMilliseconds() - tTick = setTimeout(tick, 1000-millis) -} - -const start = function () { - lastSeconds = 99 // force redraw - tick() -} -const stop = function () { - if (tTick) { - clearTimeout(tTick) - tTick = undefined - } -} - -// clean app screen -g.clear() -Bangle.loadWidgets() -Bangle.drawWidgets() // Show launcher when button pressed Bangle.setUI("clock"); - -Bangle.on('lcdPower', function (on) { +Bangle.on("lcdPower", function(on) { if (on) { - start() - } else { - stop() + draw(); } -}) -start() +}); +g.reset().clear(); +Bangle.drawWidgets(); +draw(); diff --git a/apps/barclock/screenshot.png b/apps/barclock/screenshot.png index d37ee9cae..9c2b7a50f 100644 Binary files a/apps/barclock/screenshot.png and b/apps/barclock/screenshot.png differ diff --git a/apps/barclock/screenshot_pm.png b/apps/barclock/screenshot_pm.png index a2a3f63fb..983f17aaa 100644 Binary files a/apps/barclock/screenshot_pm.png and b/apps/barclock/screenshot_pm.png differ diff --git a/apps/findphone/ChangeLog b/apps/findphone/ChangeLog index 86558abf5..29100f3c1 100644 --- a/apps/findphone/ChangeLog +++ b/apps/findphone/ChangeLog @@ -1,2 +1,3 @@ 0.01: First Version 0.02: Remove HID requirement, update screen +0.03: Fix for Bangle 2, toggle find with top half of screen, exit touch bottom half of screen diff --git a/apps/findphone/README.md b/apps/findphone/README.md index c655457a2..64e719d6a 100644 --- a/apps/findphone/README.md +++ b/apps/findphone/README.md @@ -6,3 +6,8 @@ Ring your phone via GadgetBridge if you lost it somewhere. 2. Lose phone 3. Open app 4. Click any button or screen + +## On a Bangle 2 + +- You can touch the top half of the screen to toggle Find / Stop +- You can touch the bottom half of the screen to exit the app. diff --git a/apps/findphone/app.js b/apps/findphone/app.js index 34f729bc7..e5e32739a 100644 --- a/apps/findphone/app.js +++ b/apps/findphone/app.js @@ -1,13 +1,15 @@ //notify your phone +const fontSize = g.getWidth() / 8; var finding = false; function draw() { // show message - g.clear(1); - require("Font8x12").add(Graphics); - g.setFont("8x12",3); + g.clear(g.theme.bg); + g.setColor(g.theme.fg); + g.setFont("Vector", fontSize); g.setFontAlign(0,0); + if (finding) { g.drawString("Finding...", g.getWidth()/2, (g.getHeight()/2)-20); g.drawString("Click to stop", g.getWidth()/2, (g.getHeight()/2)+20); @@ -17,17 +19,37 @@ function draw() { g.flip(); } +function findPhone(v) { + Bluetooth.println(JSON.stringify({t:"findPhone", n:v})); +} + function find(){ finding = !finding; draw(); - Bluetooth.println("\n"+JSON.stringify({t:"findPhone", n:finding})); + findPhone(finding); } draw(); //register all buttons and screen to find phone setWatch(find, BTN1, {repeat:true}); -setWatch(find, BTN2, {repeat:true}); -setWatch(find, BTN3, {repeat:true}); -setWatch(find, BTN4, {repeat:true}); -setWatch(find, BTN5, {repeat:true}); + +if (process.env.HWVERSION == 1) { + setWatch(find, BTN2, {repeat:true}); + setWatch(find, BTN3, {repeat:true}); + setWatch(find, BTN4, {repeat:true}); + setWatch(find, BTN5, {repeat:true}); +} + +if (process.env.HWVERSION == 2) { + Bangle.on('touch', function(button, xy) { + + // click top part of the screen to stop start + if (xy.y < g.getHeight() / 2) { + find(); + } else { + findPhone(false); + setTimeout(load, 100); // exit in 100ms + } + }); +} diff --git a/apps/gbridge/README.md b/apps/gbridge/README.md index 867b736ab..03bf883d7 100644 --- a/apps/gbridge/README.md +++ b/apps/gbridge/README.md @@ -52,3 +52,62 @@ Activity reporting You'll need a Gadgetbridge release *after* version 0.50.0 for Actvity Reporting to be enabled. By default heart rate isn't reported, but it can be enabled from `Settings`, `App/Widget Settings`, `Gadgetbridge`, `Record HRM` + + +## Troubleshooting + +1. Switch to using one of the stock watch faces like s7clk or wave on a Bangle 2. + +2. Check that the battery charge level is being seen by the Gadgetbridge App on the phone. This proves that data is getting to your phone. + +### You can test the notifications on the Bangle + +First disconnect from Gadgetbridge on your phone. Then connect +through the IDE and enter the following code. You should get a pop +up screen on your Bangle. This proves that the watch is correctly +setup for notifications. + + + GB({"t":"notify","id":1575479849,"src":"Hangouts","title":"A Name","body":"message contents"}) + + +NOTE: On a Bangle 2, this will fail if you have not installed 'Notifications Fullscreen'. + +### Check that notifications are getting through to your Bangle + +* Disconnect your Bangle from Gadgetbridge on your phone. +* Connect through the IDE +* Run the following bit of code + + var log = []; + function GB(d) { + log.push(JSON.stringify(d)); + } + +* Disconnect from the IDE +* Connect your Bangle to Gadgetbridge +* Call your phone to get a missed call +* Disonnect your Bangle to Gadgetbridge +* Connect through the IDE +* Run the following bit of code + + log; + +If notifications are getting through then you should see something like. + + + >log + =[ + "{\"t\":\"call\",\"cmd\"" ... "r\":\"0191xxxxxxx\"}", + "{\"t\":\"call\",\"cmd\"" ... "r\":\"0191xxxxxxx\"}" + ] + + +IMPORTANT: Now reset your Bangle using a BTN3 long press so that the GB() function is restored. + +## References + +[Bangle Gadgetbridge Page](https://www.espruino.com/Gadgetbridge) + +[Gadgetbridge Project Home](https://codeberg.org/Freeyourgadget/Gadgetbridge/wiki/Home) + diff --git a/apps/launch/ChangeLog b/apps/launch/ChangeLog index b56c9f6bb..09569d8da 100644 --- a/apps/launch/ChangeLog +++ b/apps/launch/ChangeLog @@ -4,3 +4,4 @@ 0.04: Now displays widgets 0.05: Use g.theme for colours 0.06: Use Bangle.setUI for buttons +0.07: Theme colours fix \ No newline at end of file diff --git a/apps/launch/app.js b/apps/launch/app.js index ab1a89fc0..449e16e62 100644 --- a/apps/launch/app.js +++ b/apps/launch/app.js @@ -33,8 +33,10 @@ function drawMenu() { if (i+menuScroll==selected) { g.setColor(g.theme.bgH).fillRect(0,y,w-1,y+63); g.setColor(g.theme.fgH).drawRect(0,y,w-1,y+63); - } else - g.clearRect(0,y,w-1,y+63); + } else { + g.clearRect(0, y, w-1, y+63); + g.setColor(g.theme.fg); + } g.drawString(app.name,64,y+32); var icon=undefined; if (app.icon) icon = s.read(app.icon); diff --git a/apps/notifyfs/ChangeLog b/apps/notifyfs/ChangeLog index 1c39bcbd5..cf0a13866 100644 --- a/apps/notifyfs/ChangeLog +++ b/apps/notifyfs/ChangeLog @@ -9,3 +9,4 @@ 0.09: Add onHide callback 0.10: Ensure dismissing a notification dismissal doesn't enter launcher if in clock mode 0.11: Improvements to help notifications work with themes, Bangle.js 2 support +0.12: More use of themes, title now uses theme highlight colors, font adjusts diff --git a/apps/notifyfs/notify.js b/apps/notifyfs/notify.js index a45d889f0..9cadbb124 100644 --- a/apps/notifyfs/notify.js +++ b/apps/notifyfs/notify.js @@ -1,7 +1,7 @@ let oldg; let id = null; let hideCallback = null; - +const titleFont = g.getWidth() / 8; /** * See notify/notify.js */ @@ -63,8 +63,8 @@ exports.show = function(options) { // top bar if (options.title||options.src) { const title = options.title || options.src; - g.setColor(options.titleBgColor||"#333").fillRect(x, y, x+w-1, y+30); - g.setColor(g.theme.fg).setFontAlign(-1, -1, 0).setFont("6x8", 3); + g.setColor(options.titleBgColor||g.theme.bgH).fillRect(x, y, x+w-1, y+30); + g.setColor(g.theme.fgH).setFontAlign(-1, -1, 0).setFont("Vector", titleFont); g.drawString(title.trim().substring(0, 13), x+5, y+3); if (options.title && options.src) { g.setColor(g.theme.fg).setFontAlign(1, 1, 0).setFont("6x8", 2); diff --git a/apps/slidingtext/slidingtext.locale.es.js b/apps/slidingtext/slidingtext.locale.es.js index e1f3bc18b..1b6f6d11b 100644 --- a/apps/slidingtext/slidingtext.locale.es.js +++ b/apps/slidingtext/slidingtext.locale.es.js @@ -7,7 +7,7 @@ const spanishNumberStr = [ ["ZERO"], // 0 ["CUATRO",''], //4 ["CINCO",''], //5 ["SEIS",''], //6 - ["SEITO",''], //7 + ["SIETE",''], //7 ["OCHO",''], //8 ["NUEVE",''], // 9, ["DIEZ",''], // 10 @@ -20,7 +20,7 @@ const spanishNumberStr = [ ["ZERO"], // 0 ["DIECI",'SIETE'], // 17 ["DIECI",'OCHO'], // 18 ["DIECI",'NEUVE'], // 19 - ["VEINTA",''], // 20 + ["VEINTE",''], // 20 ["VEINTI",'UNO'], // 21 ["VEINTI",'DOS'], // 22 ["VEINTI",'TRES'], // 23 @@ -74,4 +74,4 @@ class SpanishDateFormatter extends DateFormatter { } } -module.exports = SpanishDateFormatter; \ No newline at end of file +module.exports = SpanishDateFormatter; diff --git a/apps/weather/ChangeLog b/apps/weather/ChangeLog index fd5d4d146..09e159045 100644 --- a/apps/weather/ChangeLog +++ b/apps/weather/ChangeLog @@ -4,4 +4,5 @@ 0.05: Add wind direction. 0.06: Use setUI for launcher. 0.07: Add theme support and unknown icon. -0.08: Refactor and reduce widget ram usage. \ No newline at end of file +0.08: Refactor and reduce widget ram usage. +0.09: Fix crash when weather.json is absent. \ No newline at end of file diff --git a/apps/weather/lib.js b/apps/weather/lib.js index f08df4a4a..299009e74 100644 --- a/apps/weather/lib.js +++ b/apps/weather/lib.js @@ -47,7 +47,7 @@ global.GB = (event) => { }; exports.get = function() { - return storage.readJSON('weather.json').weather; + return (storage.readJSON('weather.json')||{}).weather; } scheduleExpiry(storage.readJSON('weather.json')||{});