diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 77334c54d..14f667ad7 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -53,3 +53,4 @@ 0.38: Add telegram foss handling 0.39: Set default color for message icons according to theme 0.40: Use default Bangle formatter for booleans +0.41: Add notification icons in the widget \ No newline at end of file diff --git a/apps/messages/README.md b/apps/messages/README.md index da2701f35..878e03636 100644 --- a/apps/messages/README.md +++ b/apps/messages/README.md @@ -22,12 +22,13 @@ it starts getting clipped. * `Auto-Open Music` - Should the app automatically open when the phone starts playing music? * `Unlock Watch` - Should the app unlock the watch when a new message arrives, so you can touch the buttons at the bottom of the app? * `Flash Icon` - Toggle flashing of the widget icon. +* `Widget messages` - The maximum amount of message icons to show on the widget. ## New Messages When a new message is received: -* If you're in an app, the Bangle will buzz and a 'new message' icon appears in the Widget bar. You can tap this bar to view the message. +* If you're in an app, the Bangle will buzz and a message icon appears in the Widget bar. You can tap this icon to view the message. * If you're in a clock, the Messages app will automatically start and show the message When a message is shown, you'll see a screen showing the message title and text. diff --git a/apps/messages/lib.js b/apps/messages/lib.js index 3f801e101..3c6fbc880 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -85,7 +85,7 @@ exports.pushMessage = function(event) { return load("messages.app.js"); } if (!quiet && (!global.WIDGETS || !WIDGETS.messages)) return Bangle.buzz(); // no widgets - just buzz to let someone know - WIDGETS.messages.show(); + if (global.WIDGETS && WIDGETS.messages) WIDGETS.messages.update(messages); }, 500); } /// Remove all messages @@ -102,7 +102,7 @@ exports.clearAll = function(event) { if (inApp) return onMessagesModified(); // if we have a widget, update it if (global.WIDGETS && WIDGETS.messages) - WIDGETS.messages.hide(); + WIDGETS.messages.update(messages); } exports.getMessageImage = function(msg) { diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index b30d31705..a423ecafb 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,7 +1,7 @@ { "id": "messages", "name": "Messages", - "version": "0.40", + "version": "0.41", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", diff --git a/apps/messages/screenshot-notify.gif b/apps/messages/screenshot-notify.gif index 3d0ed0b32..e5cc669bd 100644 Binary files a/apps/messages/screenshot-notify.gif and b/apps/messages/screenshot-notify.gif differ diff --git a/apps/messages/settings.js b/apps/messages/settings.js index b708213be..97584f01a 100644 --- a/apps/messages/settings.js +++ b/apps/messages/settings.js @@ -4,6 +4,7 @@ if (settings.vibrate===undefined) settings.vibrate=":"; if (settings.repeat===undefined) settings.repeat=4; if (settings.unreadTimeout===undefined) settings.unreadTimeout=60; + if (settings.maxMessages===undefined) settings.maxMessages=3; settings.unlockWatch=!!settings.unlockWatch; settings.openMusic=!!settings.openMusic; settings.maxUnreadTimeout=240; @@ -54,6 +55,11 @@ value: !!settings().quietNoAutOpn, onchange: v => updateSetting("quietNoAutOpn", v) }, + /*LANG*/'Widget messages': { + value:0|settings().maxMessages, + min: 1, max: 5, + onchange: v => updateSetting("maxMessages", v) + } }; E.showMenu(mainmenu); }) diff --git a/apps/messages/widget.js b/apps/messages/widget.js index 25573220f..13eb1c0ef 100644 --- a/apps/messages/widget.js +++ b/apps/messages/widget.js @@ -1,3 +1,15 @@ +(() => { + +function getMessages() { + if ("undefined"!=typeof MESSAGES) return MESSAGES; + return require("Storage").readJSON("messages.json",1)||[]; +} + +function filterMessages(msgs) { + return msgs.filter(msg => msg.new && msg.id != "music") + .filter((msg, i, arr) => arr.findIndex(nmsg => msg.src == nmsg.src) == i); +} + WIDGETS["messages"]={area:"tl", width:0, iconwidth:24, draw:function(recall) { // If we had a setTimeout queued from the last time we were called, remove it @@ -11,8 +23,21 @@ draw:function(recall) { let settings = require('Storage').readJSON("messages.settings.json", true) || {}; if (settings.flash===undefined) settings.flash = true; if (recall !== true || settings.flash) { + var msgsShown = E.clip(this.msgs.length, 0, settings.maxMessages); g.reset().clearRect(this.x, this.y, this.x+this.width, this.y+23); - g.drawImage(settings.flash && (c&1) ? atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+DAADDAADDAADDwAPD8A/DOBzDDn/DA//DAHvDAPvjAPvjAPvjAPvh///gf/vAAD+AAB8AAAAA==") : atob("GBiBAAAAAAAAAAAAAAAAAAAAAB//+D///D///A//8CP/xDj/HD48DD+B8D/D+D/3vD/vvj/vvj/vvj/vvh/v/gfnvAAD+AAB8AAAAA=="), this.x, this.y-1); + for(let i = 0;i < msgsShown;i++) { + const msg = this.msgs[i]; + const colors = [g.theme.bg, g.setColor(require("messages").getMessageImageCol(msg)).getColor()]; + if (settings.flash && (c&1)) { + if (colors[1] == g.theme.fg) { + colors.reverse(); + } else { + colors[1] = g.theme.fg; + } + } + g.setColor(colors[1]).setBgColor(colors[0]); + g.drawImage(i == (settings.maxMessages - 1) && msgs.length > settings.maxMessages ? atob("GBgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH4H4H4H4H4H4H4H4H4H4H4H4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA") : require("messages").getMessageImage(msg), this.x + i * this.iconwidth, this.y - 1); + } } if (settings.repeat===undefined) settings.repeat = 4; if (c<120 && (Date.now()-this.l)>settings.repeat*1000) { @@ -21,16 +46,19 @@ draw:function(recall) { } WIDGETS["messages"].i=setTimeout(()=>WIDGETS["messages"].draw(true), 1000); if (process.env.HWVERSION>1) Bangle.on('touch', this.touch); -},show:function(quiet) { - WIDGETS["messages"].t=Date.now(); // first time - WIDGETS["messages"].l=Date.now()-10000; // last buzz - if (quiet) WIDGETS["messages"].t -= 500000; // if quiet, set last time in the past so there is no buzzing - WIDGETS["messages"].width=this.iconwidth; - Bangle.drawWidgets(); -},hide:function() { - delete WIDGETS["messages"].t; - delete WIDGETS["messages"].l; - WIDGETS["messages"].width=0; +},update:function(rawMsgs, quiet) { + const settings = require('Storage').readJSON("messages.settings.json", true) || {}; + msgs = filterMessages(rawMsgs); + if (msgs.length === 0) { + delete WIDGETS["messages"].t; + delete WIDGETS["messages"].l; + } else { + WIDGETS["messages"].t=Date.now(); // first time + WIDGETS["messages"].l=Date.now()-10000; // last buzz + if (quiet) WIDGETS["messages"].t -= 500000; // if quiet, set last time in the past so there is no buzzing + } + WIDGETS["messages"].width=this.iconwidth * E.clip(msgs.length, 0, settings.maxMessages); + WIDGETS["messages"].msgs = msgs; Bangle.drawWidgets(); },buzz:function() { if ((require('Storage').readJSON('setting.json',1)||{}).quiet) return; // never buzz during Quiet Mode @@ -40,10 +68,11 @@ draw:function(recall) { if (!w||!w.width||c.xw.x+w.width||c.yw.y+w.iconwidth) return; load("messages.app.js"); }}; + /* We might have returned here if we were in the Messages app for a message but then the watch was never viewed. In that case we don't want to buzz but should still show that there are unread messages. */ -if (global.MESSAGES===undefined) (function() { - var messages = require("Storage").readJSON("messages.json",1)||[]; - if (messages.some(m=>m.new&&m.id!="music")) WIDGETS["messages"].show(true); +if (global.MESSAGES===undefined) + WIDGETS["messages"].update(getMessages(), true); + })();