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)",
"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",

View File

@ -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

View File

@ -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 = (<screen width> - <ampm: 2chars * (2*6)px>) / (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();

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.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
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.

View File

@ -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
}
});
}

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.
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.05: Use g.theme for colours
0.06: Use Bangle.setUI for buttons
0.07: Theme colours fix

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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;
module.exports = SpanishDateFormatter;

View File

@ -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.
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() {
return storage.readJSON('weather.json').weather;
return (storage.readJSON('weather.json')||{}).weather;
}
scheduleExpiry(storage.readJSON('weather.json')||{});