diff --git a/README.md b/README.md index d2f7022e9..07d831e43 100644 --- a/README.md +++ b/README.md @@ -265,11 +265,15 @@ and which gives information about the app for the Launcher. // 'notify' - provides 'notify' library for showing notifications // 'locale' - provides 'locale' library for language-specific date/distance/etc // (a version of 'locale' is included in the firmware) + // 'module' - this provides a module that can be used with 'require'. + // 'provides_modules' should be used if type:module is specified "tags": "", // comma separated tag list for searching "supports": ["BANGLEJS2"], // List of device IDs supported, either BANGLEJS or BANGLEJS2 "dependencies" : { "notify":"type" } // optional, app 'types' we depend on (see "type" above) "dependencies" : { "messages":"app" } // optional, depend on a specific app ID // for instance this will use notify/notifyfs is they exist, or will pull in 'notify' + "dependencies" : { "messageicons":"module" } // optional, depend on a specific library to be used with 'require' + "provides_modules" : ["messageicons"] // optional, this app provides a module that can be used with 'require' "readme": "README.md", // if supplied, a link to a markdown-style text file // that contains more information about this app (usage, etc) // A 'Read more...' link will be added under the app diff --git a/apps/messageicons/ChangeLog b/apps/messageicons/ChangeLog new file mode 100644 index 000000000..52a4b35a7 --- /dev/null +++ b/apps/messageicons/ChangeLog @@ -0,0 +1 @@ +0.01: Moved message icons from messages into standalone library diff --git a/apps/messageicons/app.png b/apps/messageicons/app.png new file mode 100644 index 000000000..1e47a39c6 Binary files /dev/null and b/apps/messageicons/app.png differ diff --git a/apps/messageicons/lib.js b/apps/messageicons/lib.js new file mode 100644 index 000000000..ff9f4b680 --- /dev/null +++ b/apps/messageicons/lib.js @@ -0,0 +1,104 @@ +exports.getImage = function(msg) { + /* + * icons should be 24x24px or less with 1bpp colors and 'Transparency to Color' + * http://www.espruino.com/Image+Converter + */ + if (msg.img) return atob(msg.img); + const s = (("string"=== typeof msg) ? msg : (msg.src || "")).toLowerCase(); + if (s=="airbnb") return atob("GBgBAAAAAAAAAAAAADwAAH4AAGYAAMMAAIEAAYGAAYGAAzzAA2bABmZgBmZgDGYwDDwwCDwQCBgQDDwwB+fgA8PAAAAAAAAAAAAA"); + if (s=="alarm" || s =="alarmclockreceiver") return atob("GBjBAP////8AAAAAAAACAEAHAOAefng5/5wTgcgHAOAOGHAMGDAYGBgYGBgYGBgYGBgYDhgYBxgMATAOAHAHAOADgcAB/4AAfgAAAAAAAAA="); + if (s=="bibel") return atob("GBgBAAAAA//wD//4D//4H//4H/f4H/f4H+P4H4D4H4D4H/f4H/f4H/f4H/f4H/f4H//4H//4H//4GAAAEAAAEAAACAAAB//4AAAA"); + if (s=="bring") return atob("GBgBAAAAAAAAAAAAAAAAAHwAAFoAAf+AA/+AA/+AA/+AA/eAA+eAA0+AAx+AA7+AA/+AA//AA/+AAf8AAAIAAAAAAAAAAAAAAAAA"); + if (s=="calendar" || s=="etar") return atob("GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgAGB//+B//+B//+B9m2B//+B//+Btm2B//+B//+Btm+B//+B//+A//8AAAAAAAAAAAAA=="); + if (s=="corona-warn") return atob("GBgBAAAAABwAAP+AAf/gA//wB/PwD/PgDzvAHzuAP8EAP8AAPAAAPMAAP8AAH8AAHzsADzuAB/PAB/PgA//wAP/gAH+AAAwAAAAA"); + if (s=="discord") return atob("GBgBAAAAAAAAAAAAAIEABwDgDP8wH//4H//4P//8P//8P//8Pjx8fhh+fzz+f//+f//+e//ePH48HwD4AgBAAAAAAAAAAAAAAAAA"); + if (s=="facebook" || s=="messenger") return atob("GBiBAAAAAAAAAAAYAAD/AAP/wAf/4A/48A/g8B/g+B/j+B/n+D/n/D8A/B8A+B+B+B/n+A/n8A/n8Afn4APnwADnAAAAAAAAAAAAAA=="); + if (s=="gmx") return atob("GBgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEJmfmd8Zuc85v847/88Z9s8fttmHIHiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); + if (s=="google") return atob("GBiBAAAAAAD/AAP/wAf/4A/D4B8AwDwAADwAAHgAAHgAAHAAAHAH/nAH/nAH/ngH/ngAHjwAPDwAfB8A+A/D8Af/4AP/wAD/AAAAAA=="); + if (s=="google home") return atob("GBiCAAAAAAAAAAAAAAAAAAAAAoAAAAAACqAAAAAAKqwAAAAAqroAAAACquqAAAAKq+qgAAAqr/qoAACqv/6qAAKq//+qgA6r///qsAqr///6sAqv///6sAqv///6sAqv///6sA6v///6sA6v///qsA6qqqqqsA6qqqqqsA6qqqqqsAP7///vwAAAAAAAAAAAAAAAAA=="); // 2 bit unpaletted + if (s=="home assistant") return atob("FhaBAAAAAADAAAeAAD8AAf4AD/3AfP8D7fwft/D/P8ec572zbzbNsOEhw+AfD8D8P4fw/z/D/P8P8/w/z/AAAAA="); + if (s=="instagram") return atob("GBiBAAAAAAAAAAAAAAAAAAP/wAYAYAwAMAgAkAh+EAjDEAiBEAiBEAiBEAiBEAjDEAh+EAgAEAwAMAYAYAP/wAAAAAAAAAAAAAAAAA=="); + if (s=="kalender") return atob("GBgBBgBgBQCgff++RQCiRgBiQAACf//+QAACQAACR//iRJkiRIEiR//iRNsiRIEiRJkiR//iRIEiRIEiR//iQAACQAACf//+AAAA"); + if (s=="lieferando") return atob("GBgBABgAAH5wAP9wAf/4A//4B//4D//4H//4P/88fV8+fV4//V4//Vw/HVw4HVw4HBg4HBg4HBg4HDg4Hjw4Hj84Hj44Hj44Hj44"); + if (s=="mattermost") return atob("GBgBAAAAAPAAA+EAB4MADgcYHAcYOA8MOB8OeD8GcD8GcH8GcD8HcD8HeBwHeAAOfAAOfgAePwA8P8D8H//4D//wB//gAf/AAH4A"); + if (s=="n26") return atob("GBgBAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAOIAAOIAAPIAANoAANoAAM4AAMYAAMYAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAA"); + if (s=="nextbike") return atob("GBgBAAAAAAAAAAAAAAAAAAAAAACAfgDAPwDAP4HAH4N4H8f8D82GMd8CMDsDMGMDMGGGGMHOD4D8AAAAAAAAAAAAAAAAAAAAAAAA"); + if (s=="nina") return atob("GBgBAAAABAAQCAAICAAIEAAEEgAkJAgSJBwSKRxKSj4pUn8lVP+VVP+VUgAlSgApKQBKJAASJAASEgAkEAAECAAICAAIBAAQAAAA"); + if (s=="outlook mail") return atob("HBwBAAAAAAAAAAAIAAAfwAAP/gAB/+AAP/5/A//v/D/+/8P/7/g+Pv8Dye/gPd74w5znHDnOB8Oc4Pw8nv/Dwe/8Pj7/w//v/D/+/8P/7/gf/gAA/+AAAfwAAACAAAAAAAAAAAA="); + if (s=="paypal") return atob("GBgBAAAAAAAAAAAAAf+AAf/AAf/gA//gA//gA//wA//wA//wA//wB//wB//wB//gB/+AB/gAB/gAB/gAAPgAAPgAAAAAAAAAAAAA"); + if (s=="phone") return atob("FxeBABgAAPgAAfAAB/AAD+AAH+AAP8AAP4AAfgAA/AAA+AAA+AAA+AAB+AAB+AAB+OAB//AB//gB//gA//AA/8AAf4AAPAA="); + if (s=="post & dhl") return atob("GBgBAPgAE/5wMwZ8NgN8NgP4NgP4HgP4HgPwDwfgD//AB/+AAf8AAAAABs7AHcdgG4MwAAAAGESAFESAEkSAEnyAEkSAFESAGETw"); + if (s=="signal") return atob("GBgBAAAAAGwAAQGAAhggCP8QE//AB//oJ//kL//wD//0D//wT//wD//wL//0J//kB//oA//ICf8ABfxgBYBAADoABMAABAAAAAAA"); + if (s=="skype") return atob("GhoBB8AAB//AA//+Af//wH//+D///w/8D+P8Afz/DD8/j4/H4fP5/A/+f4B/n/gP5//B+fj8fj4/H8+DB/PwA/x/A/8P///B///gP//4B//8AD/+AAA+AA=="); + if (s=="slack") return atob("GBiBAAAAAAAAAABAAAHvAAHvAADvAAAPAB/PMB/veD/veB/mcAAAABzH8B3v+B3v+B3n8AHgAAHuAAHvAAHvAADGAAAAAAAAAAAAAA=="); + if (s=="snapchat") return atob("GBgBAAAAAAAAAH4AAf+AAf+AA//AA//AA//AA//AA//AH//4D//wB//gA//AB//gD//wH//4f//+P//8D//wAf+AAH4AAAAAAAAA"); + if (s=="steam") return atob("GBgBAAAAAAAAAAAAAAAAAAAAAAfgAAwwAAvQABvQABvQADvQgDww4H/g+f8A/zwAf9gAH9AAB8AAACAAAcAAAAAAAAAAAAAAAAAA"); + if (s=="teams") return atob("GBgBAAAAAAAAAAQAAB4AAD8IAA8cP/M+f/scf/gIeDgAfvvefvvffvvffvvffvvff/vff/veP/PeAA/cAH/AAD+AAD8AAAQAAAAA"); + if (s=="telegram" || s=="telegram foss") return atob("GBiBAAAAAAAAAAAAAAAAAwAAHwAA/wAD/wAf3gD/Pgf+fh/4/v/z/P/H/D8P/Acf/AM//AF/+AF/+AH/+ADz+ADh+ADAcAAAMAAAAA=="); + if (s=="threema") return atob("GBjB/4Yx//8AAAAAAAAAAAAAfgAB/4AD/8AH/+AH/+AP//AP2/APw/APw/AHw+AH/+AH/8AH/4AH/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="); + if (s=="to do" || s=="opentasks") return atob("GBgBAAAAAAAAAAAwAAB4AAD8AAH+AAP/DAf/Hg//Px/+f7/8///4///wf//gP//AH/+AD/8AB/4AA/wAAfgAAPAAAGAAAAAAAAAA"); + if (s=="twitch") return atob("GBgBH//+P//+P//+eAAGeAAGeAAGeDGGeDOGeDOGeDOGeDOGeDOGeDOGeAAOeAAOeAAcf4/4f5/wf7/gf//Af/+AA/AAA+AAAcAA"); + if (s=="twitter") return atob("GhYBAABgAAB+JgA/8cAf/ngH/5+B/8P8f+D///h///4f//+D///g///wD//8B//+AP//gD//wAP/8AB/+AB/+AH//AAf/AAAYAAA"); + if (s=="warnapp") return atob("GBgBAAAAAAAAAAAAAH4AAP8AA//AA//AD//gP//gf//4f//+/+P+/8H//8n//4n/fxh/fzg+Pj88Dn44AA4AAAwAAAwAAAgAAAAA"); + if (s=="whatsapp") return atob("GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA=="); + if (s=="wordfeud") return atob("GBgCWqqqqqqlf//////9v//////+v/////++v/////++v8///Lu+v8///L++v8///P/+v8v//P/+v9v//P/+v+fx/P/+v+Pk+P/+v/PN+f/+v/POuv/+v/Ofdv/+v/NvM//+v/I/Y//+v/k/k//+v/i/w//+v/7/6//+v//////+v//////+f//////9Wqqqqqql"); + if (s=="youtube" || s=="newpipe") return atob("GBgBAAAAAAAAAAAAAAAAAf8AH//4P//4P//8P//8P5/8P4/8f4P8f4P8P4/8P5/8P//8P//8P//4H//4Af8AAAAAAAAAAAAAAAAA"); + if (msg.id=="music") return atob("FhaBAH//+/////////////h/+AH/4Af/gB/+H3/7/f/v9/+/3/7+f/vB/w8H+Dwf4PD/x/////////////3//+A="); + // if (s=="sms message" || s=="mail" || s=="gmail") // .. default icon (below) + return atob("FhKBAH//+P//yf/+c//z5/+fz/z/n+f/Pz/+ef/8D///////////////////////f//4///A"); +}; + +exports.getColor = function(msg,options) { + options = options||{}; + var st = options.settings || require('Storage').readJSON("messages.settings.json", 1) || {}; + if (options.default===undefined) options.default=g.theme.fg; + if (st.iconColorMode == 'mono') return options.default; + const s = (("string"=== typeof msg) ? msg : (msg.src || "")).toLowerCase(); + return { + // generic colors, using B2-safe colors + // DO NOT USE BLACK OR WHITE HERE, just leave the declaration out and then the theme's fg color will be used + "airbnb": "#f00", + "mail": "#ff0", + "music": "#f0f", + "phone": "#0f0", + "sms message": "#0ff", + // brands, according to https://www.schemecolor.com/?s (picking one for multicolored logos) + // all dithered on B2, but we only use the color for the icons. (Could maybe pick the closest 3-bit color for B2?) + "bibel": "#54342c", + "bring": "#455a64", + "discord": "#738adb", + "etar": "#36a18b", + "facebook": "#4267b2", + "gmail": "#ea4335", + "gmx": "#1c449b", + "google": "#4285F4", + "google home": "#fbbc05", +// "home assistant": "#41bdf5", // ha-blue is #41bdf5, but that's the background + "instagram": "#dd2a7b", + "lieferando": "#ee5c00", + "messenger": "#0078ff", + "mattermost": "#00f", + "n26": "#36a18b", + "nextbike": "#00f", + "newpipe": "#f00", + "nina": "#e57004", + "opentasks": "#409f8f", + "outlook mail": "#0072c6", + "paypal": "#003087", + "post & dhl": "#f2c101", + "signal": "#00f", + "skype": "#00aff0", + "slack": "#e51670", + "snapchat": "#ff0", + "steam": "#171a21", + "teams": "#464eb8", + "telegram": "#0088cc", + "telegram foss": "#0088cc", + "to do": "#3999e5", + "twitch": "#6441A4", + "twitter": "#1da1f2", + "whatsapp": "#4fce5d", + "wordfeud": "#e7d3c7", + "youtube": "#f00", + }[s]||options.default; +}; diff --git a/apps/messageicons/metadata.json b/apps/messageicons/metadata.json new file mode 100644 index 000000000..eb907f893 --- /dev/null +++ b/apps/messageicons/metadata.json @@ -0,0 +1,14 @@ +{ + "id": "messageicons", + "name": "Message Icons", + "version": "0.01", + "description": "Library containing a list of icons and colors for apps", + "icon": "app.png", + "type": "module", + "tags": "tool,system", + "supports": ["BANGLEJS","BANGLEJS2"], + "provides_modules" : ["messageicons"], + "storage": [ + {"name":"messageicons","url":"lib.js"} + ] +} diff --git a/apps/messages/ChangeLog b/apps/messages/ChangeLog index 17d77cd0d..ee27d41c6 100644 --- a/apps/messages/ChangeLog +++ b/apps/messages/ChangeLog @@ -74,3 +74,4 @@ 0.52: Fix require("messages").buzz() regression Fix background color in messages list after one unread message is shown 0.53: Messages now uses Bangle.load() to load messages app faster (if possible) +0.54: Move icons out to messageicons module diff --git a/apps/messages/app.js b/apps/messages/app.js index f6226d178..bebd92816 100644 --- a/apps/messages/app.js +++ b/apps/messages/app.js @@ -316,10 +316,14 @@ function showMessage(msgid) { {type:"txt", font:fontSmall, label:msg.src||/*LANG*/"Message", bgCol:g.theme.bg2, col: g.theme.fg2, fillx:1, pad:2, halign:1 }, title?{type:"txt", font:titleFont, label:title, bgCol:g.theme.bg2, col: g.theme.fg2, fillx:1, pad:2 }:{}, ]}, - { type:"btn", src:require("messages").getMessageImage(msg), col:require("messages").getMessageImageCol(msg, g.theme.fg2), pad: 3, cb:()=>{ - cancelReloadTimeout(); // don't auto-reload to clock now - showMessageSettings(msg); - }}, + { type:"btn", + src:require("messageicons").getImage(msg), + col:require("messageicons").getColor(msg, {settings:settings, default:g.theme.fg2}), + pad: 3, cb:()=>{ + cancelReloadTimeout(); // don't auto-reload to clock now + showMessageSettings(msg); + } + }, ]}, {type:"txt", font:bodyFont, label:body, fillx:1, filly:1, pad:2, cb:()=>{ // allow tapping to show a larger version @@ -382,14 +386,15 @@ function checkMessages(options) { g.clearRect(r.x,r.y,r.x+r.w, r.y+r.h); if (!msg) return; var x = r.x+2, title = msg.title, body = msg.body; - var img = require("messages").getMessageImage(msg); + var img = require("messageicons").getImage(msg); if (msg.id=="music") { title = msg.artist || /*LANG*/"Music"; body = msg.track; } if (img) { - var fg = g.getColor(); - g.setColor(require("messages").getMessageImageCol(msg,fg)).drawImage(img, x+24, r.y+24, {rotate:0}) // force centering + var fg = g.getColor(), + col = require("messageicons").getColor(msg, {settings:settings, default:fg}); + g.setColor(col).drawImage(img, x+24, r.y+24, {rotate:0}) // force centering .setColor(fg); // only color the icon x += 50; } diff --git a/apps/messages/lib.js b/apps/messages/lib.js index e94d6c8f6..0ed03e4b6 100644 --- a/apps/messages/lib.js +++ b/apps/messages/lib.js @@ -142,22 +142,22 @@ exports.getMessages = function() { exports.buzz = function(msgSrc) { exports.stopBuzz(); // cancel any previous buzz timeouts if ((require('Storage').readJSON('setting.json',1)||{}).quiet) return Promise.resolve(); // never buzz during Quiet Mode - + var msgSettings = require('Storage').readJSON("messages.settings.json", true) || {}; var pattern; if (msgSrc && msgSrc.toLowerCase() === "phone") { // special vibration pattern for incoming calls - pattern = (require('Storage').readJSON("messages.settings.json", true) || {}).vibrateCalls; + pattern = msgSettings.vibrateCalls; } else { - pattern = (require('Storage').readJSON("messages.settings.json", true) || {}).vibrate; + pattern = msgSettings.vibrate; } if (pattern === undefined) { pattern = ":"; } // pattern may be "", so we can't use || ":" here if (!pattern) return Promise.resolve(); - var repeat = (require('Storage').readJSON("messages.settings.json", true) || {}).repeat; + var repeat = msgSettings.repeat; if (repeat===undefined) repeat=4; // repeat may be zero if (repeat) { exports.buzzTimeout = setTimeout(()=>require("buzz").pattern(pattern), repeat*1000); - var vibrateTimeout = (require('Storage').readJSON("messages.settings.json", true) || {}).vibrateTimeout; + var vibrateTimeout = msgSettings.vibrateTimeout; if (vibrateTimeout===undefined) vibrateTimeout=60; if (vibrateTimeout && !exports.stopTimeout) exports.stopTimeout = setTimeout(exports.stopBuzz, vibrateTimeout*1000); } @@ -172,107 +172,3 @@ exports.stopBuzz = function() { if (exports.stopTimeout) clearTimeout(exports.stopTimeout); delete exports.stopTimeout; }; - -exports.getMessageImage = function(msg) { - /* - * icons should be 24x24px or less with 1bpp colors and 'Transparency to Color' - * http://www.espruino.com/Image+Converter - */ - if (msg.img) return atob(msg.img); - const s = (("string"=== typeof msg) ? msg : (msg.src || "")).toLowerCase(); - if (s=="airbnb") return atob("GBgBAAAAAAAAAAAAADwAAH4AAGYAAMMAAIEAAYGAAYGAAzzAA2bABmZgBmZgDGYwDDwwCDwQCBgQDDwwB+fgA8PAAAAAAAAAAAAA"); - if (s=="alarm" || s =="alarmclockreceiver") return atob("GBjBAP////8AAAAAAAACAEAHAOAefng5/5wTgcgHAOAOGHAMGDAYGBgYGBgYGBgYGBgYDhgYBxgMATAOAHAHAOADgcAB/4AAfgAAAAAAAAA="); - if (s=="bibel") return atob("GBgBAAAAA//wD//4D//4H//4H/f4H/f4H+P4H4D4H4D4H/f4H/f4H/f4H/f4H/f4H//4H//4H//4GAAAEAAAEAAACAAAB//4AAAA"); - if (s=="bring") return atob("GBgBAAAAAAAAAAAAAAAAAHwAAFoAAf+AA/+AA/+AA/+AA/eAA+eAA0+AAx+AA7+AA/+AA//AA/+AAf8AAAIAAAAAAAAAAAAAAAAA"); - if (s=="calendar" || s=="etar") return atob("GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgAGB//+B//+B//+B9m2B//+B//+Btm2B//+B//+Btm+B//+B//+A//8AAAAAAAAAAAAA=="); - if (s=="corona-warn") return atob("GBgBAAAAABwAAP+AAf/gA//wB/PwD/PgDzvAHzuAP8EAP8AAPAAAPMAAP8AAH8AAHzsADzuAB/PAB/PgA//wAP/gAH+AAAwAAAAA"); - if (s=="discord") return atob("GBgBAAAAAAAAAAAAAIEABwDgDP8wH//4H//4P//8P//8P//8Pjx8fhh+fzz+f//+f//+e//ePH48HwD4AgBAAAAAAAAAAAAAAAAA"); - if (s=="facebook" || s=="messenger") return atob("GBiBAAAAAAAAAAAYAAD/AAP/wAf/4A/48A/g8B/g+B/j+B/n+D/n/D8A/B8A+B+B+B/n+A/n8A/n8Afn4APnwADnAAAAAAAAAAAAAA=="); - if (s=="gmx") return atob("GBgBAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHEJmfmd8Zuc85v847/88Z9s8fttmHIHiAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"); - if (s=="google") return atob("GBiBAAAAAAD/AAP/wAf/4A/D4B8AwDwAADwAAHgAAHgAAHAAAHAH/nAH/nAH/ngH/ngAHjwAPDwAfB8A+A/D8Af/4AP/wAD/AAAAAA=="); - if (s=="google home") return atob("GBiCAAAAAAAAAAAAAAAAAAAAAoAAAAAACqAAAAAAKqwAAAAAqroAAAACquqAAAAKq+qgAAAqr/qoAACqv/6qAAKq//+qgA6r///qsAqr///6sAqv///6sAqv///6sAqv///6sA6v///6sA6v///qsA6qqqqqsA6qqqqqsA6qqqqqsAP7///vwAAAAAAAAAAAAAAAAA=="); // 2 bit unpaletted - if (s=="home assistant") return atob("FhaBAAAAAADAAAeAAD8AAf4AD/3AfP8D7fwft/D/P8ec572zbzbNsOEhw+AfD8D8P4fw/z/D/P8P8/w/z/AAAAA="); - if (s=="instagram") return atob("GBiBAAAAAAAAAAAAAAAAAAP/wAYAYAwAMAgAkAh+EAjDEAiBEAiBEAiBEAiBEAjDEAh+EAgAEAwAMAYAYAP/wAAAAAAAAAAAAAAAAA=="); - if (s=="kalender") return atob("GBgBBgBgBQCgff++RQCiRgBiQAACf//+QAACQAACR//iRJkiRIEiR//iRNsiRIEiRJkiR//iRIEiRIEiR//iQAACQAACf//+AAAA"); - if (s=="lieferando") return atob("GBgBABgAAH5wAP9wAf/4A//4B//4D//4H//4P/88fV8+fV4//V4//Vw/HVw4HVw4HBg4HBg4HBg4HDg4Hjw4Hj84Hj44Hj44Hj44"); - if (s=="mattermost") return atob("GBgBAAAAAPAAA+EAB4MADgcYHAcYOA8MOB8OeD8GcD8GcH8GcD8HcD8HeBwHeAAOfAAOfgAePwA8P8D8H//4D//wB//gAf/AAH4A"); - if (s=="n26") return atob("GBgBAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAOIAAOIAAPIAANoAANoAAM4AAMYAAMYAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAA"); - if (s=="nextbike") return atob("GBgBAAAAAAAAAAAAAAAAAAAAAACAfgDAPwDAP4HAH4N4H8f8D82GMd8CMDsDMGMDMGGGGMHOD4D8AAAAAAAAAAAAAAAAAAAAAAAA"); - if (s=="nina") return atob("GBgBAAAABAAQCAAICAAIEAAEEgAkJAgSJBwSKRxKSj4pUn8lVP+VVP+VUgAlSgApKQBKJAASJAASEgAkEAAECAAICAAIBAAQAAAA"); - if (s=="outlook mail") return atob("HBwBAAAAAAAAAAAIAAAfwAAP/gAB/+AAP/5/A//v/D/+/8P/7/g+Pv8Dye/gPd74w5znHDnOB8Oc4Pw8nv/Dwe/8Pj7/w//v/D/+/8P/7/gf/gAA/+AAAfwAAACAAAAAAAAAAAA="); - if (s=="paypal") return atob("GBgBAAAAAAAAAAAAAf+AAf/AAf/gA//gA//gA//wA//wA//wA//wB//wB//wB//gB/+AB/gAB/gAB/gAAPgAAPgAAAAAAAAAAAAA"); - if (s=="phone") return atob("FxeBABgAAPgAAfAAB/AAD+AAH+AAP8AAP4AAfgAA/AAA+AAA+AAA+AAB+AAB+AAB+OAB//AB//gB//gA//AA/8AAf4AAPAA="); - if (s=="post & dhl") return atob("GBgBAPgAE/5wMwZ8NgN8NgP4NgP4HgP4HgPwDwfgD//AB/+AAf8AAAAABs7AHcdgG4MwAAAAGESAFESAEkSAEnyAEkSAFESAGETw"); - if (s=="signal") return atob("GBgBAAAAAGwAAQGAAhggCP8QE//AB//oJ//kL//wD//0D//wT//wD//wL//0J//kB//oA//ICf8ABfxgBYBAADoABMAABAAAAAAA"); - if (s=="skype") return atob("GhoBB8AAB//AA//+Af//wH//+D///w/8D+P8Afz/DD8/j4/H4fP5/A/+f4B/n/gP5//B+fj8fj4/H8+DB/PwA/x/A/8P///B///gP//4B//8AD/+AAA+AA=="); - if (s=="slack") return atob("GBiBAAAAAAAAAABAAAHvAAHvAADvAAAPAB/PMB/veD/veB/mcAAAABzH8B3v+B3v+B3n8AHgAAHuAAHvAAHvAADGAAAAAAAAAAAAAA=="); - if (s=="snapchat") return atob("GBgBAAAAAAAAAH4AAf+AAf+AA//AA//AA//AA//AA//AH//4D//wB//gA//AB//gD//wH//4f//+P//8D//wAf+AAH4AAAAAAAAA"); - if (s=="steam") return atob("GBgBAAAAAAAAAAAAAAAAAAAAAAfgAAwwAAvQABvQABvQADvQgDww4H/g+f8A/zwAf9gAH9AAB8AAACAAAcAAAAAAAAAAAAAAAAAA"); - if (s=="teams") return atob("GBgBAAAAAAAAAAQAAB4AAD8IAA8cP/M+f/scf/gIeDgAfvvefvvffvvffvvffvvff/vff/veP/PeAA/cAH/AAD+AAD8AAAQAAAAA"); - if (s=="telegram" || s=="telegram foss") return atob("GBiBAAAAAAAAAAAAAAAAAwAAHwAA/wAD/wAf3gD/Pgf+fh/4/v/z/P/H/D8P/Acf/AM//AF/+AF/+AH/+ADz+ADh+ADAcAAAMAAAAA=="); - if (s=="threema") return atob("GBjB/4Yx//8AAAAAAAAAAAAAfgAB/4AD/8AH/+AH/+AP//AP2/APw/APw/AHw+AH/+AH/8AH/4AH/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA="); - if (s=="to do" || s=="opentasks") return atob("GBgBAAAAAAAAAAAwAAB4AAD8AAH+AAP/DAf/Hg//Px/+f7/8///4///wf//gP//AH/+AD/8AB/4AA/wAAfgAAPAAAGAAAAAAAAAA"); - if (s=="twitch") return atob("GBgBH//+P//+P//+eAAGeAAGeAAGeDGGeDOGeDOGeDOGeDOGeDOGeDOGeAAOeAAOeAAcf4/4f5/wf7/gf//Af/+AA/AAA+AAAcAA"); - if (s=="twitter") return atob("GhYBAABgAAB+JgA/8cAf/ngH/5+B/8P8f+D///h///4f//+D///g///wD//8B//+AP//gD//wAP/8AB/+AB/+AH//AAf/AAAYAAA"); - if (s=="warnapp") return atob("GBgBAAAAAAAAAAAAAH4AAP8AA//AA//AD//gP//gf//4f//+/+P+/8H//8n//4n/fxh/fzg+Pj88Dn44AA4AAAwAAAwAAAgAAAAA"); - if (s=="whatsapp") return atob("GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA=="); - if (s=="wordfeud") return atob("GBgCWqqqqqqlf//////9v//////+v/////++v/////++v8///Lu+v8///L++v8///P/+v8v//P/+v9v//P/+v+fx/P/+v+Pk+P/+v/PN+f/+v/POuv/+v/Ofdv/+v/NvM//+v/I/Y//+v/k/k//+v/i/w//+v/7/6//+v//////+v//////+f//////9Wqqqqqql"); - if (s=="youtube" || s=="newpipe") return atob("GBgBAAAAAAAAAAAAAAAAAf8AH//4P//4P//8P//8P5/8P4/8f4P8f4P8P4/8P5/8P//8P//8P//4H//4Af8AAAAAAAAAAAAAAAAA"); - if (msg.id=="music") return atob("FhaBAH//+/////////////h/+AH/4Af/gB/+H3/7/f/v9/+/3/7+f/vB/w8H+Dwf4PD/x/////////////3//+A="); - // if (s=="sms message" || s=="mail" || s=="gmail") // .. default icon (below) - return atob("FhKBAH//+P//yf/+c//z5/+fz/z/n+f/Pz/+ef/8D///////////////////////f//4///A"); -}; - -exports.getMessageImageCol = function(msg,def) { - let iconColorMode = (require('Storage').readJSON("messages.settings.json", 1) || {}).iconColorMode; - if (iconColorMode == 'mono') - return g.theme.fg; - const s = (("string"=== typeof msg) ? msg : (msg.src || "")).toLowerCase(); - return { - // generic colors, using B2-safe colors - // DO NOT USE BLACK OR WHITE HERE, just leave the declaration out and then the theme's fg color will be used - "airbnb": "#f00", - "mail": "#ff0", - "music": "#f0f", - "phone": "#0f0", - "sms message": "#0ff", - // brands, according to https://www.schemecolor.com/?s (picking one for multicolored logos) - // all dithered on B2, but we only use the color for the icons. (Could maybe pick the closest 3-bit color for B2?) - "bibel": "#54342c", - "bring": "#455a64", - "discord": "#738adb", - "etar": "#36a18b", - "facebook": "#4267b2", - "gmail": "#ea4335", - "gmx": "#1c449b", - "google": "#4285F4", - "google home": "#fbbc05", -// "home assistant": "#41bdf5", // ha-blue is #41bdf5, but that's the background - "instagram": "#dd2a7b", - "lieferando": "#ee5c00", - "messenger": "#0078ff", - "mattermost": "#00f", - "n26": "#36a18b", - "nextbike": "#00f", - "newpipe": "#f00", - "nina": "#e57004", - "opentasks": "#409f8f", - "outlook mail": "#0072c6", - "paypal": "#003087", - "post & dhl": "#f2c101", - "signal": "#00f", - "skype": "#00aff0", - "slack": "#e51670", - "snapchat": "#ff0", - "steam": "#171a21", - "teams": "#464eb8", - "telegram": "#0088cc", - "telegram foss": "#0088cc", - "to do": "#3999e5", - "twitch": "#6441A4", - "twitter": "#1da1f2", - "whatsapp": "#4fce5d", - "wordfeud": "#e7d3c7", - "youtube": "#f00", - }[s]||(def !== undefined?def:g.theme.fg); -}; diff --git a/apps/messages/metadata.json b/apps/messages/metadata.json index bc6d18f3f..f3051958e 100644 --- a/apps/messages/metadata.json +++ b/apps/messages/metadata.json @@ -1,12 +1,13 @@ { "id": "messages", "name": "Messages", - "version": "0.53", + "version": "0.54", "description": "App to display notifications from iOS and Gadgetbridge/Android", "icon": "app.png", "type": "app", "tags": "tool,system", "supports": ["BANGLEJS","BANGLEJS2"], + "dependencies" : { "messageicons":"module" }, "readme": "README.md", "storage": [ {"name":"messages.app.js","url":"app.js"}, diff --git a/apps/messages/widget.js b/apps/messages/widget.js index c8d132f82..c0dcd132f 100644 --- a/apps/messages/widget.js +++ b/apps/messages/widget.js @@ -21,7 +21,8 @@ WIDGETS["messages"]={area:"tl", width:0, draw:function(recall) { g.reset().clearRect(this.x, this.y, this.x+this.width, this.y+23); for(let i = 0;i < msgsShown;i++) { const msg = this.msgs[i]; - const colors = [g.theme.bg, g.setColor(require("messages").getMessageImageCol(msg)).getColor()]; + const colors = [g.theme.bg, + require("messageicons").getColor(msg, {settings:settings})]; if (settings.flash && ((Date.now()/1000)&1)) { if (colors[1] == g.theme.fg) { colors.reverse(); @@ -31,7 +32,7 @@ WIDGETS["messages"]={area:"tl", width:0, draw:function(recall) { } g.setColor(colors[1]).setBgColor(colors[0]); // draw the icon, or '...' if too many messages - g.drawImage(i == (settings.maxMessages - 1) && this.msgs.length > settings.maxMessages ? atob("EASBAGGG88/zz2GG") : require("messages").getMessageImage(msg), + g.drawImage(i == (settings.maxMessages - 1) && this.msgs.length > settings.maxMessages ? atob("EASBAGGG88/zz2GG") : require("messageicons").getImage(msg), this.x + 12 + i * 24, this.y + 12, {rotate:0/*force centering*/}); } } diff --git a/apps/widmsggrid/ChangeLog b/apps/widmsggrid/ChangeLog index 4be6afb16..75259c4f0 100644 --- a/apps/widmsggrid/ChangeLog +++ b/apps/widmsggrid/ChangeLog @@ -1 +1,2 @@ -0.01: New widget! \ No newline at end of file +0.01: New widget! +0.02: Adjust to message icons moving to messageicons lib diff --git a/apps/widmsggrid/metadata.json b/apps/widmsggrid/metadata.json index b624f5c23..c9ed5bbe0 100644 --- a/apps/widmsggrid/metadata.json +++ b/apps/widmsggrid/metadata.json @@ -1,13 +1,14 @@ { "id": "widmsggrid", "name": "Messages Grid Widget", - "version": "0.01", + "version": "0.02", "description": "Widget that display notification icons in a grid", "icon": "widget.png", "type": "widget", "dependencies": {"messages":"app"}, "tags": "tool,system", "supports": ["BANGLEJS","BANGLEJS2"], + "dependencies" : { "messageicons":"module" }, "readme": "README.md", "storage": [ {"name":"widmsggrid.wid.js","url":"widget.js"} diff --git a/apps/widmsggrid/widget.js b/apps/widmsggrid/widget.js index 7c5882e6c..431adf479 100644 --- a/apps/widmsggrid/widget.js +++ b/apps/widmsggrid/widget.js @@ -32,15 +32,17 @@ .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 + let icons = require("messageicons"); + let defaultCol = icons.getColor("alert", {settings:settings}); w.srcs.forEach(src => { - const appColor = require("messages").getMessageImageCol(src, require("messages").getMessageImageCol("alert")); - let colors = [g.theme.bg, g.setColor(appColor).getColor()]; + const appColor = icons.getColor(src, {settings:settings,default:defaultCol}); + let colors = [g.theme.bg, appColor]; 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 }); + g.drawImage(icons.getImage(src), w.x+offset(c), w.y+offset(r), { scale: 1 / cols }); if (++c >= cols) { c = 0; r++; @@ -89,4 +91,4 @@ }; delete s; const w = WIDGETS["msggrid"]; -})(); \ No newline at end of file +})(); diff --git a/bin/sanitycheck.js b/bin/sanitycheck.js index c7dbb0d03..dddccf3a8 100755 --- a/bin/sanitycheck.js +++ b/bin/sanitycheck.js @@ -76,12 +76,12 @@ const APP_KEYS = [ 'id', 'name', 'shortName', 'version', 'icon', 'screenshots', 'description', 'tags', 'type', 'sortorder', 'readme', 'custom', 'customConnect', 'interface', 'storage', 'data', 'supports', 'allow_emulator', - 'dependencies' + 'dependencies', 'provides_modules' ]; const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate', 'noOverwite', 'supports', 'noOverwrite']; const DATA_KEYS = ['name', 'wildcard', 'storageFile', 'url', 'content', 'evaluate']; const SUPPORTS_DEVICES = ["BANGLEJS","BANGLEJS2"]; // device IDs allowed for 'supports' -const METADATA_TYPES = ["app","clock","widget","bootloader","RAM","launch","textinput","scheduler","notify","locale","settings","waypoints"]; // values allowed for "type" field +const METADATA_TYPES = ["app","clock","widget","bootloader","RAM","launch","scheduler","notify","locale","settings","waypoints","module"]; // values allowed for "type" field const FORBIDDEN_FILE_NAME_CHARS = /[,;]/; // used as separators in appid.info const VALID_DUPLICATES = [ '.tfmodel', '.tfnames' ]; const GRANDFATHERED_ICONS = ["s7clk", "snek", "astral", "alpinenav", "slomoclock", "arrow", "pebble", "rebble"]; @@ -167,16 +167,15 @@ apps.forEach((app,appIdx) => { if (app.dependencies) { if (("object"==typeof app.dependencies) && !Array.isArray(app.dependencies)) { Object.keys(app.dependencies).forEach(dependency => { - if (!["type","app"].includes(app.dependencies[dependency])) - ERROR(`App ${app.id} 'dependencies' must all be tagged 'type' or 'app' right now`, {file:metadataFile}); + if (!["type","app","module"].includes(app.dependencies[dependency])) + ERROR(`App ${app.id} 'dependencies' must all be tagged 'type/app/module' right now`, {file:metadataFile}); if (app.dependencies[dependency]=="type" && !METADATA_TYPES.includes(dependency)) ERROR(`App ${app.id} 'type' dependency must be one of `+METADATA_TYPES, {file:metadataFile}); - }); } else ERROR(`App ${app.id} 'dependencies' must be an object`, {file:metadataFile}); } - + var fileNames = []; app.storage.forEach((file) => { if (!file.name) ERROR(`App ${app.id} has a file with no name`, {file:metadataFile}); @@ -236,7 +235,7 @@ apps.forEach((app,appIdx) => { // clock app checks if (app.type=="clock") { var a = fileContents.indexOf("Bangle.loadWidgets()"); - var b = fileContents.indexOf("Bangle.setUI("); + var b = fileContents.indexOf("Bangle.setUI("); if (a>=0 && b>=0 && a { ERROR(`App ${app.id} should include file named ${fileName} but it doesn't`, {file:metadataFile}); }); } + if (app.type=="module" && !app.provides_modules) { + ERROR(`App ${app.id} has type:module but it doesn't have a provides_modules field`, {file:metadataFile}); + } + if (app.provides_modules) { + app.provides_modules.forEach(modulename => { + if (!app.storage.find(s=>s.name==modulename)) + ERROR(`App ${app.id} has provides_modules ${modulename} but it doesn't provide that filename`, {file:metadataFile}); + }); + } }); diff --git a/core b/core index b294d25f3..c379f01ca 160000 --- a/core +++ b/core @@ -1 +1 @@ -Subproject commit b294d25f395c0d2830dcb4203a6aff46339d17b7 +Subproject commit c379f01cac3f41e3d60ec4ff2d162331fffb799f