2023-02-25 14:00:57 +00:00
|
|
|
let lockListener;
|
2023-02-26 18:22:11 +00:00
|
|
|
let quiet;
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const toSemantic = function (espruinoVersion){
|
2024-04-04 17:23:09 +00:00
|
|
|
return {
|
|
|
|
major: espruinoVersion.substring(0,espruinoVersion.indexOf("v")),
|
|
|
|
minor: espruinoVersion.substring(espruinoVersion.indexOf("v") + 1, espruinoVersion.includes(".") ? espruinoVersion.indexOf(".") : espruinoVersion.length),
|
|
|
|
patch: espruinoVersion.includes(".") ? espruinoVersion.substring(espruinoVersion.indexOf(".") + 1, espruinoVersion.length) : 0
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const isNewer = function(espruinoVersion, baseVersion){
|
|
|
|
const s = toSemantic(espruinoVersion);
|
|
|
|
const b = toSemantic(baseVersion);
|
2024-04-04 17:23:09 +00:00
|
|
|
|
|
|
|
return s.major >= b.major &&
|
|
|
|
s.minor >= b.major &&
|
|
|
|
s.patch > b.patch;
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
let settings = Object.assign(
|
2024-03-28 14:37:17 +00:00
|
|
|
require('Storage').readJSON("messagesoverlay.default.json", true) || {},
|
|
|
|
require('Storage').readJSON("messagesoverlay.json", true) || {}
|
|
|
|
);
|
|
|
|
|
|
|
|
settings = Object.assign({
|
|
|
|
fontSmall:"6x8",
|
2024-04-04 19:15:15 +00:00
|
|
|
fontMedium:"6x15",
|
|
|
|
fontBig: "12x20",
|
2024-04-04 19:45:41 +00:00
|
|
|
fontLarge:"Vector:30"
|
2024-03-28 14:37:17 +00:00
|
|
|
}, settings);
|
|
|
|
|
|
|
|
const ovrx = settings.border;
|
|
|
|
const ovry = ovrx;
|
|
|
|
const ovrw = g.getWidth()-2*ovrx;
|
|
|
|
const ovrh = g.getHeight()-2*ovry;
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const LOG=()=>{};
|
2024-03-29 08:27:40 +00:00
|
|
|
//LOG = function() { print.apply(null, arguments);};
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const isQuiet = function(){
|
2023-02-26 18:22:11 +00:00
|
|
|
if (quiet == undefined) quiet = (require('Storage').readJSON('setting.json', 1) || {}).quiet;
|
|
|
|
return quiet;
|
2023-02-26 17:51:23 +00:00
|
|
|
};
|
|
|
|
|
2023-02-26 10:03:25 +00:00
|
|
|
let eventQueue = [];
|
|
|
|
let callInProgress = false;
|
2024-03-29 17:14:55 +00:00
|
|
|
let buzzing = false;
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const show = function(ovr){
|
2023-02-26 20:17:58 +00:00
|
|
|
let img = ovr;
|
2023-07-23 09:00:33 +00:00
|
|
|
LOG("show", img.getBPP());
|
2023-02-26 20:17:58 +00:00
|
|
|
if (ovr.getBPP() == 1) {
|
|
|
|
img = ovr.asImage();
|
2024-04-04 19:45:41 +00:00
|
|
|
img.paconstte = new Uint16Array([g.theme.fg,g.theme.bg]);
|
2023-02-26 20:17:58 +00:00
|
|
|
}
|
|
|
|
Bangle.setLCDOverlay(img, ovrx, ovry);
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const manageEvent = function(ovr, event) {
|
2023-02-25 14:00:57 +00:00
|
|
|
event.new = true;
|
|
|
|
|
|
|
|
LOG("manageEvent");
|
|
|
|
if (event.id == "call") {
|
|
|
|
showCall(ovr, event);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
switch (event.t) {
|
|
|
|
case "add":
|
2023-02-26 10:03:25 +00:00
|
|
|
eventQueue.unshift(event);
|
2023-02-25 14:00:57 +00:00
|
|
|
|
|
|
|
if (!callInProgress)
|
|
|
|
showMessage(ovr, event);
|
|
|
|
break;
|
|
|
|
|
2024-02-10 15:51:46 +00:00
|
|
|
case "modify": {
|
2023-02-25 14:00:57 +00:00
|
|
|
let find = false;
|
2023-02-26 10:03:25 +00:00
|
|
|
eventQueue.forEach(element => {
|
2023-02-25 14:00:57 +00:00
|
|
|
if (element.id == event.id) {
|
|
|
|
find = true;
|
|
|
|
Object.assign(element, event);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
if (!find)
|
2023-02-26 10:03:25 +00:00
|
|
|
eventQueue.unshift(event);
|
2023-02-25 14:00:57 +00:00
|
|
|
|
|
|
|
if (!callInProgress)
|
|
|
|
showMessage(ovr, event);
|
|
|
|
break;
|
2024-02-10 15:51:46 +00:00
|
|
|
}
|
2023-02-25 14:00:57 +00:00
|
|
|
case "remove":
|
2023-02-26 10:03:25 +00:00
|
|
|
if (eventQueue.length == 0 && !callInProgress)
|
2023-02-25 14:00:57 +00:00
|
|
|
next(ovr);
|
|
|
|
|
2023-02-26 10:03:25 +00:00
|
|
|
if (!callInProgress && eventQueue[0] !== undefined && eventQueue[0].id == event.id)
|
2023-02-25 14:00:57 +00:00
|
|
|
next(ovr);
|
2023-07-12 17:59:04 +00:00
|
|
|
else
|
|
|
|
eventQueue = [];
|
2023-02-25 14:00:57 +00:00
|
|
|
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const roundedRect = function(ovr, x,y,w,h,filled){
|
2023-02-25 14:00:57 +00:00
|
|
|
var poly = [
|
|
|
|
x,y+4,
|
|
|
|
x+4,y,
|
|
|
|
x+w-5,y,
|
|
|
|
x+w-1,y+4,
|
|
|
|
x+w-1,y+h-5,
|
|
|
|
x+w-5,y+h-1,
|
|
|
|
x+4,y+h-1,
|
|
|
|
x,y+h-5,
|
|
|
|
x,y+4
|
|
|
|
];
|
2024-04-04 21:11:41 +00:00
|
|
|
if (filled){
|
|
|
|
let c = ovr.getColor();
|
|
|
|
ovr.setColor(ovr.getBgColor());
|
|
|
|
ovr.fillPoly(poly,true);
|
|
|
|
ovr.setColor(c);
|
|
|
|
}
|
2023-02-25 14:00:57 +00:00
|
|
|
ovr.drawPoly(poly,true);
|
2023-02-26 08:51:45 +00:00
|
|
|
};
|
|
|
|
|
2024-04-05 22:23:06 +00:00
|
|
|
const divider = 38;
|
|
|
|
|
|
|
|
const drawScreen = function(ovr, title, src, iconcolor, icon){
|
2024-04-04 21:11:41 +00:00
|
|
|
ovr.setColor(ovr.theme.fg2);
|
|
|
|
ovr.setBgColor(ovr.theme.bg2);
|
2024-04-05 22:23:06 +00:00
|
|
|
ovr.clearRect(2,2,ovr.getWidth()-3, divider - 1);
|
2024-04-04 17:22:13 +00:00
|
|
|
|
2023-02-26 08:51:45 +00:00
|
|
|
ovr.setFont(settings.fontSmall);
|
|
|
|
ovr.setFontAlign(0,-1);
|
2023-02-26 12:47:39 +00:00
|
|
|
|
2024-04-05 22:23:06 +00:00
|
|
|
const textCenter = (ovr.getWidth()+34-24)/2-1;
|
2023-02-26 12:47:39 +00:00
|
|
|
|
2024-04-05 22:23:06 +00:00
|
|
|
const w = ovr.getWidth() - 35 - 26;
|
2023-02-26 08:51:45 +00:00
|
|
|
|
2024-04-05 22:23:06 +00:00
|
|
|
if (title)
|
|
|
|
drawTitle(title, textCenter, w, divider, 1);
|
|
|
|
|
|
|
|
if (src)
|
|
|
|
drawSource(src, textCenter, w, 2, -1);
|
2023-02-26 08:51:45 +00:00
|
|
|
|
2024-03-29 17:09:26 +00:00
|
|
|
ovr.setColor(ovr.theme.fg);
|
2024-04-04 21:11:41 +00:00
|
|
|
ovr.setBgColor(ovr.theme.bg);
|
2023-02-26 12:09:36 +00:00
|
|
|
|
2024-04-04 21:11:41 +00:00
|
|
|
roundedRect(ovr, ovr.getWidth()-26,5,22,30,true);
|
2024-04-05 22:23:06 +00:00
|
|
|
ovr.setFontAlign(0,0);
|
2023-02-26 18:22:11 +00:00
|
|
|
ovr.setFont("Vector:16");
|
2024-04-05 22:23:06 +00:00
|
|
|
ovr.drawString("X",ovr.getWidth()-14,20);
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-04-04 21:11:41 +00:00
|
|
|
ovr.setBgColor("#888");
|
2024-04-05 22:23:06 +00:00
|
|
|
roundedRect(ovr, 4, 5, 30, 30,true);
|
2024-04-04 21:11:41 +00:00
|
|
|
ovr.setBgColor(ovr.theme.bg);
|
|
|
|
ovr.setColor(ovr.getBPP() != 1 ? iconcolor : ovr.theme.fg);
|
2024-04-05 22:23:06 +00:00
|
|
|
ovr.drawImage(icon,7,8);
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
|
|
|
|
2024-04-05 22:23:06 +00:00
|
|
|
const drawSource = function(src, center, w, y, align) {
|
|
|
|
ovr.setFont(settings.fontSmall);
|
|
|
|
while (ovr.stringWidth(src) > w) src = src.substring(0,src.length-2);
|
|
|
|
if (src.length != src.length) src += "...";
|
|
|
|
ovr.setFontAlign(0,align);
|
|
|
|
ovr.drawString(src, center, y);
|
|
|
|
};
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-04-05 22:23:06 +00:00
|
|
|
const drawTitle = function(title, center, w, y, align) {
|
|
|
|
let titleFont = settings.fontLarge,
|
2023-02-25 14:00:57 +00:00
|
|
|
lines;
|
2024-04-05 22:23:06 +00:00
|
|
|
if (ovr.setFont(titleFont).stringWidth(title) > w)
|
|
|
|
titleFont = settings.fontMedium;
|
|
|
|
if (ovr.setFont(titleFont).stringWidth(title) > w) {
|
|
|
|
lines = ovr.wrapString(title, w);
|
|
|
|
title = (lines.length > 2) ? lines.slice(0, 2).join("\n") + "..." : lines.join("\n");
|
2023-02-25 14:00:57 +00:00
|
|
|
}
|
|
|
|
|
2024-04-05 22:23:06 +00:00
|
|
|
ovr.setFontAlign(0,align);
|
|
|
|
ovr.setFont(titleFont);
|
|
|
|
ovr.drawString(title, center, y+2);
|
|
|
|
};
|
|
|
|
|
|
|
|
const showMessage = function(ovr, msg) {
|
|
|
|
LOG("showMessage");
|
|
|
|
|
|
|
|
ovr.setClipRect(0,0,ovr.getWidth(),ovr.getHeight());
|
|
|
|
drawScreen(ovr, msg.title, msg.src || /*LANG*/ "Message", require("messageicons").getColor(msg), require("messageicons").getImage(msg));
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-03-28 21:56:23 +00:00
|
|
|
drawMessage(ovr, msg);
|
|
|
|
|
2023-02-26 17:51:23 +00:00
|
|
|
if (!isQuiet() && msg.new) {
|
2023-02-25 14:00:57 +00:00
|
|
|
msg.new = false;
|
2024-03-29 17:14:55 +00:00
|
|
|
if (!buzzing){
|
|
|
|
buzzing = true;
|
2024-04-03 17:58:25 +00:00
|
|
|
Bangle.buzz().then(()=>{setTimeout(()=>{buzzing = false;},2000);});
|
2024-03-29 17:14:55 +00:00
|
|
|
}
|
2024-03-29 16:51:46 +00:00
|
|
|
Bangle.setLCDPower(1);
|
2023-02-25 14:00:57 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-04-04 21:11:41 +00:00
|
|
|
const getBorderColor = function() {
|
|
|
|
if (Bangle.isLocked())
|
|
|
|
return ovr.theme.fg;
|
|
|
|
else
|
|
|
|
return ovr.theme.fgH;
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const drawBorder = function(img) {
|
2023-07-15 13:04:32 +00:00
|
|
|
LOG("drawBorder", isQuiet());
|
2024-03-29 17:09:26 +00:00
|
|
|
ovr.setBgColor(ovr.theme.bg);
|
2023-07-23 09:00:33 +00:00
|
|
|
if (img) ovr=img;
|
2024-04-04 21:11:41 +00:00
|
|
|
ovr.setColor(getBorderColor());
|
2023-02-25 14:00:57 +00:00
|
|
|
ovr.drawRect(0,0,ovr.getWidth()-1,ovr.getHeight()-1);
|
|
|
|
ovr.drawRect(1,1,ovr.getWidth()-2,ovr.getHeight()-2);
|
2024-04-05 22:23:06 +00:00
|
|
|
ovr.drawRect(2,divider,ovr.getWidth()-2,divider+1);
|
2023-02-26 20:17:58 +00:00
|
|
|
show(ovr);
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const showCall = function(ovr, msg) {
|
2023-02-25 14:00:57 +00:00
|
|
|
LOG("showCall");
|
|
|
|
LOG(msg);
|
|
|
|
|
|
|
|
if (msg.t == "remove") {
|
|
|
|
LOG("hide call screen");
|
|
|
|
next(ovr); //dont shift
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
callInProgress = true;
|
|
|
|
|
2024-04-05 22:23:06 +00:00
|
|
|
drawScreen(ovr, msg.title, msg.src || /*LANG*/ "Message", require("messageicons").getColor(msg), require("messageicons").getImage(msg));
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2023-02-26 10:03:25 +00:00
|
|
|
stopCallBuzz();
|
2023-02-26 17:51:23 +00:00
|
|
|
if (!isQuiet()) {
|
2023-02-25 14:00:57 +00:00
|
|
|
if (msg.new) {
|
|
|
|
msg.new = false;
|
2023-02-26 14:53:00 +00:00
|
|
|
if (callBuzzTimer) clearInterval(callBuzzTimer);
|
2023-02-26 10:03:25 +00:00
|
|
|
callBuzzTimer = setInterval(function() {
|
2023-02-25 14:00:57 +00:00
|
|
|
Bangle.buzz(500);
|
|
|
|
}, 1000);
|
|
|
|
|
|
|
|
Bangle.buzz(500);
|
|
|
|
}
|
|
|
|
}
|
2023-02-26 10:03:25 +00:00
|
|
|
drawMessage(ovr, msg);
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const next = function(ovr) {
|
2023-02-25 14:00:57 +00:00
|
|
|
LOG("next");
|
2023-02-26 10:03:25 +00:00
|
|
|
stopCallBuzz();
|
2023-02-25 14:00:57 +00:00
|
|
|
|
|
|
|
if (!callInProgress)
|
2023-02-26 10:03:25 +00:00
|
|
|
eventQueue.shift();
|
2023-02-25 14:00:57 +00:00
|
|
|
|
|
|
|
callInProgress = false;
|
2023-02-26 10:03:25 +00:00
|
|
|
if (eventQueue.length == 0) {
|
2023-02-25 14:00:57 +00:00
|
|
|
LOG("no element in queue - closing");
|
|
|
|
cleanup();
|
2023-08-29 19:04:09 +00:00
|
|
|
return false;
|
2023-02-25 14:00:57 +00:00
|
|
|
}
|
|
|
|
|
2023-02-26 10:03:25 +00:00
|
|
|
showMessage(ovr, eventQueue[0]);
|
2023-08-29 19:04:09 +00:00
|
|
|
return true;
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
|
|
|
|
2023-02-26 10:03:25 +00:00
|
|
|
let callBuzzTimer = null;
|
2024-04-04 19:45:41 +00:00
|
|
|
const stopCallBuzz = function() {
|
2023-02-26 10:03:25 +00:00
|
|
|
if (callBuzzTimer) {
|
|
|
|
clearInterval(callBuzzTimer);
|
2023-02-26 14:53:00 +00:00
|
|
|
callBuzzTimer = undefined;
|
2023-02-25 14:00:57 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const drawTriangleUp = function(ovr) {
|
2024-04-04 21:11:41 +00:00
|
|
|
ovr.fillPoly([ovr.getWidth()-10, 46,ovr.getWidth()-15, 56,ovr.getWidth()-5, 56]);
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const drawTriangleDown = function(ovr) {
|
2024-04-04 21:11:41 +00:00
|
|
|
ovr.fillPoly([ovr.getWidth()-10, ovr.getHeight()-6, ovr.getWidth()-15, ovr.getHeight()-16, ovr.getWidth()-5, ovr.getHeight()-16]);
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
|
|
|
|
2023-02-28 19:02:47 +00:00
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const scrollUp = function(ovr) {
|
|
|
|
const msg = eventQueue[0];
|
2023-02-26 10:03:25 +00:00
|
|
|
LOG("up", msg);
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2023-02-26 10:03:25 +00:00
|
|
|
if (!msg.CanscrollUp) return;
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-03-29 22:12:53 +00:00
|
|
|
msg.FirstLine = msg.FirstLine > 0 ? msg.FirstLine - 1 : 0;
|
2023-02-26 10:03:25 +00:00
|
|
|
drawMessage(ovr, msg);
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const scrollDown = function(ovr) {
|
|
|
|
const msg = eventQueue[0];
|
2023-02-26 10:03:25 +00:00
|
|
|
LOG("down", msg);
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2023-02-26 10:03:25 +00:00
|
|
|
if (!msg.CanscrollDown) return;
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-03-29 22:12:53 +00:00
|
|
|
msg.FirstLine = msg.FirstLine + 1;
|
2023-02-26 10:03:25 +00:00
|
|
|
drawMessage(ovr, msg);
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const drawMessage = function(ovr, msg) {
|
|
|
|
const getStringHeight = function(str){
|
2024-04-04 17:23:09 +00:00
|
|
|
"jit";
|
2024-04-04 19:45:41 +00:00
|
|
|
const metrics = ovr.stringMetrics(str);
|
2024-04-04 17:23:09 +00:00
|
|
|
if (isNewer("2v21.13", process.version)){
|
|
|
|
if (metrics.maxImageHeight > 16)
|
|
|
|
metrics.maxImageHeight = metrics.height;
|
|
|
|
}
|
|
|
|
return Math.max(metrics.height, metrics.maxImageHeight);
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const wrapString = function(str, maxWidth) {
|
2023-02-25 14:00:57 +00:00
|
|
|
str = str.replace("\r\n", "\n").replace("\r", "\n");
|
|
|
|
return ovr.wrapString(str, maxWidth);
|
|
|
|
};
|
2024-04-04 19:45:41 +00:00
|
|
|
const wrappedStringHeight = function(strArray){
|
2024-03-29 22:12:53 +00:00
|
|
|
let r = 0;
|
|
|
|
strArray.forEach((line, i) => {
|
2024-04-04 17:23:09 +00:00
|
|
|
r += getStringHeight(line);
|
2024-03-29 22:12:53 +00:00
|
|
|
});
|
|
|
|
return r;
|
2024-04-03 17:58:25 +00:00
|
|
|
};
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-03-29 17:09:26 +00:00
|
|
|
ovr.setColor(ovr.theme.fg);
|
|
|
|
ovr.setBgColor(ovr.theme.bg);
|
|
|
|
|
2024-04-04 17:22:13 +00:00
|
|
|
if (msg.FirstLine === undefined) msg.FirstLine = 0;
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const padding = eventQueue.length > 1 ? (eventQueue.length > 3 ? 7 : 5) : 3;
|
2024-04-03 17:58:25 +00:00
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const yText = 40;
|
2024-04-04 20:29:56 +00:00
|
|
|
let yLine = yText + 4;
|
2024-03-28 21:56:23 +00:00
|
|
|
|
2024-04-04 21:11:41 +00:00
|
|
|
ovr.setClipRect(2, yText, ovr.getWidth() - 3, ovr.getHeight() - 3);
|
2024-04-04 20:29:56 +00:00
|
|
|
|
|
|
|
const maxTextHeight = ovr.getHeight() - yLine - padding + 2;
|
2024-03-29 22:12:53 +00:00
|
|
|
|
2024-04-04 17:22:13 +00:00
|
|
|
if (!msg.lines) {
|
2024-03-28 21:56:23 +00:00
|
|
|
let bodyFont = settings.fontBig;
|
2023-02-25 14:00:57 +00:00
|
|
|
ovr.setFont(bodyFont);
|
2024-03-28 21:56:23 +00:00
|
|
|
msg.lines = wrapString(msg.body, ovr.getWidth() - 4 - padding);
|
2024-03-29 22:12:53 +00:00
|
|
|
|
|
|
|
if (wrappedStringHeight(msg.lines) > maxTextHeight) {
|
2024-03-28 21:56:23 +00:00
|
|
|
bodyFont = settings.fontMedium;
|
2023-02-25 14:00:57 +00:00
|
|
|
ovr.setFont(bodyFont);
|
2024-03-28 21:56:23 +00:00
|
|
|
msg.lines = wrapString(msg.body, ovr.getWidth() - 4 - padding);
|
2023-02-25 14:00:57 +00:00
|
|
|
}
|
2024-03-28 21:56:23 +00:00
|
|
|
msg.bodyFont = bodyFont;
|
2024-03-29 22:12:53 +00:00
|
|
|
msg.lineHeights = [];
|
|
|
|
msg.lines.forEach((line, i) => {
|
2024-04-04 17:22:13 +00:00
|
|
|
msg.lineHeights[i] = getStringHeight(line);
|
2024-03-29 22:12:53 +00:00
|
|
|
});
|
2024-04-03 17:58:25 +00:00
|
|
|
}
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-04-04 17:22:13 +00:00
|
|
|
LOG("Prepared message", msg);
|
|
|
|
|
2024-03-28 21:56:23 +00:00
|
|
|
ovr.setFont(msg.bodyFont);
|
2023-02-26 12:09:36 +00:00
|
|
|
ovr.setColor(ovr.theme.fg);
|
2024-03-29 22:12:53 +00:00
|
|
|
ovr.setBgColor(ovr.theme.bg);
|
2024-03-28 21:56:23 +00:00
|
|
|
ovr.clearRect(2, yText, ovr.getWidth()-3, ovr.getHeight()-3);
|
|
|
|
|
|
|
|
let xText = 4;
|
|
|
|
|
|
|
|
if (msg.bodyFont == settings.fontBig) {
|
|
|
|
ovr.setFontAlign(0, -1);
|
|
|
|
xText = Math.round(ovr.getWidth() / 2 - (padding - 3) / 2) + 1;
|
2024-03-29 22:12:53 +00:00
|
|
|
yLine = (ovr.getHeight() + yLine) / 2 - (wrappedStringHeight(msg.lines) / 2);
|
|
|
|
ovr.drawString(msg.lines.join("\n"), xText, yLine);
|
|
|
|
} else {
|
2024-03-28 21:56:23 +00:00
|
|
|
ovr.setFontAlign(-1, -1);
|
2024-03-29 22:12:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
let currentLine = msg.FirstLine;
|
2024-03-28 21:56:23 +00:00
|
|
|
|
2024-03-29 22:12:53 +00:00
|
|
|
let drawnHeight = 0;
|
2024-04-03 17:58:25 +00:00
|
|
|
|
2024-04-04 20:29:56 +00:00
|
|
|
while(drawnHeight < maxTextHeight && msg.lines.length > currentLine) {
|
2024-04-04 19:45:41 +00:00
|
|
|
const lineHeight = msg.lineHeights[currentLine];
|
2024-04-04 20:29:56 +00:00
|
|
|
ovr.drawString(msg.lines[currentLine], xText, yLine + drawnHeight);
|
|
|
|
drawnHeight += lineHeight;
|
|
|
|
currentLine++;
|
2024-03-29 22:12:53 +00:00
|
|
|
}
|
2024-03-28 15:43:01 +00:00
|
|
|
|
|
|
|
if (eventQueue.length > 1){
|
|
|
|
ovr.drawLine(ovr.getWidth()-4,ovr.getHeight()/2,ovr.getWidth()-4,ovr.getHeight()-4);
|
|
|
|
ovr.drawLine(ovr.getWidth()/2,ovr.getHeight()-4,ovr.getWidth()-4,ovr.getHeight()-4);
|
|
|
|
}
|
|
|
|
if (eventQueue.length > 3){
|
|
|
|
ovr.drawLine(ovr.getWidth()-6,ovr.getHeight()*0.6,ovr.getWidth()-6,ovr.getHeight()-6);
|
|
|
|
ovr.drawLine(ovr.getWidth()*0.6,ovr.getHeight()-6,ovr.getWidth()-6,ovr.getHeight()-6);
|
|
|
|
}
|
|
|
|
|
2024-04-04 21:11:41 +00:00
|
|
|
ovr.setColor(ovr.theme.fg);
|
2023-02-25 14:00:57 +00:00
|
|
|
if (msg.FirstLine != 0) {
|
2023-02-26 10:03:25 +00:00
|
|
|
msg.CanscrollUp = true;
|
|
|
|
drawTriangleUp(ovr);
|
2023-02-25 14:00:57 +00:00
|
|
|
} else
|
2023-02-26 10:03:25 +00:00
|
|
|
msg.CanscrollUp = false;
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-03-29 22:12:53 +00:00
|
|
|
if (currentLine < msg.lines.length) {
|
2023-02-26 10:03:25 +00:00
|
|
|
msg.CanscrollDown = true;
|
|
|
|
drawTriangleDown(ovr);
|
2023-02-25 14:00:57 +00:00
|
|
|
} else
|
2023-02-26 10:03:25 +00:00
|
|
|
msg.CanscrollDown = false;
|
2024-03-28 21:56:23 +00:00
|
|
|
|
2023-02-26 20:17:58 +00:00
|
|
|
show(ovr);
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const getDragHandler = function(ovr){
|
2024-03-29 22:12:53 +00:00
|
|
|
return (e) => {
|
|
|
|
if (e.dy > 0) {
|
2023-02-26 10:03:25 +00:00
|
|
|
scrollUp(ovr);
|
2024-03-29 22:12:53 +00:00
|
|
|
} else if (e.dy < 0){
|
2023-02-26 10:03:25 +00:00
|
|
|
scrollDown(ovr);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const getTouchHandler = function(ovr){
|
2023-02-26 10:03:25 +00:00
|
|
|
return (_, xy) => {
|
2023-02-26 08:51:45 +00:00
|
|
|
if (xy.y < ovry + 40){
|
2023-02-25 14:00:57 +00:00
|
|
|
next(ovr);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
2024-04-04 16:28:39 +00:00
|
|
|
const EVENTS=["touch", "drag", "swipe"];
|
2024-04-03 18:07:12 +00:00
|
|
|
|
|
|
|
let hasBackup = false;
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const origOn = Bangle.on;
|
|
|
|
const backupOn = function(event, handler){
|
2024-04-03 18:07:12 +00:00
|
|
|
if (EVENTS.includes(event)){
|
|
|
|
if (!backup[event])
|
|
|
|
backup[event] = [];
|
|
|
|
backup[event].push(handler);
|
|
|
|
}
|
|
|
|
else origOn.call(Bangle, event, handler);
|
2023-02-26 09:25:29 +00:00
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const origRemove = Bangle.removeListener;
|
|
|
|
const backupRemove = function(event, handler){
|
2024-04-03 18:07:12 +00:00
|
|
|
if (EVENTS.includes(event) && backup[event]){
|
|
|
|
LOG("backup for " + event + ": " + backup[event]);
|
|
|
|
backup[event] = backup[event].filter(e=>e!==handler);
|
|
|
|
}
|
|
|
|
else origRemove.call(Bangle, event, handler);
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const origRemoveAll = Bangle.removeAllListeners;
|
|
|
|
const backupRemoveAll = function(event){
|
2024-04-03 18:07:12 +00:00
|
|
|
if (backup[event])
|
|
|
|
backup[event] = undefined;
|
|
|
|
origRemoveAll.call(Bangle);
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const restoreHandlers = function(){
|
2024-04-03 18:07:12 +00:00
|
|
|
if (!hasBackup){
|
|
|
|
LOG("No backup available");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
for (const event of EVENTS){
|
2024-04-03 18:07:12 +00:00
|
|
|
LOG("Restore", backup[event]);
|
|
|
|
origRemoveAll.call(Bangle, event);
|
|
|
|
if (backup[event] && backup[event].length == 1)
|
|
|
|
backup[event] = backup[event][0];
|
|
|
|
Bangle["#on" + event]=backup[event];
|
|
|
|
backup[event] = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
Bangle.on = origOn;
|
|
|
|
Bangle.removeListener = origRemove;
|
|
|
|
Bangle.removeAllListeners = origRemoveAll;
|
|
|
|
|
|
|
|
hasBackup = false;
|
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const backupHandlers = function(){
|
2024-04-03 18:07:12 +00:00
|
|
|
if (hasBackup){
|
|
|
|
LOG("Backup already exists");
|
|
|
|
return false; // do not backup, overlay is already up
|
|
|
|
}
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
for (const event of EVENTS){
|
2024-04-03 18:07:12 +00:00
|
|
|
backup[event] = Bangle["#on" + event];
|
|
|
|
if (typeof backup[event] == "function")
|
|
|
|
backup[event] = [ backup[event] ];
|
|
|
|
LOG("Backed up", backup[event], event);
|
|
|
|
Bangle.removeAllListeners(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
Bangle.on = backupOn;
|
|
|
|
Bangle.removeListener = backupRemove;
|
|
|
|
Bangle.removeAllListeners = backupRemoveAll;
|
|
|
|
|
|
|
|
hasBackup = true;
|
|
|
|
|
|
|
|
return true;
|
2023-02-26 09:25:29 +00:00
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const cleanup = function(){
|
2023-02-25 14:00:57 +00:00
|
|
|
if (lockListener) {
|
|
|
|
Bangle.removeListener("lock", lockListener);
|
|
|
|
lockListener = undefined;
|
|
|
|
}
|
2024-04-03 18:07:12 +00:00
|
|
|
restoreHandlers();
|
2023-02-25 14:00:57 +00:00
|
|
|
|
|
|
|
Bangle.setLCDOverlay();
|
2023-02-26 14:23:41 +00:00
|
|
|
ovr = undefined;
|
2023-02-26 18:22:11 +00:00
|
|
|
quiet = undefined;
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const backup = {};
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const main = function(ovr, event) {
|
2024-03-29 08:23:49 +00:00
|
|
|
LOG("Main", event.t);
|
2024-04-04 19:45:41 +00:00
|
|
|
const didBackup = backupHandlers();
|
2023-02-26 14:53:00 +00:00
|
|
|
|
2023-02-25 14:00:57 +00:00
|
|
|
if (!lockListener) {
|
2024-03-28 19:30:17 +00:00
|
|
|
lockListener = function (e){
|
|
|
|
updateClearingTimeout();
|
2023-07-23 09:00:33 +00:00
|
|
|
drawBorder();
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|
2024-04-03 18:07:12 +00:00
|
|
|
LOG("Add overlay lock handlers");
|
|
|
|
origOn.call(Bangle, 'lock', lockListener);
|
2023-02-25 14:00:57 +00:00
|
|
|
}
|
2024-04-03 18:07:12 +00:00
|
|
|
|
|
|
|
if (didBackup){
|
|
|
|
LOG("Add overlay UI handlers");
|
|
|
|
origOn.call(Bangle, 'touch', getTouchHandler(ovr));
|
|
|
|
origOn.call(Bangle, 'drag', getDragHandler(ovr));
|
2023-02-28 06:57:06 +00:00
|
|
|
}
|
2023-02-25 14:00:57 +00:00
|
|
|
|
|
|
|
if (event !== undefined){
|
|
|
|
manageEvent(ovr, event);
|
2024-04-04 21:11:41 +00:00
|
|
|
drawBorder(ovr);
|
2023-02-25 14:00:57 +00:00
|
|
|
} else {
|
|
|
|
LOG("No event given");
|
|
|
|
cleanup();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-02-26 14:23:41 +00:00
|
|
|
let ovr;
|
2023-08-29 19:04:09 +00:00
|
|
|
let clearingTimeout;
|
2023-02-26 14:23:41 +00:00
|
|
|
|
2024-04-04 19:45:41 +00:00
|
|
|
const updateClearingTimeout = ()=>{
|
2024-03-28 19:30:17 +00:00
|
|
|
LOG("updateClearingTimeout");
|
2024-03-29 16:53:10 +00:00
|
|
|
if (settings.autoclear <= 0)
|
2024-03-28 19:30:17 +00:00
|
|
|
return;
|
2024-03-29 16:53:10 +00:00
|
|
|
LOG("Remove clearing timeout", clearingTimeout);
|
2024-03-28 19:30:17 +00:00
|
|
|
if (clearingTimeout) clearTimeout(clearingTimeout);
|
|
|
|
if (Bangle.isLocked()){
|
2024-03-29 16:53:10 +00:00
|
|
|
LOG("Set new clearing timeout");
|
2024-03-28 19:30:17 +00:00
|
|
|
clearingTimeout = setTimeout(()=>{
|
2024-03-29 16:53:10 +00:00
|
|
|
LOG("setNewTimeout");
|
2024-04-04 19:45:41 +00:00
|
|
|
const event = eventQueue.pop();
|
2024-04-03 17:58:25 +00:00
|
|
|
if (event)
|
|
|
|
drawMessage(ovr, event);
|
2024-03-28 19:30:17 +00:00
|
|
|
if (eventQueue.length > 0){
|
|
|
|
LOG("still got elements");
|
|
|
|
updateClearingTimeout();
|
|
|
|
} else {
|
|
|
|
cleanup();
|
|
|
|
}
|
|
|
|
}, settings.autoclear * 1000);
|
|
|
|
} else {
|
|
|
|
clearingTimeout = undefined;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2023-07-12 17:59:04 +00:00
|
|
|
exports.message = function(type, event) {
|
2024-04-03 17:58:25 +00:00
|
|
|
LOG("Got message", type, event);
|
2023-07-12 17:59:04 +00:00
|
|
|
// only handle some event types
|
|
|
|
if(!(type=="text" || type == "call")) return;
|
2023-07-13 17:11:29 +00:00
|
|
|
if(type=="text" && event.id == "nav") return;
|
2023-07-12 17:59:04 +00:00
|
|
|
if(event.handled) return;
|
2023-08-29 19:04:09 +00:00
|
|
|
if(event.messagesoverlayignore) return;
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2023-02-26 20:17:58 +00:00
|
|
|
bpp = 4;
|
2024-03-28 14:37:17 +00:00
|
|
|
if (process.memory().free < settings.lowmwm)
|
2023-07-23 09:23:01 +00:00
|
|
|
bpp = 1;
|
2023-02-26 20:17:58 +00:00
|
|
|
|
2024-03-28 14:37:17 +00:00
|
|
|
while (process.memory().free < settings.minfreemem && eventQueue.length > 0){
|
2024-04-04 19:45:41 +00:00
|
|
|
const dropped = eventQueue.pop();
|
2023-07-23 08:42:21 +00:00
|
|
|
print("Dropped message because of memory constraints", dropped);
|
|
|
|
}
|
|
|
|
|
2023-07-23 09:23:01 +00:00
|
|
|
if (!ovr || ovr.getBPP() != bpp) {
|
2023-02-26 20:17:58 +00:00
|
|
|
ovr = Graphics.createArrayBuffer(ovrw, ovrh, bpp, {
|
2023-02-26 14:23:41 +00:00
|
|
|
msb: true
|
|
|
|
});
|
|
|
|
}
|
2023-02-25 14:00:57 +00:00
|
|
|
|
2024-03-29 17:09:26 +00:00
|
|
|
ovr.reset();
|
|
|
|
|
2023-02-26 20:17:58 +00:00
|
|
|
if (bpp == 4)
|
|
|
|
ovr.theme = g.theme;
|
|
|
|
else
|
|
|
|
ovr.theme = { fg:0, bg:1, fg2:1, bg2:0, fgH:1, bgH:0 };
|
|
|
|
|
2024-03-29 08:23:49 +00:00
|
|
|
ovr.clear();
|
2023-02-25 14:00:57 +00:00
|
|
|
main(ovr, event);
|
2023-08-29 19:04:09 +00:00
|
|
|
|
|
|
|
updateClearingTimeout();
|
|
|
|
|
2023-07-15 13:04:32 +00:00
|
|
|
if (!isQuiet()) Bangle.setLCDPower(1);
|
2023-07-12 17:59:04 +00:00
|
|
|
event.handled = true;
|
2023-02-25 14:00:57 +00:00
|
|
|
};
|