mirror of https://github.com/espruino/BangleApps
notifyfs: Update notify API for #527
Also some cleanup: - fall back to "src" if title is missing - move message-splitting into separate function - make icon position depend on whether titlebar is presentpull/530/head
parent
7bb98d38e0
commit
48bf67dfb1
|
@ -93,7 +93,7 @@
|
|||
"name": "Fullscreen Notifications",
|
||||
"shortName":"Notifications",
|
||||
"icon": "notify.png",
|
||||
"version":"0.03",
|
||||
"version":"0.04",
|
||||
"description": "A handler for displaying notifications that displays them fullscreen. This may not fully restore the screen after on some apps. See `Notifications (default)` for more information about the notifications library.",
|
||||
"tags": "widget",
|
||||
"type": "notify",
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
0.01: New Library!
|
||||
0.02: Add notification ID option
|
||||
0.03: Fix custom render callback
|
||||
0.03: Fix custom render callback
|
||||
0.04: Pass `area{x,y,w,h}` to render callback instead of just `y`
|
|
@ -1,6 +1,32 @@
|
|||
var pos = 0;
|
||||
var oldg;
|
||||
var id = null;
|
||||
let oldg;
|
||||
let id = null;
|
||||
|
||||
/**
|
||||
* See notify/notify.js
|
||||
*/
|
||||
function fitWords(text,rows,width) {
|
||||
// We never need more than rows*width characters anyway, split by any whitespace
|
||||
const words = text.trim().substr(0,rows*width).split(/\s+/);
|
||||
let row=1,len=0,limit=width;
|
||||
let result = "";
|
||||
for (let word of words) {
|
||||
// len==0 means first word of row, after that we also add a space
|
||||
if ((len?len+1:0)+word.length > limit) {
|
||||
if (row>=rows) {
|
||||
result += "...";
|
||||
break;
|
||||
}
|
||||
result += "\n";
|
||||
len=0;
|
||||
row++;
|
||||
if (row===rows) limit -= 3; // last row needs space for "..."
|
||||
}
|
||||
result += (len?" ":"") + word;
|
||||
len += (len?1:0) + word.length;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
options = {
|
||||
|
@ -19,56 +45,49 @@ exports.show = function(options) {
|
|||
options = options||{};
|
||||
if (options.on===undefined) options.on=true;
|
||||
id = ("id" in options)?options.id:null;
|
||||
var h = options.size||120;
|
||||
let size = options.size||120;
|
||||
if (size>120) {size=120}
|
||||
Bangle.setLCDMode("direct");
|
||||
var y = 40;
|
||||
var x = 4;
|
||||
// clear area
|
||||
let x = 0,
|
||||
y = 0,
|
||||
w = 240,
|
||||
h = 240;
|
||||
// clear screen
|
||||
g.clear(1);
|
||||
// top bar
|
||||
var top = 0;
|
||||
if (options.title) {
|
||||
g.setColor(0x39C7).fillRect(0, y, 239, y+30);
|
||||
if (options.title||options.src) {
|
||||
y=40;h=size;
|
||||
const title = options.title || options.src
|
||||
g.setColor(0x39C7).fillRect(x, y, x+w-1, y+30);
|
||||
g.setColor(-1).setFontAlign(-1, -1, 0).setFont("6x8", 3);
|
||||
g.drawString(options.title.trim().substring(0, 13), 5, y+3);
|
||||
y+=30;
|
||||
}
|
||||
if (options.src) {
|
||||
g.setColor(-1).setFontAlign(1, 1, 0).setFont("6x8", 2);
|
||||
g.drawString(options.src.substring(0, 10), 235, y-32);
|
||||
g.drawString(title.trim().substring(0, 13), x+5, y+3);
|
||||
if (options.title && options.src) {
|
||||
g.setColor(-1).setFontAlign(1, 1, 0).setFont("6x8", 2);
|
||||
// above drawing area, but we are fullscreen
|
||||
g.drawString(options.src.substring(0, 10), x+235, y-32);
|
||||
}
|
||||
y += 30;h -= 30;
|
||||
}
|
||||
if (options.icon) {
|
||||
let i = options.icon;
|
||||
g.drawImage(i, x,y+4);
|
||||
if ("string"==typeof i) x += i.charCodeAt(0);
|
||||
else x += i[0];
|
||||
let i = options.icon, iw,ih;
|
||||
if ("string"==typeof i) {iw=i.charCodeAt(0); ih=i.charCodeAt(1)}
|
||||
else {iw=i[0]; ih=i[1]}
|
||||
const iy=y ? (y+4) : (h-ih)/2; // show below title bar if present, otherwise center vertically
|
||||
g.drawImage(i, x+4,iy);
|
||||
x += iw+4;w -= iw+4;
|
||||
}
|
||||
// body text
|
||||
if (options.body) {
|
||||
var body = options.body;
|
||||
const maxChars = Math.floor((300-x)/16);
|
||||
var limit = maxChars;
|
||||
let row = 1;
|
||||
let words = body.trim().replace("\n", " ").split(" ");
|
||||
body = "";
|
||||
for (var i = 0; i < words.length; i++) {
|
||||
if (body.length + words[i].length + 1 > limit) {
|
||||
if (row>=8) {
|
||||
body += "...";
|
||||
break;
|
||||
}
|
||||
body += "\n " + words[i];
|
||||
row++;
|
||||
limit += maxChars;
|
||||
if (row==8) limit -= 4;
|
||||
} else {
|
||||
body += " " + words[i];
|
||||
}
|
||||
}
|
||||
g.setColor(-1).setFont("6x8", 2).setFontAlign(-1, -1, 0).drawString(body, x-4, y+4);
|
||||
const maxRows = Math.floor((h-4)/16), // font=2*(6x8)
|
||||
maxChars = Math.floor((w-4)/12),
|
||||
text=fitWords(options.body, maxRows, maxChars);
|
||||
g.setColor(-1).setFont("6x8", 2).setFontAlign(-1, -1, 0).drawString(text, x+4, y+4);
|
||||
}
|
||||
|
||||
if (options.render) options.render(120-h/2);
|
||||
if (options.render) {
|
||||
const area={x:x, y:y, w:w, h:h}
|
||||
options.render(area);
|
||||
}
|
||||
|
||||
if (options.on) Bangle.setLCDPower(1); // light up
|
||||
Bangle.on("touch", exports.hide);
|
||||
|
|
Loading…
Reference in New Issue