mirror of https://github.com/espruino/BangleApps
new widget: widmsggrid: Messages Grid Widget
Displays multiple notification icons in a grid.pull/2186/head
parent
996f65121c
commit
3c57eeeffd
|
@ -0,0 +1 @@
|
||||||
|
0.01: New widget!
|
|
@ -0,0 +1,23 @@
|
||||||
|
# Messages Grid Widget
|
||||||
|
|
||||||
|
Widget that displays multiple notification icons in a grid.
|
||||||
|
The widget has a fixed size: if there are multiple notifications it uses smaller
|
||||||
|
icons.
|
||||||
|
It shows a single icon per application, so if you have two SMS messages, the
|
||||||
|
grid only has one SMS icon.
|
||||||
|
If there are multiple messages waiting, the total number is shown in the
|
||||||
|
bottom-right corner.
|
||||||
|
|
||||||
|
Example: one SMS, one Signal, and two WhatsApp messages:
|
||||||
|

|
||||||
|
|
||||||
|
## Installation
|
||||||
|
This widget needs the [`messages`](/?id=messages) app to handle notifications.
|
||||||
|
|
||||||
|
## Settings
|
||||||
|
This widget uses the `Widget` settings from the `messages` app:
|
||||||
|
|
||||||
|
### Widget
|
||||||
|
* `Flash icon` Toggle flashing of the widget icons.
|
||||||
|
<!-- * `Show read` - Also show the widget when there are only old messages. -->
|
||||||
|
* `Widget messages` Not used by this widget, but you should select `Hide` to hide the default widget.
|
|
@ -0,0 +1,16 @@
|
||||||
|
{
|
||||||
|
"id": "widmsggrid",
|
||||||
|
"name": "Messages Grid Widget",
|
||||||
|
"version": "0.01",
|
||||||
|
"description": "Widget that display notification icons in a grid",
|
||||||
|
"icon": "widget.png",
|
||||||
|
"type": "widget",
|
||||||
|
"dependencies": {"messages":"app"},
|
||||||
|
"tags": "tool,system",
|
||||||
|
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||||
|
"readme": "README.md",
|
||||||
|
"storage": [
|
||||||
|
{"name":"widmsggrid.wid.js","url":"widget.js"}
|
||||||
|
],
|
||||||
|
"screenshots": [{"url":"screenshot.png"}]
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
|
@ -0,0 +1,92 @@
|
||||||
|
(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"];
|
||||||
|
})();
|
Binary file not shown.
After Width: | Height: | Size: 10 KiB |
Loading…
Reference in New Issue