diff --git a/apps/ashadyclock/0.bin b/apps/ashadyclock/0.bin new file mode 100644 index 000000000..0be5abd15 Binary files /dev/null and b/apps/ashadyclock/0.bin differ diff --git a/apps/ashadyclock/1.bin b/apps/ashadyclock/1.bin new file mode 100644 index 000000000..54fe59905 Binary files /dev/null and b/apps/ashadyclock/1.bin differ diff --git a/apps/ashadyclock/2.bin b/apps/ashadyclock/2.bin new file mode 100644 index 000000000..a95c74b20 Binary files /dev/null and b/apps/ashadyclock/2.bin differ diff --git a/apps/ashadyclock/3.bin b/apps/ashadyclock/3.bin new file mode 100644 index 000000000..db3821284 Binary files /dev/null and b/apps/ashadyclock/3.bin differ diff --git a/apps/ashadyclock/4.bin b/apps/ashadyclock/4.bin new file mode 100644 index 000000000..b59e41a0d Binary files /dev/null and b/apps/ashadyclock/4.bin differ diff --git a/apps/ashadyclock/5.bin b/apps/ashadyclock/5.bin new file mode 100644 index 000000000..10985534a Binary files /dev/null and b/apps/ashadyclock/5.bin differ diff --git a/apps/ashadyclock/6.bin b/apps/ashadyclock/6.bin new file mode 100644 index 000000000..d45f451b6 Binary files /dev/null and b/apps/ashadyclock/6.bin differ diff --git a/apps/ashadyclock/7.bin b/apps/ashadyclock/7.bin new file mode 100644 index 000000000..f847816ab Binary files /dev/null and b/apps/ashadyclock/7.bin differ diff --git a/apps/ashadyclock/8.bin b/apps/ashadyclock/8.bin new file mode 100644 index 000000000..deb47c3c0 Binary files /dev/null and b/apps/ashadyclock/8.bin differ diff --git a/apps/ashadyclock/9.bin b/apps/ashadyclock/9.bin new file mode 100644 index 000000000..c806c2012 Binary files /dev/null and b/apps/ashadyclock/9.bin differ diff --git a/apps/ashadyclock/app-icon.js b/apps/ashadyclock/app-icon.js new file mode 100644 index 000000000..3e45d1754 --- /dev/null +++ b/apps/ashadyclock/app-icon.js @@ -0,0 +1 @@ +E.toArrayBuffer(atob("MDADAAAAHA4HHAAAHA4HA4HA4HAAAAA4//////AAH//////6///AAAA///6//9AAV/////////XAAAA//////6AAv//X//////4AAAA//////4AA////X/////4AAAA//////4AA/////6////4AAAA//////4AA///6vX///v4AAAAAA////4AA///4A//6//AAAAAAF///64AAHA4CFX////AAAAAAH//X/oAAAAAAH6///4AAAAAAH////AAAAAAAH////QAAAAAAH////AAAAAAA/////AAAAAAAH////AAAAAAC////4AAAAAAAH////AAAAAAH////4AAAAAAA6v///AAAAAA//X/9QAAAAAAA////VAAAAAA////4AAAAAAAA////4AAAAAH////4AAAAAAAA////4AAAAA/6///AAAAAAAAA////4AAAAA////6AAAAAAAAF////4AAAAH/X/94AAAAAAAAH/X//oAAAAX////AAAAAAAAAH////AAAAA/////AAAAAAAAAH////AEQAB+///4AwEAAAAAAH////AigAH////4EUGEAAAAAX////A0GA///3/AmEUigAAAAjGMYxEw0AxxGOIGg0w0igAAGikUwmGmmgwEUwmmGmk0wwAAmmmmmmmGmmgimmmmmmmGmgAGmmmGgGmmmmAmmmmiE0w00wAE0000wE000wwmmmmiA0000wAE00U0AGmmmmA0000wE0U00wAAAAAAAmmmmmAAAAAAGmmmmAAAAAAAE0000wAAAAAE00U00AAAAAACk0000QAAAAAmmmmmgAAAAAAGmmmmigAAAAA00000AAAAAAA00000UAAAAAmmmmmEAAAAAA000w00AAAAAGmmmmmAAAAAAE00000QAAAAE0U000wAAAAAA00000wAAAAA000mmiAAAAAAmmmmmiAAAAAmimmmkQAAAAAGmmmmmAAAAAE00000QAAAAAA00000wmEwmAmmmmmmEwmEwAE0000w00000wmmmmmmimmmgAGmmmmmmmmmGEw00mmmmmmmgAGmmmmmmmmmGE0w00000000AA0000U000mmmA000000000wwAGmmmmmmmmmEU0GmmmmmmmmAAAAiAEACgAECAAgCEAAiAEAAA")) diff --git a/apps/ashadyclock/app.js b/apps/ashadyclock/app.js new file mode 100644 index 000000000..8c86ca8d2 --- /dev/null +++ b/apps/ashadyclock/app.js @@ -0,0 +1,107 @@ +var settings = Object.assign({ + // default values + showWidgets: false, + alternativeColor: false, +}, require('Storage').readJSON("ashadyclock.json", true) || {}); + +let drawTimeout; +// schedule a draw for the next minute +function queueDraw() { + if (drawTimeout) clearTimeout(drawTimeout); + drawTimeout = setTimeout(function() { + drawTimeout = undefined; + draw(); + }, 60000 - (Date.now() % 60000)); +} + +let palBottom; +if (settings.alternativeColor) { + palBottom = new Uint16Array(E.toArrayBuffer(E.toFlatString(new Uint16Array([ + g.toColor("#000"), + g.toColor("#000"), + g.toColor("#0FF"), + g.toColor("#0FF"), + g.toColor("#00F"), + g.toColor("#000"), + g.toColor("#00F"), + g.toColor("#000") + ]).buffer))); +} else { + palBottom = new Uint16Array(E.toArrayBuffer(E.toFlatString(new Uint16Array([ + g.toColor("#000"), + g.toColor("#000"), + g.toColor("#F00"), + g.toColor("#FF0"), + g.toColor("#00F"), + g.toColor("#000"), + g.toColor("#FF0"), + g.toColor("#000") + ]).buffer))); +} + +let palTop = new Uint16Array(E.toArrayBuffer(E.toFlatString(new Uint16Array([ + g.toColor("#FFF"), + g.toColor("#000"), + g.toColor("#FFF"), + g.toColor("#FFF"), + g.toColor("#00F"), + g.toColor("#000"), + g.toColor("#FFF"), + g.toColor("#000"), + ]).buffer))); + +let xOffset = (g.getWidth() - 176) / 2; +let yOffset = (g.getHeight() - 176) / 2; + +function drawTop(d0, d1) { + if (settings.showWidgets && g.getHeight()<=176) { + drawNumber(d1, 82 + xOffset, 24 + yOffset, palTop, {scale: 0.825}); + drawNumber(d0, 13 + xOffset, 24 + yOffset, palTop, {scale: 0.825}); + } else { + drawNumber(d1, 80, 0, palTop); + drawNumber(d0, -1, 0, palTop); + } +} + +function drawBottom(d0, d1) { + if (settings.showWidgets && g.getHeight()<=176) { + drawNumber(d1, 82 + xOffset, 92 + yOffset, palBottom, {scale: 0.825}); + drawNumber(d0, 13 + xOffset, 92 + yOffset, palBottom, {scale: 0.825}); + } else { + drawNumber(d1, 80, 75, palBottom); + drawNumber(d0, -1, 75, palBottom); + } +} + +function drawNumber(number, x, y, palette, options) { + let image = + { + width : 98, height : 100, bpp : 3, + transparent: 4, + buffer : require("Storage").read("ashadyclock." + number +".bin") + }; + image.palette = palette; + g.drawImage(image, x, y, options); +} + +function draw() { + let d = new Date(); + g.clearRect(0, settings.showWidgets ? 24 : 0, g.getWidth(),g.getHeight()); + + drawBottom(Math.floor(d.getMinutes()/10), d.getMinutes() % 10); + drawTop(Math.floor(d.getHours()/10), d.getHours() % 10); + + queueDraw(); +} + +g.clear(); +// draw immediately at first +draw(); + +// Show launcher when middle button pressed +Bangle.setUI("clock"); + +if(settings.showWidgets) { + Bangle.loadWidgets(); + Bangle.drawWidgets(); +} diff --git a/apps/ashadyclock/app.png b/apps/ashadyclock/app.png new file mode 100644 index 000000000..e01fd0746 Binary files /dev/null and b/apps/ashadyclock/app.png differ diff --git a/apps/ashadyclock/metadata.json b/apps/ashadyclock/metadata.json new file mode 100644 index 000000000..1b92ecabc --- /dev/null +++ b/apps/ashadyclock/metadata.json @@ -0,0 +1,27 @@ +{ "id": "ashadyclock", + "name": "A Shady Clock", + "shortName":"Shady Clk", + "icon": "app.png", + "version":"0.01", + "description": "A nice clock with drop shadow. Hours and minutes. Configure color and widgets in settings. Create any color combination with the existing images by changing only the app color values.", + "type": "clock", + "tags": "clock", + "screenshots": [{"url":"screenshot-1.png"},{"url":"screenshot.png"}], + "supports": ["BANGLEJS","BANGLEJS2"], + "storage": [ + {"name":"ashadyclock.app.js","url":"app.js"}, + {"name":"ashadyclock.img","url":"app-icon.js","evaluate":true}, + {"name":"ashadyclock.0.bin","url":"0.bin"}, + {"name":"ashadyclock.1.bin","url":"1.bin"}, + {"name":"ashadyclock.2.bin","url":"2.bin"}, + {"name":"ashadyclock.3.bin","url":"3.bin"}, + {"name":"ashadyclock.4.bin","url":"4.bin"}, + {"name":"ashadyclock.5.bin","url":"5.bin"}, + {"name":"ashadyclock.6.bin","url":"6.bin"}, + {"name":"ashadyclock.7.bin","url":"7.bin"}, + {"name":"ashadyclock.8.bin","url":"8.bin"}, + {"name":"ashadyclock.9.bin","url":"9.bin"}, + {"name":"ashadyclock.settings.js","url":"settings.js"} + ], + "data": [{"name":"ashadyclock.json"}] +} diff --git a/apps/ashadyclock/screenshot-1.png b/apps/ashadyclock/screenshot-1.png new file mode 100644 index 000000000..a0c7ea3be Binary files /dev/null and b/apps/ashadyclock/screenshot-1.png differ diff --git a/apps/ashadyclock/screenshot.png b/apps/ashadyclock/screenshot.png new file mode 100644 index 000000000..731055915 Binary files /dev/null and b/apps/ashadyclock/screenshot.png differ diff --git a/apps/ashadyclock/settings.js b/apps/ashadyclock/settings.js new file mode 100644 index 000000000..eef57e519 --- /dev/null +++ b/apps/ashadyclock/settings.js @@ -0,0 +1,32 @@ +(function(back) { + var FILE = "ashadyclock.json"; + // Load settings + var settings = Object.assign({ + showWidgets: false, + alternativeColor: false, + }, require('Storage').readJSON(FILE, true) || {}); + + function writeSettings() { + require('Storage').writeJSON(FILE, settings); + } + + // Show the menu + E.showMenu({ + "" : { "title" : "Shady Clck" }, + "< Back" : () => back(), + 'Show Widgets': { + value: !!settings.showWidgets, // !! converts undefined to false + onchange: v => { + settings.showWidgets = v; + writeSettings(); + } + }, + 'Blue Color': { + value: !!settings.alternativeColor, // !! converts undefined to false + onchange: v => { + settings.alternativeColor = v; + writeSettings(); + } + }, + }); +}) diff --git a/apps/delaylock/ChangeLog b/apps/delaylock/ChangeLog new file mode 100644 index 000000000..5560f00bc --- /dev/null +++ b/apps/delaylock/ChangeLog @@ -0,0 +1 @@ +0.01: New App! diff --git a/apps/delaylock/README.md b/apps/delaylock/README.md new file mode 100644 index 000000000..da2ef3cda --- /dev/null +++ b/apps/delaylock/README.md @@ -0,0 +1,23 @@ +# Delayed Locking + +Delay the locking of the touchscreen to 5 seconds after the backlight turns off. Giving you the chance to interact with the watch without having to press the hardware button again. + +## Usage + +Just install and the behavior is tweaked at boot time. + +## Features + +- respects the LCD Timeout and Brightness as configured in the settings app. + +## Requests + +Tag @thyttan in an issue to https://gitbub.com/espruino/BangleApps/issues to report problems or suggestions. + +## Creator + +thyttan + +## Acknowledgements + +Inspired by the conversation between Gordon Williams and user156427 linked here: https://forum.espruino.com/conversations/392219/ diff --git a/apps/delaylock/app.png b/apps/delaylock/app.png new file mode 100644 index 000000000..7bdce945d Binary files /dev/null and b/apps/delaylock/app.png differ diff --git a/apps/delaylock/boot.js b/apps/delaylock/boot.js new file mode 100644 index 000000000..87dcbf186 --- /dev/null +++ b/apps/delaylock/boot.js @@ -0,0 +1,21 @@ +{ + let backlightTimeout = Bangle.getOptions().backlightTimeout; + let brightness = require("Storage").readJSON("setting.json", true); + brightness = brightness?brightness.brightness:1; + + Bangle.setOptions({ + backlightTimeout: backlightTimeout, + lockTimeout: backlightTimeout+5000 + }); + + let turnLightsOn = (_,numOrObj)=>{ + if (!Bangle.isBacklightOn()) { + Bangle.setLCDPower(brightness); + if (typeof numOrObj !== "number") E.stopEventPropagation(); // Touches will not be passed on to other listeners, but swipes will. + } + }; + + setWatch(turnLightsOn, BTN1, { repeat: true, edge: 'rising' }); + Bangle.prependListener("swipe", turnLightsOn); + Bangle.prependListener("touch", turnLightsOn); +} diff --git a/apps/delaylock/metadata.json b/apps/delaylock/metadata.json new file mode 100644 index 000000000..dff4d9219 --- /dev/null +++ b/apps/delaylock/metadata.json @@ -0,0 +1,13 @@ +{ "id": "delaylock", + "name": "Delayed Locking", + "version":"0.01", + "description": "Delay the locking of the screen to 5 seconds after the backlight turns off.", + "icon": "app.png", + "tags": "settings, configuration, backlight, touchscreen, screen", + "type": "bootloader", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"delaylock.boot.js","url":"boot.js"} + ] +} diff --git a/apps/ffcniftyapp/ChangeLog b/apps/ffcniftyapp/ChangeLog new file mode 100644 index 000000000..30dcec467 --- /dev/null +++ b/apps/ffcniftyapp/ChangeLog @@ -0,0 +1,3 @@ +0.01: New Clock Nifty A ++ >> adding more information on the right side of the clock + + diff --git a/apps/ffcniftyapp/README.md b/apps/ffcniftyapp/README.md new file mode 100644 index 000000000..d6795840e --- /dev/null +++ b/apps/ffcniftyapp/README.md @@ -0,0 +1,13 @@ +# Nifty-A ++ Clock + +This is the clock: + + + +The week number (ISO8601) can be turned off in settings (default is `On`) +Weather and Steps can be also turned off in settings. + + + +Based on the # Nifty-A Clock by @alessandrococco + diff --git a/apps/ffcniftyapp/app-icon.js b/apps/ffcniftyapp/app-icon.js new file mode 100644 index 000000000..f0a2393b1 --- /dev/null +++ b/apps/ffcniftyapp/app-icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwwkEIf4A5gX/+AGEn//mIWLgP/C4gGCAAMgC5UvC4sDC4YICkIhBgMQiEBE4Uxn4XDj//iEAn/yA4ICBgUikEikYXBBAIXEn/xJYURAYMygERkQHBiYLBKYIXF+AVDC4czgUSmIXBCQgED+ZeBR4YXBLYICDC5CPGC4IAIC40zmaPDC4MSLQQXK+ayCR4QXCiRoEC44ECh4bCC4MTiTDBC6ZHOC5B3NLYcvC4kBgL5BAAUikT+BfIIrB/8ykf/eYQXBkUTI4cBW4YQCgQGDmAXDkJfEC46GBAoJKCR4geCAAMRAAZRDAoIODO4UBPRIAJR5QXWgKNCTApNDC5Mv/6/DAwR3GAAyHCC4anJIo3/+bvEa4Uia4oXHkEvC4cvIgUf+YXKHYIvEAgcPC5QSGC5UBSwYXJLYQXFkUhgABBC5Ef/4mBl4XEmETmIXKgaXBmYCBC4cTkMxiQXJS4IACL4p3MgESCwJHFR5oxCiB3FkERC5cSToQXFmUyiAZFR48Bn7zCAQMjkfykQkBN4n/XgKPBAAQgCUQIfBUwYXHFgIGCdI4XDmYADmIIEkAWJAH4A4A==")) \ No newline at end of file diff --git a/apps/ffcniftyapp/app.js b/apps/ffcniftyapp/app.js new file mode 100644 index 000000000..840dd72ff --- /dev/null +++ b/apps/ffcniftyapp/app.js @@ -0,0 +1,174 @@ +const w = require("weather"); +//const locale = require("locale"); + +// Weather icons from https://icons8.com/icon/set/weather/color +function getSun() { + return require("heatshrink").decompress(atob("kEggILIgOAAZkDAYPAgeBwPAgIFBBgPhw4TBp/yAYMcnADBnEcAYMwhgDBsEGgE/AYP8AYYLDCYgbDEYYrD8fHIwI7CIYZLDL54AHA==")); +} +function getPartSun() { + return require("heatshrink").decompress(atob("kcjwIVSgOAAgUwAYUGAYVgBoQHBkAIBocIDIX4CIcOAYMYg/wgECgODgE8oFAmEDxEYgYZBgQLBGYNAg/ggcYgANBAIIxBsPAG4MYsAIBoQ3ChAQCgI4BHYUEBgUADIIPBh///4GBv//8Cda")); +} +//function getPartRain() { +// return require("heatshrink").decompress(atob("kEggIHEmADJjEwsEAjkw8EAh0B4EAg35wEAgP+CYMDwv8AYMDBAP2g8HgH+g0DBYMMgPwAYX8gOMEwMG3kAg8OvgSBjg2BgcYGQIcBAY5CBg0Av//HAM///4MYgNBEIMOCoUMDoUAnBwGkEA")); +//} +function getCloud() { + return require("heatshrink").decompress(atob("kEggIfcj+AAYM/8ADBuFwAYPAmADCCAMBwEf8ADBhFwg4aBnEPAYMYjAVBhgDDDoQDHCYc4jwDB+EP///FYIDBMTgA==")); +} +function getSnow() { + return require("heatshrink").decompress(atob("kEggITQj/AAYM98ADBsEwAYPAjADCj+AgOAj/gAYMIuEHwEAjEPAYQVChk4AYQhCAYcYBYQTDnEPgEB+EH///IAQACE4IAB8EICIPghwDB4EeBYNAjgDBg8EAYQYCg4bCgZuFA==")); +} +function getRain() { + return require("heatshrink").decompress(atob("kEggIPMh+AAYM/8ADBuFwAYPgmADB4EbAYOAj/ggOAhnwg4aBnAeCjEcCIMMjADCDoQDHjAPCnAXCuEP///8EDAYJECAAXBwkAgPDhwDBwUMgEEhkggEOjFgFgMQLYQAOA==")); +} +function getStorm() { + return require("heatshrink").decompress(atob("kcjwIROgfwAYMB44ICsEwAYMYgYQCgAICoEHCwMYgFDwEHCYfgEAMA4AIBmAXCgUGFIVAwADBhEQFIQtCGwNggPgjAVBngCBv8Oj+AgfjwYpCGAIABn4kBgOBBAVwjBHBD4IdBgYNBGwUAkCdbA=")); +} +// err icon - https://icons8.com/icons/set/error +function getErr() { + return require("heatshrink").decompress(atob("kEggILIgOAAYsD4ADBg/gAYMGsADBhkwAYsYjADCjgDBmEMAYNxxwDBsOGAYPBwYDEgOBwOAgYDB4EDHYPAgwDBsADDhgDBFIcwjAHBjE4AYMcmADBhhNCKIcG/4AGOw4A==")); +} +//function getDummy() { +// return require("heatshrink").decompress(atob("gMBwMAwA")); +//} + + + + +/** +Choose weather icon to display based on condition. +Based on function from the Bangle weather app so it should handle all of the conditions +sent from gadget bridge. +*/ +function chooseIcon(condition) { + condition = condition.toLowerCase(); + if (condition.includes("thunderstorm") || + condition.includes("squalls") || + condition.includes("tornado")) return getStorm; + else if (condition.includes("freezing") || condition.includes("snow") || + condition.includes("sleet")) { + return getSnow; + } + else if (condition.includes("drizzle") || + condition.includes("shower") || + condition.includes("rain")) return getRain; + else if (condition.includes("clear")) return getSun; + else if (condition.includes("clouds")) return getCloud; + else if (condition.includes("few clouds") || + condition.includes("scattered clouds") || + condition.includes("mist") || + condition.includes("smoke") || + condition.includes("haze") || + condition.includes("sand") || + condition.includes("dust") || + condition.includes("fog") || + condition.includes("overcast") || + condition.includes("partly cloudy") || + condition.includes("ash")) { + return getPartSun; + } else return getErr; +} +/*function condenseWeather(condition) { + condition = condition.toLowerCase(); + if (condition.includes("thunderstorm") || + condition.includes("squalls") || + condition.includes("tornado")) return "storm"; + if (condition.includes("freezing") || condition.includes("snow") || + condition.includes("sleet")) { + return "snow"; + } + if (condition.includes("drizzle") || + condition.includes("shower") || + condition.includes("rain")) return "rain"; + if (condition.includes("clear")) return "clear"; + if (condition.includes("clouds")) return "clouds"; + if (condition.includes("few clouds") || + condition.includes("scattered clouds") || + condition.includes("mist") || + condition.includes("smoke") || + condition.includes("haze") || + condition.includes("sand") || + condition.includes("dust") || + condition.includes("fog") || + condition.includes("overcast") || + condition.includes("partly cloudy") || + condition.includes("ash")) { + return "scattered"; + } else { return "N/A"; } + return "N/A"; +} +*/ +// copied from: https://gist.github.com/IamSilviu/5899269#gistcomment-3035480 +function ISO8601_week_no(date) { + var tdt = new Date(date.valueOf()); + var dayn = (date.getDay() + 6) % 7; + tdt.setDate(tdt.getDate() - dayn + 3); + var firstThursday = tdt.valueOf(); + tdt.setMonth(0, 1); + if (tdt.getDay() !== 4) { + tdt.setMonth(0, 1 + ((4 - tdt.getDay()) + 7) % 7); + } + return 1 + Math.ceil((firstThursday - tdt) / 604800000); +} + +function format(value) { + return ("0" + value).substr(-2); +} + +const ClockFace = require("ClockFace"); +const clock = new ClockFace({ + init: function () { + const appRect = Bangle.appRect; + + this.viewport = { + width: appRect.w, + height: appRect.h + }; + + this.center = { + x: this.viewport.width / 2, + y: Math.round((this.viewport.height / 2) + appRect.y) + }; + + this.scale = g.getWidth() / this.viewport.width; + this.centerTimeScaleX = this.center.x + 32 * this.scale; + this.centerDatesScaleX = this.center.x + 40 * this.scale; + }, + draw: function (date) { + const hour = date.getHours() - (this.is12Hour && date.getHours() > 12 ? 12 : 0); + const month = date.getMonth() + 1; + // const monthName = require("date_utils").month(month, 1); + // const dayName = require("date_utils").dow(date.getDay(), 1); + let steps = Bangle.getHealthStatus("day").steps; + let curr = (w.get() === undefined ? "no data" : w.get()); // Get weather from weather app. + //let cWea =(curr === "no data" ? "no data" : curr.txt); + let cTemp= (curr === "no data" ? 273 : curr.temp); + // const temp = locale.temp(curr.temp - 273.15).match(/^(\D*\d*)(.*)$/); + let w_icon = chooseIcon(curr.txt === undefined ? "no data" : curr.txt ); + //let w_icon = chooseIcon(curr.txt); + + g.setFontAlign(1, 0).setFont("Vector", 90 * this.scale); + g.drawString(format(hour), this.centerTimeScaleX, this.center.y - 31 * this.scale); + g.drawString(format(date.getMinutes()), this.centerTimeScaleX, this.center.y + 46 * this.scale); + + g.fillRect(this.center.x + 30 * this.scale, this.center.y - 72 * this.scale, this.center.x + 32 * this.scale, this.center.y + 74 * this.scale); + + g.setFontAlign(-1, 0).setFont("Vector", 16 * this.scale); + g.drawString(format(date.getDate()), this.centerDatesScaleX, this.center.y - 62 * this.scale); //26 + g.drawString("." + format(month) + ".", this.centerDatesScaleX + 20, this.center.y - 62 * this.scale); //44 + g.drawString(date.getFullYear(date), this.centerDatesScaleX, this.center.y - 44 * this.scale); //62 + if (this.showWeekNum) + g.drawString("CW" + format(ISO8601_week_no(date)), this.centerDatesScaleX, this.center.y + -26 * this.scale); //15 + // print(w_icon()); + if (this.showWeather) { + g.drawImage(w_icon(), this.centerDatesScaleX, this.center.y - 8 * this.scale); + // g.drawString(condenseWeather(curr.txt), this.centerDatesScaleX, this.center.y + 24 * this.scale); + g.drawString((cTemp === undefined ? 273 : cTemp ) - 273 + "°C", this.centerDatesScaleX, this.center.y + 44 * this.scale); //48 + + } + if (this.showSteps) + g.drawString(steps, this.centerDatesScaleX, this.center.y + 66 * this.scale); + + }, + settingsFile: "ffcniftyapp.json" +}); +clock.start(); diff --git a/apps/ffcniftyapp/app.png b/apps/ffcniftyapp/app.png new file mode 100644 index 000000000..1cd8a49b7 Binary files /dev/null and b/apps/ffcniftyapp/app.png differ diff --git a/apps/ffcniftyapp/metadata.json b/apps/ffcniftyapp/metadata.json new file mode 100644 index 000000000..bbe8e7e69 --- /dev/null +++ b/apps/ffcniftyapp/metadata.json @@ -0,0 +1,20 @@ +{ + "id": "ffcniftyapp", + "name": "Nifty-A Clock ++", + "version": "0.01", + "description": "A nifty clock with time and date and more", + "dependencies": {"weather":"app"}, + "icon": "app.png", + "screenshots": [{"url":"screenshot_niftyapp.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS","BANGLEJS2"], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + {"name":"ffcniftyapp.app.js","url":"app.js"}, + {"name":"ffcniftyapp.img","url":"app-icon.js","evaluate":true}, + {"name":"ffcniftyapp.settings.js","url":"settings.js"} + ], + "data": [{"name":"ffcniftyapp.json"}] +} diff --git a/apps/ffcniftyapp/screenshot_niftyapp.png b/apps/ffcniftyapp/screenshot_niftyapp.png new file mode 100644 index 000000000..2428523d0 Binary files /dev/null and b/apps/ffcniftyapp/screenshot_niftyapp.png differ diff --git a/apps/ffcniftyapp/screenshot_settings_niftyapp.png b/apps/ffcniftyapp/screenshot_settings_niftyapp.png new file mode 100644 index 000000000..0bc9cc72c Binary files /dev/null and b/apps/ffcniftyapp/screenshot_settings_niftyapp.png differ diff --git a/apps/ffcniftyapp/settings.js b/apps/ffcniftyapp/settings.js new file mode 100644 index 000000000..a1f09e454 --- /dev/null +++ b/apps/ffcniftyapp/settings.js @@ -0,0 +1,35 @@ + +(function (back) { + var DEFAULTS = { + 'showWeekNum': false, + 'showWeather': false, + 'showSteps': false, + }; + let settings = require('Storage').readJSON("ffcniftyapp.json", 1) || DEFAULTS; + E.showMenu({ + + "": { "title": "Nifty-A Clock ++" }, + "< Back": () => back(), + /*LANG*/"Show Week Number": { + value: settings.showWeekNum, + onchange: v => { + settings.showWeekNum = v; + require("Storage").writeJSON("ffcniftyapp.json", settings); + } + }, + /*LANG*/"Show Weather": { + value: settings.showWeather, + onchange: w => { + settings.showWeather = w; + require("Storage").writeJSON("ffcniftyapp.json", settings); + } + }, + /*LANG*/"Show Steps": { + value: settings.showSteps, + onchange: z => { + settings.showSteps = z; + require("Storage").writeJSON("ffcniftyapp.json", settings); + } + } + }); +}) diff --git a/apps/reply/ChangeLog b/apps/reply/ChangeLog new file mode 100644 index 000000000..f3c7b0d2c --- /dev/null +++ b/apps/reply/ChangeLog @@ -0,0 +1 @@ +0.01: New Library! \ No newline at end of file diff --git a/apps/reply/README.md b/apps/reply/README.md new file mode 100644 index 000000000..dc874d183 --- /dev/null +++ b/apps/reply/README.md @@ -0,0 +1,23 @@ +# Canned Replies Library + +A library that handles replying to messages received from Gadgetbridge/Messages apps. + +## Replying to a message +The user can define a set of canned responses via the customise page after installing the app, or alternatively if they have a keyboard installed, they can type a response back. The requesting app will receive either an object containing the full reply for GadgetBridge, or a string with the response from the user, depending on how they wish to handle the response. + +## Integrating in your app +To use this in your app, simply call + +```js +require("reply").reply(/*options*/{...}).then(result => ...); +``` + +The ```options``` object can contain the following: + +- ```msg```: A message object containing a field ```id```, the ID to respond to. If this is included in options, the result of the promise will be an object as follows: ```{t: "notify", id: msg.id, n: "REPLY", msg: "USER REPLY"}```. If not included, the result of the promise will be an object, ```{msg: "USER REPLY"}``` +- ```shouldReply```: Whether or not the library should send the response over Bluetooth with ```Bluetooth.println(...```. Useful if the calling app wants to handle the response a different way. Default is true. +- ```title```: The title to show at the top of the menu. Defaults to ```"Reply with:"```. +- ```fileOverride```: An override file to read canned responses from, which is an array of objects each with a ```text``` property. Default is ```replies.json```. Useful for apps which might want to make use of custom canned responses. + +## Known Issues +Emojis are currently not supported. \ No newline at end of file diff --git a/apps/reply/app.png b/apps/reply/app.png new file mode 100644 index 000000000..bef8338cf Binary files /dev/null and b/apps/reply/app.png differ diff --git a/apps/reply/interface.html b/apps/reply/interface.html new file mode 100644 index 000000000..ddad4ef35 --- /dev/null +++ b/apps/reply/interface.html @@ -0,0 +1,122 @@ + + +
+ + + + + + + +Loading
+Syncing custom replies with your watch
+No custom replies
+Use the field above to add a custom reply
+