Merge branch 'espruino:master' into master

pull/925/head
Ronin0000 2021-10-04 07:31:25 -07:00 committed by GitHub
commit c7b723f87e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 192 additions and 164 deletions

View File

@ -42,7 +42,7 @@
"name": "Launcher (Default)", "name": "Launcher (Default)",
"shortName":"Launcher", "shortName":"Launcher",
"icon": "app.png", "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.", "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", "tags": "tool,system,launcher,b2",
"type":"launch", "type":"launch",
@ -107,7 +107,7 @@
"name": "Fullscreen Notifications", "name": "Fullscreen Notifications",
"shortName":"Notifications", "shortName":"Notifications",
"icon": "notify.png", "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.", "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", "tags": "widget,b2",
"type": "notify", "type": "notify",
@ -585,7 +585,7 @@
{ "id": "weather", { "id": "weather",
"name": "Weather", "name": "Weather",
"icon": "icon.png", "icon": "icon.png",
"version":"0.08", "version":"0.09",
"description": "Show Gadgetbridge weather report", "description": "Show Gadgetbridge weather report",
"readme": "readme.md", "readme": "readme.md",
"tags": "widget,outdoors", "tags": "widget,outdoors",
@ -1381,7 +1381,7 @@
{ "id": "barclock", { "id": "barclock",
"name": "Bar Clock", "name": "Bar Clock",
"icon": "clock-bar.png", "icon": "clock-bar.png",
"version":"0.07", "version":"0.08",
"description": "A simple digital clock showing seconds as a bar", "description": "A simple digital clock showing seconds as a bar",
"tags": "clock", "tags": "clock",
"type":"clock", "type":"clock",
@ -2058,7 +2058,7 @@
"name": "Find Phone", "name": "Find Phone",
"shortName":"Find Phone", "shortName":"Find Phone",
"icon": "app.png", "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.", "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", "tags": "tool,android",
"readme": "README.md", "readme": "README.md",

View File

@ -5,3 +5,4 @@
0.05: Clock does not start if app Languages is not installed 0.05: Clock does not start if app Languages is not installed
0.06: Improve accuracy 0.06: Improve accuracy
0.07: Update to use Bangle.setUI instead of setWatch 0.07: Update to use Bangle.setUI instead of setWatch
0.08: Use theme colors, Layout library

View File

@ -3,167 +3,102 @@
* A simple digital clock showing seconds as a bar * A simple digital clock showing seconds as a bar
**/ **/
// Check settings for what type our clock should be // Check settings for what type our clock should be
const is12Hour = (require('Storage').readJSON('setting.json', 1) || {})['12hour'] const is12Hour = (require("Storage").readJSON("setting.json", 1) || {})["12hour"];
let locale = require('locale') let locale = require("locale");
{ // add some more info to locale { // add some more info to locale
let date = new Date() let date = new Date();
date.setFullYear(1111) date.setFullYear(1111);
date.setMonth(1, 3) // februari: months are zero-indexed date.setMonth(1, 3); // februari: months are zero-indexed
const localized = locale.date(date, true) const localized = locale.date(date, true);
locale.dayFirst = /3.*2/.test(localized) locale.dayFirst = /3.*2/.test(localized);
locale.hasMeridian = false locale.hasMeridian = false;
if(typeof locale.meridian === 'function') { // function does not exists if languages app is not installed if (typeof locale.meridian==="function") { // function does not exist if languages app is not installed
locale.hasMeridian = (locale.meridian(date) !== '') locale.hasMeridian = (locale.meridian(date)!=="");
} }
} }
const screen = { Bangle.loadWidgets();
width: g.getWidth(), function renderBar(l) {
height: g.getWidth(), if (!this.fraction) {
middle: g.getWidth() / 2, // zero-size fillRect stills draws one line of pixels, we don't want that
center: g.getHeight() / 2, return;
}
const width = this.fraction*l.w;
g.fillRect(l.x, l.y, width-1, l.y+l.height-1);
} }
// hardcoded "settings" const Layout = require("Layout");
const settings = { const layout = new Layout({
time: { type: "v", c: [
color: -1, {
font: '6x8', type: "h", c: [
size: (is12Hour && locale.hasMeridian) ? 6 : 8, {id: "time", label: "88:88", type: "txt", font: "6x8:5", bgCol: g.theme.bg}, // size updated below
middle: screen.middle, {id: "ampm", label: " ", type: "txt", font: "6x8:2", bgCol: g.theme.bg},
center: screen.center, ],
ampm: {
color: -1,
font: '6x8',
size: 2,
}, },
}, {id: "bar", type: "custom", fraction: 0, fillx: 1, height: 6, col: g.theme.fg2, render: renderBar},
date: { {height: 40},
color: -1, {id: "date", type: "txt", font: "10%", valign: 1},
font: 'Vector', ],
size: 20, }, false, {lazy: true});
middle: screen.height - 20, // at bottom of screen // adjustments based on screen size and whether we display am/pm
center: screen.center, let thickness; // bar thickness, same as time font "pixel block" size
}, if (is12Hour) {
bar: { // Maximum font size = (<screen width> - <ampm: 2chars * (2*6)px>) / (5chars * 6px)
color: -1, thickness = Math.floor((g.getWidth()-24)/(5*6));
top: 155, // just below time } else {
thickness: 6, // matches 24h time "pixel" size 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 function timeText(date) {
const timeText = function (date) {
if (!is12Hour) { if (!is12Hour) {
return locale.time(date, true) return locale.time(date, true);
} }
const date12 = new Date(date.getTime()) const date12 = new Date(date.getTime());
const hours = date12.getHours() const hours = date12.getHours();
if (hours === 0) { if (hours===0) {
date12.setHours(12) date12.setHours(12);
} else if (hours > 12) { } else if (hours>12) {
date12.setHours(hours - 12) date12.setHours(hours-12);
} }
return locale.time(date12, true) return locale.time(date12, true);
} }
const ampmText = function (date) { function ampmText(date) {
return is12Hour ? locale.meridian(date) : '' return (is12Hour && locale.hasMeridian)? locale.meridian(date) : "";
} }
function dateText(date) {
const dateText = function (date) {
const dayName = locale.dow(date, true), const dayName = locale.dow(date, true),
month = locale.month(date, true), month = locale.month(date, true),
day = date.getDate() day = date.getDate();
const dayMonth = locale.dayFirst ? `${day} ${month}` : `${month} ${day}` const dayMonth = locale.dayFirst ? `${day} ${month}` : `${month} ${day}`;
return `${dayName} ${dayMonth}` return `${dayName} ${dayMonth}`;
} }
const drawDateTime = function (date) { draw = function draw() {
const t = settings.time if (!Bangle.isLCDOn()) {return;} // no drawing, also no new update scheduled
g.setColor(t.color) const date = new Date();
g.setFont(t.font, t.size) layout.time.label = timeText(date);
g.setFontAlign(0, 0) // centered layout.ampm.label = ampmText(date);
g.drawString(timeText(date), t.center, t.middle, true) layout.date.label = dateText(date);
if (is12Hour && locale.hasMeridian) { const SECONDS_PER_MINUTE = 60;
const a = settings.time.ampm layout.bar.fraction = date.getSeconds()/SECONDS_PER_MINUTE;
g.setColor(a.color) layout.render();
g.setFont(a.font, a.size) // schedule update at start of next second
g.setFontAlign(1, -1) // right top const millis = date.getMilliseconds();
// at right edge of screen, aligned with time bottom setTimeout(draw, 1000-millis);
const left = screen.width - a.size * 2, };
top = t.middle + t.size - a.size
g.drawString(ampmText(date), left, top, true)
}
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 // Show launcher when button pressed
Bangle.setUI("clock"); Bangle.setUI("clock");
Bangle.on("lcdPower", function(on) {
Bangle.on('lcdPower', function (on) {
if (on) { if (on) {
start() draw();
} else {
stop()
} }
}) });
start() g.reset().clear();
Bangle.drawWidgets();
draw();

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

View File

@ -1,2 +1,3 @@
0.01: First Version 0.01: First Version
0.02: Remove HID requirement, update screen 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

View File

@ -6,3 +6,8 @@ Ring your phone via GadgetBridge if you lost it somewhere.
2. Lose phone 2. Lose phone
3. Open app 3. Open app
4. Click any button or screen 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.

View File

@ -1,13 +1,15 @@
//notify your phone //notify your phone
const fontSize = g.getWidth() / 8;
var finding = false; var finding = false;
function draw() { function draw() {
// show message // show message
g.clear(1); g.clear(g.theme.bg);
require("Font8x12").add(Graphics); g.setColor(g.theme.fg);
g.setFont("8x12",3); g.setFont("Vector", fontSize);
g.setFontAlign(0,0); g.setFontAlign(0,0);
if (finding) { if (finding) {
g.drawString("Finding...", g.getWidth()/2, (g.getHeight()/2)-20); g.drawString("Finding...", g.getWidth()/2, (g.getHeight()/2)-20);
g.drawString("Click to stop", 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(); g.flip();
} }
function findPhone(v) {
Bluetooth.println(JSON.stringify({t:"findPhone", n:v}));
}
function find(){ function find(){
finding = !finding; finding = !finding;
draw(); draw();
Bluetooth.println("\n"+JSON.stringify({t:"findPhone", n:finding})); findPhone(finding);
} }
draw(); draw();
//register all buttons and screen to find phone //register all buttons and screen to find phone
setWatch(find, BTN1, {repeat:true}); setWatch(find, BTN1, {repeat:true});
setWatch(find, BTN2, {repeat:true});
setWatch(find, BTN3, {repeat:true}); if (process.env.HWVERSION == 1) {
setWatch(find, BTN4, {repeat:true}); setWatch(find, BTN2, {repeat:true});
setWatch(find, BTN5, {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
}
});
}

View File

@ -52,3 +52,62 @@ Activity reporting
You'll need a Gadgetbridge release *after* version 0.50.0 for Actvity Reporting to be enabled. 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` 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)

View File

@ -4,3 +4,4 @@
0.04: Now displays widgets 0.04: Now displays widgets
0.05: Use g.theme for colours 0.05: Use g.theme for colours
0.06: Use Bangle.setUI for buttons 0.06: Use Bangle.setUI for buttons
0.07: Theme colours fix

View File

@ -33,8 +33,10 @@ function drawMenu() {
if (i+menuScroll==selected) { if (i+menuScroll==selected) {
g.setColor(g.theme.bgH).fillRect(0,y,w-1,y+63); g.setColor(g.theme.bgH).fillRect(0,y,w-1,y+63);
g.setColor(g.theme.fgH).drawRect(0,y,w-1,y+63); g.setColor(g.theme.fgH).drawRect(0,y,w-1,y+63);
} else } else {
g.clearRect(0,y,w-1,y+63); g.clearRect(0, y, w-1, y+63);
g.setColor(g.theme.fg);
}
g.drawString(app.name,64,y+32); g.drawString(app.name,64,y+32);
var icon=undefined; var icon=undefined;
if (app.icon) icon = s.read(app.icon); if (app.icon) icon = s.read(app.icon);

View File

@ -9,3 +9,4 @@
0.09: Add onHide callback 0.09: Add onHide callback
0.10: Ensure dismissing a notification dismissal doesn't enter launcher if in clock mode 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.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

View File

@ -1,7 +1,7 @@
let oldg; let oldg;
let id = null; let id = null;
let hideCallback = null; let hideCallback = null;
const titleFont = g.getWidth() / 8;
/** /**
* See notify/notify.js * See notify/notify.js
*/ */
@ -63,8 +63,8 @@ exports.show = function(options) {
// top bar // top bar
if (options.title||options.src) { if (options.title||options.src) {
const title = 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(options.titleBgColor||g.theme.bgH).fillRect(x, y, x+w-1, y+30);
g.setColor(g.theme.fg).setFontAlign(-1, -1, 0).setFont("6x8", 3); g.setColor(g.theme.fgH).setFontAlign(-1, -1, 0).setFont("Vector", titleFont);
g.drawString(title.trim().substring(0, 13), x+5, y+3); g.drawString(title.trim().substring(0, 13), x+5, y+3);
if (options.title && options.src) { if (options.title && options.src) {
g.setColor(g.theme.fg).setFontAlign(1, 1, 0).setFont("6x8", 2); g.setColor(g.theme.fg).setFontAlign(1, 1, 0).setFont("6x8", 2);

View File

@ -7,7 +7,7 @@ const spanishNumberStr = [ ["ZERO"], // 0
["CUATRO",''], //4 ["CUATRO",''], //4
["CINCO",''], //5 ["CINCO",''], //5
["SEIS",''], //6 ["SEIS",''], //6
["SEITO",''], //7 ["SIETE",''], //7
["OCHO",''], //8 ["OCHO",''], //8
["NUEVE",''], // 9, ["NUEVE",''], // 9,
["DIEZ",''], // 10 ["DIEZ",''], // 10
@ -20,7 +20,7 @@ const spanishNumberStr = [ ["ZERO"], // 0
["DIECI",'SIETE'], // 17 ["DIECI",'SIETE'], // 17
["DIECI",'OCHO'], // 18 ["DIECI",'OCHO'], // 18
["DIECI",'NEUVE'], // 19 ["DIECI",'NEUVE'], // 19
["VEINTA",''], // 20 ["VEINTE",''], // 20
["VEINTI",'UNO'], // 21 ["VEINTI",'UNO'], // 21
["VEINTI",'DOS'], // 22 ["VEINTI",'DOS'], // 22
["VEINTI",'TRES'], // 23 ["VEINTI",'TRES'], // 23
@ -74,4 +74,4 @@ class SpanishDateFormatter extends DateFormatter {
} }
} }
module.exports = SpanishDateFormatter; module.exports = SpanishDateFormatter;

View File

@ -4,4 +4,5 @@
0.05: Add wind direction. 0.05: Add wind direction.
0.06: Use setUI for launcher. 0.06: Use setUI for launcher.
0.07: Add theme support and unknown icon. 0.07: Add theme support and unknown icon.
0.08: Refactor and reduce widget ram usage. 0.08: Refactor and reduce widget ram usage.
0.09: Fix crash when weather.json is absent.

View File

@ -47,7 +47,7 @@ global.GB = (event) => {
}; };
exports.get = function() { exports.get = function() {
return storage.readJSON('weather.json').weather; return (storage.readJSON('weather.json')||{}).weather;
} }
scheduleExpiry(storage.readJSON('weather.json')||{}); scheduleExpiry(storage.readJSON('weather.json')||{});