messages 0.29: Support for the setUI 'back' icon in the top left

master
Gordon Williams 2022-04-01 09:49:57 +01:00
parent 7fc1747a3f
commit 45cde94a26
4 changed files with 23 additions and 40 deletions

View File

@ -41,3 +41,4 @@
0.26: Setting to auto-open music 0.26: Setting to auto-open music
0.27: Add 'mark all read' option to popup menu (fix #1624) 0.27: Add 'mark all read' option to popup menu (fix #1624)
0.28: Option to auto-unlock the watch when a new message arrives 0.28: Option to auto-unlock the watch when a new message arrives
0.29: Support for the setUI 'back' icon in the top left

View File

@ -13,11 +13,11 @@
/* For example for maps: /* For example for maps:
// a message // a message
{"t":"add","id":1575479849,"src":"Hangouts","title":"A Name","body":"message contents"} require("messages").pushMessage({"t":"add","id":1575479849,"src":"Hangouts","title":"A Name","body":"message contents"})
// maps // maps
{"t":"add","id":1,"src":"Maps","title":"0 yd - High St","body":"Campton - 11:48 ETA","img":"GhqBAAAMAAAHgAAD8AAB/gAA/8AAf/gAP/8AH//gD/98B//Pg/4B8f8Afv+PP//n3/f5//j+f/wfn/4D5/8Aef+AD//AAf/gAD/wAAf4AAD8AAAeAAADAAA="} require("messages").pushMessage({"t":"add","id":1,"src":"Maps","title":"0 yd - High St","body":"Campton - 11:48 ETA","img":"GhqBAAAMAAAHgAAD8AAB/gAA/8AAf/gAP/8AH//gD/98B//Pg/4B8f8Afv+PP//n3/f5//j+f/wfn/4D5/8Aef+AD//AAf/gAD/wAAf4AAD8AAAeAAADAAA="});
// call // call
{"t":"add","id":"call","src":"Phone","name":"Bob","number":"12421312",positive:true,negative:true} require("messages").pushMessage({"t":"add","id":"call","src":"Phone","title":"Bob","body":"12421312",positive:true,negative:true})
*/ */
var Layout = require("Layout"); var Layout = require("Layout");
@ -66,9 +66,6 @@ function saveMessages() {
require("Storage").writeJSON("messages.json",MESSAGES) require("Storage").writeJSON("messages.json",MESSAGES)
} }
function getBackImage() {
return atob("FhYBAAAAEAAAwAAHAAA//wH//wf//g///BwB+DAB4EAHwAAPAAA8AADwAAPAAB4AAHgAB+AH/wA/+AD/wAH8AA==");
}
function getNotificationImage() { function getNotificationImage() {
return atob("HBKBAD///8H///iP//8cf//j4//8f5//j/x/8//j/H//H4//4PB//EYj/44HH/Hw+P4//8fH//44///xH///g////A=="); return atob("HBKBAD///8H///iP//8cf//j4//8f5//j/x/8//j/H//H4//4PB//EYj/44HH/Hw+P4//8fH//44///xH///g////A==");
} }
@ -108,7 +105,6 @@ function getMessageImage(msg) {
if (s=="whatsapp") return atob("GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA=="); if (s=="whatsapp") return atob("GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA==");
if (s=="wordfeud") return atob("GBgCWqqqqqqlf//////9v//////+v/////++v/////++v8///Lu+v8///L++v8///P/+v8v//P/+v9v//P/+v+fx/P/+v+Pk+P/+v/PN+f/+v/POuv/+v/Ofdv/+v/NvM//+v/I/Y//+v/k/k//+v/i/w//+v/7/6//+v//////+v//////+f//////9Wqqqqqql"); if (s=="wordfeud") return atob("GBgCWqqqqqqlf//////9v//////+v/////++v/////++v8///Lu+v8///L++v8///P/+v8v//P/+v9v//P/+v+fx/P/+v+Pk+P/+v/PN+f/+v/POuv/+v/Ofdv/+v/NvM//+v/I/Y//+v/k/k//+v/i/w//+v/7/6//+v//////+v//////+f//////9Wqqqqqql");
if (msg.id=="music") return atob("FhaBAH//+/////////////h/+AH/4Af/gB/+H3/7/f/v9/+/3/7+f/vB/w8H+Dwf4PD/x/////////////3//+A="); if (msg.id=="music") return atob("FhaBAH//+/////////////h/+AH/4Af/gB/+H3/7/f/v9/+/3/7+f/vB/w8H+Dwf4PD/x/////////////3//+A=");
if (msg.id=="back") return getBackImage();
return getNotificationImage(); return getNotificationImage();
} }
function getMessageImageCol(msg,def) { function getMessageImageCol(msg,def) {
@ -170,13 +166,13 @@ function showMapMessage(msg) {
]}); ]});
g.clearRect(Bangle.appRect); g.clearRect(Bangle.appRect);
layout.render(); layout.render();
Bangle.setUI("updown",function() { function back() { // mark as not new and return to menu
// any input to mark as not new and return to menu
msg.new = false; msg.new = false;
saveMessages(); saveMessages();
layout = undefined; layout = undefined;
checkMessages({clockIfNoMsg:1,clockIfAllRead:1,showMsgIfUnread:1,openMusic:0}); checkMessages({clockIfNoMsg:1,clockIfAllRead:1,showMsgIfUnread:1,openMusic:0});
}); }
Bangle.setUI({mode:"updown", back: back}, back); // any input takes us back
} }
var updateLabelsInterval; var updateLabelsInterval;
@ -199,8 +195,6 @@ function showMusicMessage(msg) {
var sliceLength = offset + maxLen > text.length ? text.length - offset : maxLen; var sliceLength = offset + maxLen > text.length ? text.length - offset : maxLen;
return text.substr(offset, sliceLength).padEnd(maxLen, " "); return text.substr(offset, sliceLength).padEnd(maxLen, " ");
} }
function back() { function back() {
clearInterval(updateLabelsInterval); clearInterval(updateLabelsInterval);
updateLabelsInterval = undefined; updateLabelsInterval = undefined;
@ -229,7 +223,6 @@ function showMusicMessage(msg) {
layout = new Layout({ type:"v", c: [ layout = new Layout({ type:"v", c: [
{type:"h", fillx:1, bgCol:g.theme.bg2, col: g.theme.fg2, c: [ {type:"h", fillx:1, bgCol:g.theme.bg2, col: g.theme.fg2, c: [
{ type:"btn", src:getBackImage, cb:back },
{ type:"v", fillx:1, c: [ { type:"v", fillx:1, c: [
{ type:"txt", font:fontMedium, bgCol:g.theme.bg2, label:artistName, pad:2, id:"artist" }, { type:"txt", font:fontMedium, bgCol:g.theme.bg2, label:artistName, pad:2, id:"artist" },
{ type:"txt", font:fontMedium, bgCol:g.theme.bg2, label:albumName, pad:2, id:"album" } { type:"txt", font:fontMedium, bgCol:g.theme.bg2, label:albumName, pad:2, id:"album" }
@ -242,7 +235,7 @@ function showMusicMessage(msg) {
{type:"btn", pad:8, label:"\0"+atob("EhKBAMAB+AB/gB/wB/8B/+B//B//x//5//5//x//B/+B/8B/wB/gB+AB8ABw"), cb:()=>Bangle.musicControl("next")}, // next {type:"btn", pad:8, label:"\0"+atob("EhKBAMAB+AB/gB/wB/8B/+B//B//x//5//5//x//B/+B/8B/wB/gB+AB8ABw"), cb:()=>Bangle.musicControl("next")}, // next
]}:{}, ]}:{},
{type:"txt", font:"6x8:2", label:msg.dur?fmtTime(msg.dur):"--:--" } {type:"txt", font:"6x8:2", label:msg.dur?fmtTime(msg.dur):"--:--" }
]}); ]}, { back : back });
g.clearRect(Bangle.appRect); g.clearRect(Bangle.appRect);
layout.render(); layout.render();
@ -277,12 +270,9 @@ function showMessageScroller(msg) {
}, select : function(idx) { }, select : function(idx) {
if (idx>=lines.length-2) if (idx>=lines.length-2)
showMessage(msg.id); showMessage(msg.id);
} },
back : () => showMessage(msg.id)
}); });
// ensure button-press on Bangle.js 2 takes us back
if (process.env.HWVERSION>1) Bangle.btnWatches = [
setWatch(() => showMessage(msg.id), BTN1, {repeat:1,edge:"falling"})
];
} }
function showMessageSettings(msg) { function showMessageSettings(msg) {
@ -370,10 +360,8 @@ function showMessage(msgid) {
checkMessages({clockIfNoMsg:1,clockIfAllRead:0,showMsgIfUnread:0,openMusic:openMusic}); checkMessages({clockIfNoMsg:1,clockIfAllRead:0,showMsgIfUnread:0,openMusic:openMusic});
} }
var buttons = [ var buttons = [
{type:"btn", src:getBackImage(), cb:goBack} // back
]; ];
if (msg.positive) { if (msg.positive) {
buttons.push({fillx:1});
buttons.push({type:"btn", src:getPosImage(), cb:()=>{ buttons.push({type:"btn", src:getPosImage(), cb:()=>{
msg.new = false; saveMessages(); msg.new = false; saveMessages();
cancelReloadTimeout(); // don't auto-reload to clock now cancelReloadTimeout(); // don't auto-reload to clock now
@ -382,7 +370,7 @@ function showMessage(msgid) {
}}); }});
} }
if (msg.negative) { if (msg.negative) {
buttons.push({fillx:1}); if (buttons.length) buttons.push({width:32}); // nasty hack...
buttons.push({type:"btn", src:getNegImage(), cb:()=>{ buttons.push({type:"btn", src:getNegImage(), cb:()=>{
msg.new = false; saveMessages(); msg.new = false; saveMessages();
cancelReloadTimeout(); // don't auto-reload to clock now cancelReloadTimeout(); // don't auto-reload to clock now
@ -394,27 +382,23 @@ function showMessage(msgid) {
layout = new Layout({ type:"v", c: [ layout = new Layout({ type:"v", c: [
{type:"h", fillx:1, bgCol:g.theme.bg2, col: g.theme.fg2, c: [ {type:"h", fillx:1, bgCol:g.theme.bg2, col: g.theme.fg2, c: [
{ type:"btn", src:getMessageImage(msg), col:getMessageImageCol(msg), pad: 3, cb:()=>{
cancelReloadTimeout(); // don't auto-reload to clock now
showMessageSettings(msg);
}},
{ type:"v", fillx:1, c: [ { type:"v", fillx:1, c: [
{type:"txt", font:fontSmall, label:msg.src||/*LANG*/"Message", bgCol:g.theme.bg2, col: g.theme.fg2, fillx:1, pad:2, halign:1 }, {type:"txt", font:fontSmall, label:msg.src||/*LANG*/"Message", bgCol:g.theme.bg2, col: g.theme.fg2, fillx:1, pad:2, halign:1 },
title?{type:"txt", font:titleFont, label:title, bgCol:g.theme.bg2, col: g.theme.fg2, fillx:1, pad:2 }:{}, title?{type:"txt", font:titleFont, label:title, bgCol:g.theme.bg2, col: g.theme.fg2, fillx:1, pad:2 }:{},
]}, ]},
{ type:"btn", src:getMessageImage(msg), col:getMessageImageCol(msg), pad: 3, cb:()=>{
cancelReloadTimeout(); // don't auto-reload to clock now
showMessageSettings(msg);
}},
]}, ]},
{type:"txt", font:bodyFont, label:body, fillx:1, filly:1, pad:2, cb:()=>{ {type:"txt", font:bodyFont, label:body, fillx:1, filly:1, pad:2, cb:()=>{
// allow tapping to show a larger version // allow tapping to show a larger version
showMessageScroller(msg); showMessageScroller(msg);
} }, } },
{type:"h",fillx:1, c: buttons} {type:"h",fillx:1, c: buttons}
]}); ]},{back:goBack});
g.clearRect(Bangle.appRect); g.clearRect(Bangle.appRect);
layout.render(); layout.render();
// ensure button-press on Bangle.js 2 takes us back
if (process.env.HWVERSION>1) Bangle.btnWatches = [
setWatch(goBack, BTN1, {repeat:1,edge:"falling"})
];
} }
@ -452,12 +436,11 @@ function checkMessages(options) {
// Otherwise show a menu // Otherwise show a menu
E.showScroller({ E.showScroller({
h : 48, h : 48,
c : Math.max(MESSAGES.length+1,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11) c : Math.max(MESSAGES.length,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11)
draw : function(idx, r) {"ram" draw : function(idx, r) {"ram"
var msg = MESSAGES[idx-1]; var msg = MESSAGES[idx];
if (msg && msg.new) g.setBgColor(g.theme.bgH).setColor(g.theme.fgH); if (msg && msg.new) g.setBgColor(g.theme.bgH).setColor(g.theme.fgH);
else g.setColor(g.theme.fg); else g.setColor(g.theme.fg);
if (idx==0) msg = {id:"back", title:"< Back"};
if (!msg) return; if (!msg) return;
var x = r.x+2, title = msg.title, body = msg.body; var x = r.x+2, title = msg.title, body = msg.body;
var img = getMessageImage(msg); var img = getMessageImage(msg);
@ -486,13 +469,12 @@ function checkMessages(options) {
if (!longBody && msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2); if (!longBody && msg.src) g.setFontAlign(1,1).setFont("6x8").drawString(msg.src, r.x+r.w-2, r.y+r.h-2);
g.setColor("#888").fillRect(r.x,r.y+r.h-1,r.x+r.w-1,r.y+r.h-1); // dividing line between items g.setColor("#888").fillRect(r.x,r.y+r.h-1,r.x+r.w-1,r.y+r.h-1); // dividing line between items
}, },
select : idx => { select : idx => showMessage(MESSAGES[idx].id),
if (idx==0) load(); back : () => load()
else showMessage(MESSAGES[idx-1].id);
}
}); });
} }
function cancelReloadTimeout() { function cancelReloadTimeout() {
if (!unreadTimeout) return; if (!unreadTimeout) return;
clearTimeout(unreadTimeout); clearTimeout(unreadTimeout);

View File

@ -1,7 +1,7 @@
{ {
"id": "messages", "id": "messages",
"name": "Messages", "name": "Messages",
"version": "0.28", "version": "0.29",
"description": "App to display notifications from iOS and Gadgetbridge/Android", "description": "App to display notifications from iOS and Gadgetbridge/Android",
"icon": "app.png", "icon": "app.png",
"type": "app", "type": "app",

View File

@ -59,7 +59,7 @@ options is an object containing:
* `label` - the text on the button * `label` - the text on the button
* `cb` - a callback function * `cb` - a callback function
* `cbl` - a callback function for long presses * `cbl` - a callback function for long presses
* `back` - a callback function, passed as `back` into Bangle.setUI * `back` - a callback function, passed as `back` into Bangle.setUI (which usually adds an icon in the top left)
If automatic lazy rendering is enabled, calls to `layout.render()` will attempt to automatically If automatic lazy rendering is enabled, calls to `layout.render()` will attempt to automatically
determine what objects have changed or moved, clear their previous locations, and re-render just those objects. determine what objects have changed or moved, clear their previous locations, and re-render just those objects.