(function () { if (global.MESSAGES) return; // don't load widget while in the app let settings = require('Storage').readJSON("messages.settings.json", true) || {}; const s = { flash: (settings.flash === undefined) ? true : !!settings.flash, showRead: !!settings.showRead, }; delete settings; WIDGETS["msggrid"] = { area: "tl", width: 0, flash: s.flash, showRead: s.showRead, init: function() { // runs on first draw delete w.init; // don't run again Bangle.on("touch", w.touch); Bangle.on("message", w.listener); w.listener(); // update status now }, draw: function () { if (w.init) w.init(); // If we had a setTimeout queued from the last time we were called, remove it if (w.t) { clearTimeout(w.t); delete w.t; } if (!w.width) return; const b = w.flash && w.status === "new" && ((Date.now() / 1000) & 1), // Blink(= inverse colors) on this second? // show multiple icons in a grid, by scaling them down cols = Math.ceil(Math.sqrt(w.srcs.length - 0.1)); // cols===rows, -0.1 to work around rounding error g.reset().clearRect(w.x, w.y, w.x + w.width - 1, w.y + 24) .setClipRect(w.x, w.y, w.x + w.width - 1, w.y + 24); // guard against oversized icons let r = 0, c = 0; // row, column const offset = pos => Math.floor(pos / cols * 24); // pixel offset for position in row/column w.srcs.forEach(src => { const appColor = require("messages").getMessageImageCol(src, require("messages").getMessageImageCol("alert")); let colors = [g.theme.bg, g.setColor(appColor).getColor()]; if (b) { if (colors[1] == g.theme.fg) colors = colors.reverse(); else colors[1] = g.theme.fg; } g.setColor(colors[1]).setBgColor(colors[0]); g.drawImage(require("messages").getMessageImage(src, "alert"), w.x+offset(c), w.y+offset(r), { scale: 1 / cols }); if (++c >= cols) { c = 0; r++; } }); if (w.total > 1) { // show total number of messages in bottom-right corner g.reset(); if (w.total < 10) g.fillCircle(w.x + w.width - 5, w.y + 20, 4); // single digits get a round background, double digits fill their rectangle g.setColor(g.theme.bg).setBgColor(g.theme.fg) .setFont('6x8').setFontAlign(1, 1) .drawString(w.total, w.x + w.width - 1, w.y + 24, w.total > 9); } if (w.flash && w.status === "new") w.t = setTimeout(w.draw, 1000); // schedule redraw while blinking }, show: function () { w.width = 24; w.srcs = require("messages").getMessages() .filter(m => !['call', 'map', 'music'].includes(m.id)) .filter(m => m.new || w.showRead) .map(m => m.src); w.total = w.srcs.length; w.srcs = w.srcs.filter((src, i, uniq) => uniq.indexOf(src) === i); // keep unique entries only Bangle.drawWidgets(); Bangle.setLCDPower(1); // turns screen on }, hide: function () { w.width = 0; w.srcs = []; w.total = 0; Bangle.drawWidgets(); }, touch: function (b, c) { if (!w || !w.width) return; // widget not shown if (process.env.HWVERSION < 2) { // Bangle.js 1: open app when on clock we touch the side with widget if (!Bangle.CLOCK) return; const m = Bangle.appRect / 2; if ((w.x < m && b !== 1) || (w.x > m && b !== 2)) return; } // Bangle.js 2: open app when touching the widget else if (c.x < w.x || c.x > w.x + w.width || c.y < w.y || c.y > w.y + 24) return; load("messages.app.js"); }, listener: function () { w.status = require("messages").status(); if (w.status === "new" || (w.status === "old" && w.showRead)) w.show(); else w.hide(); } }; delete s; const w = WIDGETS["msggrid"]; })();