diff --git a/messagebox.lib.js b/messagebox.lib.js index cf91897..4c913d0 100644 --- a/messagebox.lib.js +++ b/messagebox.lib.js @@ -1,10 +1,10 @@ - let options = { srcFont: "6x8", titleFont: "12x20", bodyFont: "12x20", headerBgColor: g.theme.bgH, headerFgColor: g.theme.fg, + headerHlColor: g.toColor(0, 1, 0), margin: 3, // space on sides padding: 8, // space between header and body fh: 10, // footer height - leave this much space for a footer @@ -57,6 +57,7 @@ const HeaderBox = function(msg, messageRect) { this.minH = Math.max(this.titleLineH, this.srcH + this.im.height) + options.padding; this.maxH = Math.max(this.titleLineH * this.titleLines.length, this.iconW) + options.padding; this.h = this.maxH; + this.new = msg.new ?? false; }; // HeaderBox HeaderBox.prototype.draw = function(messageRect) { @@ -69,6 +70,7 @@ HeaderBox.prototype.draw = function(messageRect) { let y2 = messageRect.y + this.h - 1; setClipRect(x, y, x2, y2); g.setBgColor(options.headerBgColor).clearRect(x, y, x2, y2); + if (this.new) g.setColor(options.headerHlColor).fillPoly([x, y, x + 20, y, x, y + 20]); g.setColor(options.headerFgColor); g.setFont(options.titleFont); if (this.h > this.minH) { // multi-line title @@ -158,6 +160,14 @@ let MessageBox = function(msg, yOffset) { MessageBox.prototype.prevOffset = Bangle.appRect.y - Bangle.appRect.h; MessageBox.prototype.nextOffset = Bangle.appRect.y2 + 1; +MessageBox.prototype.setNew = function() { + this.headerBox.new = true; +} + +MessageBox.prototype.clearNew = function() { + this.headerBox.new = false; +} + MessageBox.prototype.reset = function(yOffset) { if (!yOffset) yOffset = 0; this.yOffset = yOffset; diff --git a/messagecenter.app.js b/messagecenter.app.js index ff265d5..cf0bcf0 100644 --- a/messagecenter.app.js +++ b/messagecenter.app.js @@ -1,41 +1,73 @@ Bangle.MESSAGES = [ {"t":"add","id":1720281666,"src":"SMS Message","title":"Hayley Thiessen, Wifey","subject":"", "body":"5 * short message *5", - "sender":"","positive":true,"negative":true,"new":true,"handled":true}, + "sender":"","positive":true,"negative":true,"new":true,"handled":true, "show": true}, {"t":"add","id":1720281662,"src":"SMS Message","title":"Hayley Thiessen, Wifey","subject":"", "body":"1 ***** This is a long message from my wife. I want to make it take up more than a screenful. That way we can test out scrolling. ****1", - "sender":"","positive":true,"negative":true,"new":false,"handled":true}, + "sender":"","positive":true,"negative":true,"new":false,"handled":true, "show": true}, {"t":"add","id":1720281663,"src":"SMS Message","title":"Hayley Thiessen, Wifey","subject":"", "body":"2 ***** This is a long message from my wife. I want to make it take up more than a screenful. That way we can test out scrolling. ****2", - "sender":"","positive":true,"negative":true,"new":false,"handled":true}, + "sender":"","positive":true,"negative":true,"new":false,"handled":true, "show": true}, {"t":"add","id":1720281667,"src":"SMS Message","title":"Hayley Thiessen","subject":"", "body":"6 * short message *6", - "sender":"","positive":true,"negative":true,"new":false,"handled":true}, + "sender":"","positive":true,"negative":true,"new":false,"handled":true, "show": true}, {"t":"add","id":1720281664,"src":"SMS Message","title":"Hayley Thiessen, Wifey","subject":"", "body":"3 ***** This is a long message from my wife. I want to make it take up more than a screenful. That way we can test out scrolling. ****3", - "sender":"","positive":true,"negative":true,"new":true,"handled":true}, + "sender":"","positive":true,"negative":true,"new":true,"handled":true, "show": true}, {"t":"add","id":1720281665,"src":"SMS Message","title":"Hayley Thiessen, Wifey","subject":"", "body":"4 ***** This is a long message from my wife. I want to make it take up more than a screenful. That way we can test out scrolling. ****4", - "sender":"","positive":true,"negative":true,"new":false,"handled":true}, + "sender":"","positive":true,"negative":true,"new":false,"handled":true, "show": true}, ]; -const goBack = function() { - // if (back==="call" && call) showCall(); - // else if (back==="map" && map) showMap(); - // else if (back==="music" && music) showMusic(); - // else if (back==="messages" && messageList.length) showMessage(); - // else if (back) showMain(); // previous screen was "main", or no longer valid - // else quitApp(); // no previous screen: go back to clock - console.log("go back"); +let idle = false; +let haveNewMessage = false; +let previousActive; +let active; +let events = {}; +let timeouts = {}; + +const goBack = function(timedOut) { + switch (previousActive) { + case "alarm": return showAlarm(); + case "call": return showCall(); + case "message": return showMessage(); + case "map": return showMap(); + case "music": return showMusic(); + default: + if (!timedOut) Bangle.MESSAGES.forEach((m) => {if (!m.new) m.show = false;}); + require("messages").write(Bangle.MESSAGES); + cleanup(); + Bangle.showClock(); + } }; +const cleanup = function() { + +} + +// placeholder functions +const showMusic = function() { + +}; + +const showMap = function() { + +}; + +const showAlarm = function() { + +}; + +const showCall = function() { + +}; //let settings = require('Storage').readJSON("messages.settings.json", true) || {}; //const settings = () => require("messagegui").settings(); const fontTiny = "6x8"; // fixed size, don't use this for important things @@ -52,64 +84,60 @@ const goBack = function() { // }; // setFont(); - Bangle.loadWidgets(); - require("widget_utils").hide(); -///////////////////////////////// +Bangle.loadWidgets(); +require("widget_utils").hide(); -setClipRect = function (x, y, x2, y2) { - if (y < Bangle.appRect.y) y = Bangle.appRect.y; - if (y2 < Bangle.appRect.y2) y2 = Bangle.appRect.y2; - return g.setClipRect(x, y, x2, y2); + +events.saveMessages = function(messages) { + require("messages").write(messages); }; -let active; +E.on("kill", events.saveMessages); + +events.newMessage = (type, msg) => { + console.log("new message"); + if (type === "text" && active === "message") { + require("messages").apply(msg, Bangle.MESSAGES); + if (idle) showText(Bangle.MESSAGES); // we are idle so show new messages right away + else haveNewMessage = true; // otherwise set new message flag and wait until idle + } + // TODO deal with other types of messages +} +Bangle.on("message", events.newMessage); + +// Check for new messages, wait until there is no interaction for idleTime ms +const checkForNewMessages = function(idleTime) { + console.log("checkForNewMessages"); + idleTime = idleTime ?? 3000; // how much time without interaction before we are considered idle + console.log("idleTime = ", idleTime); + idle = false; + if (timeouts.idleTimer) clearTimeout(timeouts.idleTimer); + timeouts.idleTimer = setTimeout(() => { + console.log("update messages"); + if (haveNewMessage) { + console.log("call showText()"); + haveNewMessage = false; + showText(Bangle.MESSAGES); + } + idle = true; + }, idleTime); +}; + +const setBusy = function() { + idle = false; + if (timeouts.idleTimer) clearTimeout(timeouts.idleTimer); + timeouts.idleTimer = undefined; +}; /** - * @param messageList {array} all messages + * @param allMessages {array} all messages * @param showAll {bool} true to show all messages, false to only show new messages, default: false + * @param num {number} */ - -const newMessage = (type, msg) => { - require("messages").apply(msg, Bangle.MESSAGES); - if (type === "text" && active === "message") { - Bangle.emit("updateMessages"); - // console.log("new message: ", type, msg); - } -} -Bangle.on("message", newMessage); - -const showMessage = function(allMessages, showAll) { +const showText = function(allMessages, showAll) { + Bangle.setUI(); // make sure to clear setUI from anything previous + setBusy(); // busy until everything is set up let switching = false; - let updatingMessages = false; - let shouldUpdateMessages = false; - let idle = false; - - const updateMessages = function() { - console.log("updating messages"); - activeMsgId = msgBoxes[messageNum].msg.id; - let newMessages = Bangle.MESSAGES.filter((m) => { - if (messageList.find((n) => n.id === m.id) === undefined && // not already in messageList - m.new) return true; // and it's new - else return false; - }); - const waitUntilIdle = () => { - if (idle && !switching) { - for (let msg of newMessage) { - msgBoxes.unshift(new MessageBox(msg)); - messageList.unshift(msg); - } - messageNum = messageList.findIndex((m) => m.id === activeMsgId); - refresh(); - shouldUpdateMessages = false; - updatingMessages = false; - return; - } else { - setTimeout(waitUntilIdle, 250); - } - }; - } - - Bangle.on("updateMessages", () => {shouldUpdateMessages = true;}); active = "message"; let MessageBox = require("messagebox").MessageBox; require("messagebox").setOptions({fh: 30}); @@ -118,13 +146,14 @@ const showMessage = function(allMessages, showAll) { const swipeThreshold = 20; let mode = "scroll"; // one of "scroll", "next", "prev" (switch to next/prev message), "swipe" (swipe to delete or archive) let messageNum = 0; - let messageList = showAll ? allMessages : allMessages.filter(m => m.new); + // TODO we might have to append array of (m.show && !m.new) to array of m.new so that all new messages are at the beginning of list + let messageList = showAll ? allMessages : allMessages.filter(m => m.new || m.show); if (!messageList.length) { console.log("No messages") return; } - Bangle.setLocked(false); - Bangle.setLCDPower(true); + Bangle.setLocked(false); // TODO make as option + Bangle.setLCDPower(true); // TODO make as option let msgBoxes = []; let i = 0; @@ -136,7 +165,6 @@ const showMessage = function(allMessages, showAll) { i++; } - const drawFooter = function() { let fh = 10; // footer height // left hint: swipe from left for main menu @@ -182,9 +210,6 @@ const showMessage = function(allMessages, showAll) { Bangle.setUI(); return goBack(); // no more messages } - // if (messageNum > 0) msgBoxes[messageNum - 1].reset(MessageBox.prototype.prevOffset); - // msgBoxes[messageNum].reset(); - // if (messageNum < msgBoxes.length - 1) msgBoxes[messageNum + 1].reset(MessageBox.prototype.nextOffset); refresh(); msgBoxes[messageNum].draw(); drawFooter(); @@ -208,12 +233,11 @@ const showMessage = function(allMessages, showAll) { return Bangle.messageResponse(msgBoxes[messageNum].msg, false); // false to dismiss, true to open on phone }; - let animID; const toNext = function(removeCurrent) { if (removeCurrent == undefined) removeCurrent = false; - if (animID){ - clearTimeout(animID); - animID = undefined; + if (timeouts.animID){ + clearTimeout(timeouts.animID); + timeouts.animID = undefined; } firstTouch = true; return new Promise((resolve, _reject) => { @@ -224,9 +248,6 @@ const showMessage = function(allMessages, showAll) { if (!removeCurrent) { if (messageNum < msgBoxes.length) { messageNum++; - // msgBoxes[messageNum - 1].reset(MessageBox.prototype.prevOffset); - // msgBoxes[messageNum].reset(); - // if (messageNum + 1 < msgBoxes.length) msgBoxes[messageNum + 1].reset(MessageBox.prototype.nextOffset); refresh(); } } @@ -237,7 +258,7 @@ const showMessage = function(allMessages, showAll) { msgBoxes[messageNum].draw(); msgBoxes[messageNum + 1].draw(); drawFooter(); - animID = setTimeout(animate, delay); + timeouts.animID = setTimeout(animate, delay); } }; animate(); @@ -246,9 +267,9 @@ const showMessage = function(allMessages, showAll) { const toPrev = function(removeCurrent) { if (removeCurrent == undefined) removeCurrent = false; - if (animID){ - clearTimeout(animID); - animID = undefined; + if (timeouts.animID){ + clearTimeout(timeouts.animID); + timeouts.animID = undefined; } firstTouch = true; return new Promise((resolve, _reject) => { @@ -259,9 +280,6 @@ const showMessage = function(allMessages, showAll) { if (!removeCurrent) { if (messageNum > 0) { messageNum--; - // if (messageNum - 1 > 0) msgBoxes[messageNum - 1].reset(MessageBox.prototype.prevOffset); - // msgBoxes[messageNum].reset(); - // msgBoxes[messageNum + 1].reset(MessageBox.prototype.nextOffset); refresh(); } } @@ -272,7 +290,7 @@ const showMessage = function(allMessages, showAll) { msgBoxes[messageNum].draw(); msgBoxes[messageNum - 1].draw(); drawFooter(); - animID = setTimeout(animate, delay); + timeouts.animID = setTimeout(animate, delay); } }; animate(); @@ -294,9 +312,9 @@ const showMessage = function(allMessages, showAll) { }; const animateToLeft = function() { - if (animID) { - clearTimeout(animID); - animID = undefined; + if (timeouts.animID) { + clearTimeout(timeouts.animID); + timeouts.animID = undefined; } const msgBox = msgBoxes[messageNum]; return new Promise((resolve, _reject) => { @@ -308,7 +326,7 @@ const showMessage = function(allMessages, showAll) { } else { msgBox.draw(); drawFooter(); - let animID = setTimeout(animate, delay); + timeouts.animID = setTimeout(animate, delay); } }; animate(); @@ -316,9 +334,9 @@ const showMessage = function(allMessages, showAll) { }; const animateToRight = function() { - if (animID) { - clearTimeout(animID); - animID = undefined; + if (timeouts.animID) { + clearTimeout(timeouts.animID); + timeouts.animID = undefined; } const msgBox = msgBoxes[messageNum]; return new Promise((resolve, _reject) => { @@ -330,7 +348,7 @@ const showMessage = function(allMessages, showAll) { } else { msgBox.draw(); drawFooter(); - animID = setTimeout(animate, delay); + timeouts.animID = setTimeout(animate, delay); } }; animate(); @@ -339,10 +357,9 @@ const showMessage = function(allMessages, showAll) { let firstTouch = true; const handler = function(e) { - if (updatingMessages) return; if (switching) return; // don't repond to touch while we are animating if (firstTouch) { - idle = false; + setBusy(); if (e.dy > 0 && msgBoxes[messageNum].top) { firstTouch = false; mode = "prev"; @@ -362,10 +379,12 @@ const showMessage = function(allMessages, showAll) { } } if (e.b == 0) { // released finger, reset firstTouch for next time - idle = true; + console.log("should call checkForNewMessages()"); + checkForNewMessages(); firstTouch = true; } delete messageList[messageNum].new; + msgBoxes[messageNum].clearNew(); if (mode == "scroll") scrollHandler(e.dy); else if (mode == "left") leftHandler(e); // remove from phone and watch else if (mode == "right") rightHandler(e); // remove from watch only @@ -448,9 +467,7 @@ const showMessage = function(allMessages, showAll) { msgBoxes[messageNum].draw(); drawFooter(); - idle = true; + checkForNewMessages(); }; -showMessage(Bangle.MESSAGES); - - +showText(Bangle.MESSAGES);