diff --git a/apps.json b/apps.json index 7898ba786..ebe193f3a 100644 --- a/apps.json +++ b/apps.json @@ -2,7 +2,7 @@ { "id": "fwupdate", "name": "Firmware Update", - "version": "0.02", + "version": "0.03", "description": "[BETA] Uploads new Espruino firmwares to Bangle.js 2. For now, please use the instructions under https://www.espruino.com/Bangle.js2#firmware-updates", "icon": "app.png", "type": "RAM", @@ -16,7 +16,7 @@ { "id": "boot", "name": "Bootloader", - "version": "0.39", + "version": "0.40", "description": "This is needed by Bangle.js to automatically load the clock, menu, widgets and settings", "icon": "bootloader.png", "type": "bootloader", @@ -77,7 +77,7 @@ { "id": "messages", "name": "Messages", - "version": "0.14", + "version": "0.17", "description": "App to display notifications from iOS and Gadgetbridge", "icon": "app.png", "type": "app", @@ -116,7 +116,7 @@ { "id": "ios", "name": "iOS Integration", - "version": "0.07", + "version": "0.08", "description": "Display notifications/music/etc from iOS devices", "icon": "app.png", "tags": "tool,system,ios,apple,messages,notifications", @@ -167,7 +167,7 @@ { "id": "setting", "name": "Settings", - "version": "0.38", + "version": "0.40", "description": "A menu for setting up Bangle.js", "icon": "settings.png", "tags": "tool,system", @@ -768,7 +768,7 @@ "id": "recorder", "name": "Recorder (BETA)", "shortName": "Recorder", - "version": "0.04", + "version": "0.06", "description": "Record GPS position, heart rate and more in the background, then download to your PC.", "icon": "app.png", "tags": "tool,outdoors,gps,widget", @@ -845,7 +845,7 @@ { "id": "weather", "name": "Weather", - "version": "0.13", + "version": "0.15", "description": "Show Gadgetbridge weather report", "icon": "icon.png", "screenshots": [{"url":"screenshot.png"}], @@ -936,7 +936,7 @@ "id": "widbatpc", "name": "Battery Level Widget (with percentage)", "shortName": "Battery Widget", - "version": "0.14", + "version": "0.16", "description": "Show the current battery level and charging status in the top right of the clock, with charge percentage", "icon": "widget.png", "type": "widget", @@ -971,7 +971,7 @@ { "id": "widbt", "name": "Bluetooth Widget", - "version": "0.07", + "version": "0.08", "description": "Show the current Bluetooth connection status in the top right of the clock", "icon": "widget.png", "type": "widget", @@ -1040,16 +1040,19 @@ "id": "bthrm", "name": "Bluetooth Heart Rate Monitor", "shortName": "BT HRM", - "version": "0.01", + "version": "0.02", "description": "Overrides Bangle.js's build in heart rate monitor with an external Bluetooth one.", "icon": "app.png", - "type": "boot", + "type": "app", "tags": "health,bluetooth", "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "storage": [ + {"name":"bthrm.app.js","url":"bthrm.js"}, + {"name":"bthrm.recorder.js","url":"recorder.js"}, {"name":"bthrm.boot.js","url":"boot.js"}, - {"name":"bthrm.img","url":"app-icon.js","evaluate":true} + {"name":"bthrm.img","url":"app-icon.js","evaluate":true}, + {"name":"bthrm.settings.js","url":"settings.js"} ] }, { @@ -1148,7 +1151,7 @@ { "id": "qrcode", "name": "Custom QR Code", - "version": "0.04", + "version": "0.05", "description": "Use this to upload a customised QR code to Bangle.js", "icon": "app.png", "tags": "qrcode", @@ -1324,7 +1327,7 @@ "icon": "gesture.png", "type": "app", "tags": "gesture,ai", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS", "BANGLEJS2"], "storage": [ {"name":"gesture.app.js","url":"gesture.js"}, {"name":".tfnames","url":"gesture-tfnames.js","evaluate":true}, @@ -1501,7 +1504,7 @@ { "id": "gpsinfo", "name": "GPS Info", - "version": "0.05", + "version": "0.08", "description": "An application that displays information about altitude, lat/lon, satellites and time", "icon": "gps-info.png", "type": "app", @@ -1590,7 +1593,7 @@ { "id": "widpedom", "name": "Pedometer widget", - "version": "0.20", + "version": "0.22", "description": "Daily pedometer widget", "icon": "widget.png", "type": "widget", @@ -1750,8 +1753,9 @@ "icon": "grocery.png", "type": "app", "tags": "tool,outdoors,shopping,list", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS", "BANGLEJS2"], "custom": "grocery.html", + "allow_emulator": true, "storage": [ {"name":"grocery.app.js","url":"app.js"}, {"name":"grocery.img","url":"grocery-icon.js","evaluate":true} @@ -2028,7 +2032,7 @@ "id": "chronowid", "name": "Chrono Widget", "shortName": "Chrono Widget", - "version": "0.04", + "version": "0.05", "description": "Chronometer (timer) which runs as widget.", "icon": "app.png", "tags": "tool,widget", @@ -2185,7 +2189,7 @@ "id": "calculator", "name": "Calculator", "shortName": "Calculator", - "version": "0.04", + "version": "0.05", "description": "Basic calculator reminiscent of MacOs's one. Handy for small calculus.", "icon": "calculator.png", "screenshots": [{"url":"screenshot_calculator.png"}], @@ -2430,7 +2434,7 @@ { "id": "calendar", "name": "Calendar", - "version": "0.04", + "version": "0.06", "description": "Simple calendar", "icon": "calendar.png", "screenshots": [{"url":"screenshot_calendar.png"}], @@ -2971,11 +2975,11 @@ { "id": "cprassist", "name": "CPR Assist", - "version": "0.01", + "version": "0.02", "description": "Provides assistance while performing a CPR", "icon": "cprassist-icon.png", "tags": "tool,firstaid", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", "allow_emulator": true, "screenshots": [{"url":"bangle1-CPR-assist-screenshot.png"}], @@ -3533,7 +3537,7 @@ "id": "mclockplus", "name": "Morph Clock+", "shortName": "Morph Clock+", - "version": "0.02", + "version": "0.03", "description": "Morphing Clock with more readable seconds and date and additional stopwatch", "icon": "mclockplus.png", "type": "clock", @@ -3987,11 +3991,12 @@ "icon": "app.png", "type": "clock", "tags": "clock", - "supports": ["BANGLEJS"], + "supports": ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", "allow_emulator": true, "storage": [ - {"name":"doztime.app.js","url":"app.js"}, + {"name":"doztime.app.js","url":"app-bangle1.js","supports":["BANGLEJS"]}, + {"name":"doztime.app.js","url":"app-bangle2.js","supports":["BANGLEJS2"]}, {"name":"doztime.img","url":"app-icon.js","evaluate":true} ] }, @@ -4065,7 +4070,7 @@ { "id": "hcclock", "name": "Hi-Contrast Clock", - "version": "0.02", + "version": "0.03", "description": "Hi-Contrast Clock : A simple yet very bold clock that aims to be readable in high luninosity environments. Uses big 10x5 pixel digits. Use BTN 1 to switch background and foreground colors.", "icon": "hcclock-icon.png", "type": "clock", @@ -4211,13 +4216,13 @@ "id": "pastel", "name": "Pastel Clock", "shortName": "Pastel", - "version": "0.09", - "description": "A Configurable clock with custom fonts and background. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times", + "version": "0.10", + "description": "A Configurable clock with custom fonts, background and weather display. Has a cyclic information line that includes, day, date, battery, sunrise and sunset times", "icon": "pastel.png", - "dependencies": {"mylocation":"app", "widpedom":"app"}, - "screenshots": [{"url":"screenshot_pastel.png"}], + "dependencies": {"mylocation":"app", "widpedom":"app","weather":"app"}, + "screenshots": [{"url":"screenshot_pastel.png"}, {"url":"weather_icons.png"}], "type": "clock", - "tags": "clock", + "tags": "clock, weather, tool", "supports": ["BANGLEJS","BANGLEJS2"], "readme": "README.md", "storage": [ @@ -4238,8 +4243,9 @@ { "id": "antonclk", "name": "Anton Clock", - "version": "0.03", - "description": "A simple clock using the bold Anton font.", + "version": "0.04", + "description": "A clock using the bold Anton font, optionally showing seconds and date in ISO-8601 format.", + "readme":"README.md", "icon": "app.png", "screenshots": [{"url":"screenshot.png"}], "type": "clock", @@ -4248,8 +4254,10 @@ "allow_emulator": true, "storage": [ {"name":"antonclk.app.js","url":"app.js"}, + {"name":"antonclk.settings.js","url":"settings.js"}, {"name":"antonclk.img","url":"app-icon.js","evaluate":true} - ] + ], + "data": [{"name":"antonclk.json"}] }, { "id": "waveclk", @@ -4383,7 +4391,7 @@ { "id": "gpstouch", "name": "GPS Touch", - "version": "0.01", + "version": "0.02", "description": "A touch based GPS watch, shows OS map reference", "icon": "gpstouch.png", "screenshots": [{"url":"screenshot4.png"},{"url":"screenshot2.png"},{"url":"screenshot3.png"},{"url":"screenshot1.png"}], @@ -4473,7 +4481,7 @@ "name": "A Battery Widget (with percentage)", "shortName":"A Battery Widget", "icon": "widget.png", - "version":"1.02", + "version":"1.03", "type": "widget", "supports": ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", @@ -4488,7 +4496,7 @@ "name": "LCARS Clock", "shortName":"LCARS", "icon": "lcars.png", - "version":"0.07", + "version":"0.09", "readme": "README.md", "supports": ["BANGLEJS2"], "description": "Library Computer Access Retrieval System (LCARS) clock.", @@ -4622,7 +4630,7 @@ "shortName":"93 Dub", "icon": "93dub.png", "screenshots": [{"url":"screenshot.png"}], - "version":"0.05", + "version":"0.06", "description": "Fan recreation of orviwan's 91 Dub app for the Pebble smartwatch. Uses assets from his 91-Dub-v2.0 repo", "tags": "clock", "type": "clock", @@ -4653,7 +4661,7 @@ "id": "sensible", "name": "SensiBLE", "shortName": "SensiBLE", - "version": "0.04", + "version": "0.05", "description": "Collect, display and advertise real-time sensor data.", "icon": "sensible.png", "screenshots": [ @@ -4698,6 +4706,8 @@ "tags": "tool,timer", "readme":"README.md", "supports":["BANGLEJS2"], + "screenshots": [{"url":"screenshot1.png"},{"url":"screenshot2.png"},{"url":"screenshot3.png"}], + "allow_emulator": true, "storage": [ {"name":"a_speech_timer.app.js","url":"app.js"}, {"name":"a_speech_timer.img","url":"app-icon.js","evaluate":true} @@ -4709,7 +4719,7 @@ "icon": "mylocation.png", "type": "app", "screenshots": [{"url":"screenshot_1.png"}], - "version":"0.01", + "version":"0.02", "description": "Sets and stores the lat and long of your preferred City or it can be set from the GPS. mylocation.json can be used by other apps that need your main location lat and lon. See README", "readme": "README.md", "tags": "tool,utility", @@ -4726,7 +4736,7 @@ "id": "pebble", "name": "Pebble Clock", "shortName": "Pebble", - "version": "0.06", + "version": "0.07", "description": "A pebble style clock to keep the rebellion going", "dependencies": {"widpedom":"app"}, "readme": "README.md", @@ -4734,7 +4744,7 @@ "screenshots": [{"url":"pebble_screenshot.png"}], "type": "clock", "tags": "clock", - "supports": ["BANGLEJS2"], + "supports": ["BANGLEJS", "BANGLEJS2"], "storage": [ {"name":"pebble.app.js","url":"pebble.app.js"}, {"name":"pebble.settings.js","url":"pebble.settings.js"}, @@ -4768,7 +4778,7 @@ "screenshots": [{"url":"screenshot_widbata_1.png"}], "version":"0.01", "type": "widget", - "supports": ["BANGLEJS2"], + "supports": ["BANGLEJS", "BANGLEJS2"], "readme": "README.md", "description": "Shows the current battery level status in the top right using the clocks colour theme", "tags": "widget,battery", @@ -4779,7 +4789,7 @@ { "id": "weatherClock", "name": "Weather Clock", - "version": "0.04", + "version": "0.05", "description": "A clock which displays current weather conditions (requires Gadgetbridge and Weather apps).", "icon": "app.png", "screenshots": [{"url":"screens/screen1.png"}], @@ -4839,6 +4849,25 @@ {"name": "flow.img", "url": "app-icon.js","evaluate": true } ] }, + { "id": "tinydraw", + "name": "TinyDraw", + "shortName":"TinyDraw", + "version":"0.01", + "type": "app", + "description": "Draw stuff in your wrist", + "icon": "app.png", + "allow_emulator": true, + "tags": "tools, keyboard, text, scribble", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"tinydraw.app.js","url":"app.js"}, + {"name":"tinydraw.img","url":"app-icon.js","evaluate":true} + ], + "screenshots":[ + { "url":"screenshot.png" } + ] + }, { "id": "scribble", "name": "Scribble", "shortName":"Scribble", @@ -4862,7 +4891,7 @@ "id": "ptlaunch", "name": "Pattern Launcher", "shortName": "Pattern Launcher", - "version": "0.11", + "version": "0.13", "description": "Directly launch apps from the clock screen with custom patterns.", "icon": "app.png", "screenshots": [{"url":"manage_patterns_light.png"}], @@ -4876,11 +4905,25 @@ ], "data": [{"name":"ptlaunch.patterns.json"}] }, + { "id": "slimehunt", + "name": "Slime Hunt", + "shortName":"SlimeHunt", + "icon": "app.png", + "version":"0.02", + "description": "Fight against slimes in turn based combat, try to get the highscore!", + "tags": "rpg,slime", + "supports" : ["BANGLEJS"], + "readme": "README.md", + "storage": [ + {"name":"slimehunt.app.js","url":"app.js"}, + {"name":"slimehunt.img","url":"app-icon.js","evaluate":true} + ] + }, { "id": "rebble", "name": "Rebble Clock", "shortName": "Rebble", - "version": "0.03", + "version": "0.04", "description": "A Pebble style clock, with configurable background, three sidebars including steps, day, date, sunrise, sunset, long live the rebellion", "readme": "README.md", "icon": "rebble.png", @@ -4932,10 +4975,12 @@ "id":"awairmonitor", "name":"Awair Monitor", "icon": "app.png", + "screenshots": [{"url":"screenshot.png"}], "allow_emulator": true, - "version":"0.01", + "version":"0.03", "description": "Displays the level of CO2, VOC, PM 2.5, Humidity and Temperature, from your Awair device.", - "tags": "tool,health", + "type": "clock", + "tags": "clock,tool,health", "readme":"README.md", "supports":["BANGLEJS2"], "storage": [ @@ -4946,7 +4991,7 @@ { "id": "pooqround", "name": "pooq Round watch face", "shortName":"pooq Round", - "version":"0.01", + "version":"0.02", "description": "A 24 hour analogue watchface with high legibility and a novel style.", "icon": "app.png", "type": "clock", @@ -4964,8 +5009,8 @@ }, { "id": "coretemp", - "name": "Core Temp Display", - "version": "0.01", + "name": "CoreTemp", + "version": "0.02", "description": "Display CoreTemp device sensor data", "icon": "coretemp.png", "type": "app", @@ -4973,10 +5018,14 @@ "readme": "README.md", "supports": ["BANGLEJS","BANGLEJS2"], "storage": [ - {"name":"coretemp.boot.js","url":"boot.js"}, + {"name":"coretemp.wid.js","url":"widget.js"}, {"name":"coretemp.app.js","url":"coretemp.js"}, - {"name":"coretemp.img","url":"coretemp-icon.js","evaluate":true} - ] + {"name":"coretemp.settings.js","url":"settings.js"}, + {"name":"coretemp.img","url":"coretemp-icon.js","evaluate":true}, + {"name":"coretemp.boot.js","url":"boot.js"} + ], + "data": [{"name":"coretemp.json","url":"app-settings.json"}], + "screenshots": [{"url":"screenshot.png"}] }, { "id": "showimg", @@ -5030,9 +5079,10 @@ { "id": "circlesclock", "name": "Circles clock", "shortName":"Circles clock", - "version":"0.02", + "version":"0.03", "description": "A clock with circles for different data at the bottom in a probably familiar style", "icon": "app.png", + "screenshots": [{"url":"screenshot.png"}], "dependencies": {"widpedom":"app"}, "type": "clock", "tags": "clock", @@ -5048,6 +5098,22 @@ {"name":"circlesclock.json"} ] }, + { "id": "contourclock", + "name": "Contour Clock", + "shortName" : "Contour Clock", + "version":"0.01", + "icon": "app.png", + "description": "A Minimalist clockface with large Digits. Looks best with the dark theme", + "screenshots" : [{"url":"screenshot.png"}], + "tags": "clock", + "allow_emulator":true, + "supports" : ["BANGLEJS2"], + "type": "clock", + "storage": [ + {"name":"contourclock.app.js","url":"app.js"}, + {"name":"contourclock.img","url":"app-icon.js","evaluate":true} + ] + }, { "id": "ltherm", "name": "Localized Thermometer", @@ -5063,5 +5129,342 @@ {"name":"ltherm.app.js","url":"app.js"}, {"name":"ltherm.img","url":"icon.js","evaluate":true} ] + }, + { + "id": "presentor", + "name": "Presentor", + "version": "3.0", + "description": "Use your Bangle to present!", + "icon": "app.png", + "type": "app", + "tags": "tool,bluetooth", + "interface": "interface.html", + "readme":"README.md", + "supports": ["BANGLEJS", "BANGLEJS2"], + "allow_emulator": true, + "storage": [ + {"name":"presentor.app.js","url":"app.js"}, + {"name":"presentor.img","url":"app-icon.js","evaluate":true}, + {"name":"presentor.json","url":"settings.json"} + ] + }, + { + "id": "slash", + "name": "Slash Watch", + "shortName":"Slash", + "icon": "slash.png", + "screenshots": [{"url":"screenshot.png"}], + "version":"0.01", + "description": "Slash Watch based on Pebble watch face by Nikki.", + "tags": "clock", + "type": "clock", + "supports":["BANGLEJS2"], + "readme": "README.md", + "allow_emulator": true, + "storage": [ + {"name":"slash.app.js","url":"app.js"}, + {"name":"slash.img","url":"app-icon.js","evaluate":true} + ] + }, + { + "id": "promenu", + "name": "Pro Menu", + "version": "0.02", + "description": "Replace the built in menu function. Supports Bangle.js 1 and Bangle.js 2.", + "icon": "icon.png", + "type": "boot", + "tags": "system", + "supports": ["BANGLEJS","BANGLEJS2"], + "screenshots": [{"url":"pro-menu-screenshot.png"}], + "storage": [ + {"name":"promenu.boot.js","url":"boot.js","supports": ["BANGLEJS"]}, + {"name":"promenu.boot.js","url":"bootb2.js","supports": ["BANGLEJS2"]}, + {"name":"promenu.img","url":"promenuIcon.js","evaluate":true} + ] + }, + { + "id": "touchtimer", + "name": "Touch Timer", + "shortName": "Touch Timer", + "version": "0.02", + "description": "Quickly and easily create a timer with touch-only input. The time can be easily set with a number pad.", + "icon": "app.png", + "tags": "tools", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "screenshots": [{"url":"0_light_timer_edit.png"},{"url":"1_light_timer_ready.png"},{"url":"2_light_timer_running.png"},{"url":"3_light_timer_finished.png"}], + "storage": [ + { "name": "touchtimer.app.js", "url": "app.js" }, + { "name":"touchtimer.settings.js", "url":"settings.js"}, + { "name": "touchtimer.img", "url": "app-icon.js", "evaluate": true } + ], + "data": [{"name":"touchtimer.data.json"}] + }, + { + "id": "teatimer", + "name": "Tea Timer", + "version": "1.00", + "description": "A simple timer. You can easyly set up the time.", + "icon": "teatimer.png", + "type": "app", + "tags": "tool", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"teatimer.app.js","url":"app.js"}, + {"name":"teatimer.img","url":"app-icon.js","evaluate":true} + ], + "screenshots": [ + {"url":"TeatimerStart.jpg"}, + {"url":"TeatimerHelp.jpg"}, + {"url":"TeatimerRun.jpg"}, + {"url":"TeatimerUp.jpg"} + ] + }, + { + "id": "swp2clk", + "name": "Swipe back to the Clock", + "shortName": "Swipe to Clock", + "version": "0.01", + "description": "Let's you swipe from left to right on any app to return back to the clock face. Please configure in the settings app after installing to activate, since its disabled by default.", + "icon": "app.png", + "type": "boot", + "tags": "tools", + "supports": ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + { "name": "swp2clk.boot.js", "url": "boot.js" }, + {"name":"swp2clk.settings.js","url":"settings.js"} + ], + "data": [{"name":"swp2clk.data.json"}] + }, + { + "id":"colorwheel", + "name":"Color Wheel", + "tags":"app,tool", + "version":"0.01", + "description":"a tappable wheel of good-looking colors", + "readme":"README.md", + "supports":["BANGLEJS2"], + "allow_emulator":true, + "icon":"colorwheel.png", + "storage": [ + {"name":"colorwheel.app.js","url":"app.js"}, + {"name":"colorwheel.img","url":"app-icon.js","evaluate":true} + ] + }, + { "id": "minimal_clock", + "name": "Minimal Analog Clock", + "shortName":"Minimal Clock", + "version":"0.03", + "description": "a minimal analog clock - just with some hands and no clock face", + "icon": "app-icon.png", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "allow_emulator": true, + "screenshots": [{"url":"app-screenshot.png"}], + "readme": "README.md", + "storage": [ + {"name":"minimal_clock.app.js","url":"app.js"}, + {"name":"minimal_clock.img","url":"app-icon.js","evaluate":true} + ] + }, + { "id": "simple_clock", + "name": "Simple Analog Clock", + "shortName":"Simple Clock", + "version":"0.02", + "description": "a simple, yet stylish, analog clock", + "icon": "app-icon.png", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "allow_emulator": true, + "screenshots": [{"url":"app-screenshot.png"}], + "readme": "README.md", + "storage": [ + {"name":"simple_clock.app.js","url":"app.js"}, + {"name":"simple_clock.img","url":"app-icon.js","evaluate":true} + ] + }, + { "id": "colorful_clock", + "name": "Colorful Analog Clock", + "shortName":"Colorful Clock", + "version":"0.02", + "description": "a colorful analog clock", + "icon": "app-icon.png", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "allow_emulator": true, + "screenshots": [{"url":"app-screenshot.png"}], + "readme": "README.md", + "storage": [ + {"name":"colorful_clock.app.js","url":"app.js"}, + {"name":"colorful_clock.img","url":"app-icon.js","evaluate":true} + ] + }, + { "id": "themesetter", + "name": "Theme Setter", + "shortName":"Theme Setter", + "version":"0.04", + "description": "a comfortable way to configure theme colors", + "icon": "app-icon.png", + "type": "app", + "tags": "tool", + "supports" : ["BANGLEJS2"], + "allow_emulator": true, + "screenshots": [{"url":"app-screenshot.png"}], + "readme": "README.md", + "storage": [ + {"name":"themesetter.app.js","url":"app.js"}, + {"name":"themesetter.img","url":"app-icon.js","evaluate":true} + ] + }, + { + "id": "widviztime", + "name": "Widget Autohide Widget", + "shortName": "Viz Time Widget", + "version": "0.01", + "description": "The widgets will be shown for four seconds after the device is unlocked.", + "icon": "eye.png", + "type": "widget", + "tags": "widget", + "readme":"README.md", + "supports": ["BANGLEJS","BANGLEJS2"], + "storage": [ + {"name":"widviztime.wid.js","url":"widget.js"} + ] + }, + { + "id": "supf", + "name": "Simple Clock with Date", + "shortName": "supf Clock", + "version": "0.01", + "description": "Simple Clock with seconds and date in custom language. Install 'Languages' to get localized names.", + "icon": "icon.png", + "screenshots": [{"url":"screenshot_supf.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "allow_emulator": true, + "readme": "README.md", + "storage": [ + {"name":"supf.app.js","url":"app.js"}, + {"name":"supf.img","url":"icon.js","evaluate":true} + ] + }, + { "id": "andark", + "name": "Analog Dark", + "shortName":"AnDark", + "version":"0.04", + "description": "analog clock face without disturbing widgets", + "icon": "andark_icon.png", + "type": "clock", + "tags": "clock", + "supports" : ["BANGLEJS2"], + "readme": "README.md", + "storage": [ + {"name":"andark.app.js","url":"app.js"}, + {"name":"andark.img","url":"app_icon.js","evaluate":true} + ] + }, + { + "id": "diract", + "name": "DirAct", + "shortName": "DirAct", + "version": "0.01", + "description": "Proximity interaction detection.", + "icon": "diract.png", + "type": "app", + "tags": "tool,sensors", + "supports" : [ "BANGLEJS2" ], + "allow_emulator": false, + "readme": "README.md", + "storage": [ + { "name": "diract.app.js", "url": "diract.js" }, + { "name": "diract.img", "url": "diract-icon.js", "evaluate": true } + ] + }, + { + "id": "sonicclk", + "name": "Sonic Clock", + "version": "1.01", + "description": "A classic sonic clock featuring run, stop and wait animations.", + "icon": "app.png", + "screenshots": [{"url":"screenshot.png"}], + "type": "clock", + "tags": "clock", + "supports": ["BANGLEJS2"], + "allow_emulator": true, + "readme": "README.md", + "storage": [ + {"name":"sonicclk.app.js","url":"app.js"}, + {"name":"sonicclk.img","url":"app-icon.js","evaluate":true} + ] + }, + { + "id": "touchmenu", + "name": "TouchMenu", + "version": "0.01", + "description": "Redesigned menu that uses the full touchscreen on the Bangle.js 2", + "screenshots": [{"url":"touchmenu.gif"}], + "icon": "touchmenu.png", + "type": "bootloader", + "tags": "tool", + "supports": ["BANGLEJS2"], + "storage": [ + {"name":"touchmenu.boot.js","url":"touchmenu.boot.js"} + ] + }, + { + "id": "puzzle15", + "name": "15 puzzle", + "version": "0.05", + "description": "A 15 puzzle game with drag gesture interface", + "readme":"README.md", + "icon": "puzzle15.app.png", + "screenshots": [{"url":"screenshot.png"}], + "type": "app", + "tags": "game", + "supports": ["BANGLEJS2"], + "allow_emulator": true, + "storage": [ + {"name":"puzzle15.app.js","url":"puzzle15.app.js"}, + {"name":"puzzle15.settings.js","url":"puzzle15.settings.js"}, + {"name":"puzzle15.img","url":"puzzle15.app-icon.js","evaluate":true} + ], + "data": [{"name":"puzzle15.json"}] + }, + { + "id": "flipper", + "name": "flipper", + "version": "0.01", + "description": "Switch between dark and light theme and vice versa, combine with pattern launcher and swipe to flip.", + "readme":"README.md", + "screenshots": [{"url":"flipper.png"}], + "icon": "flipper.png", + "type": "app", + "tags": "game", + "supports": ["BANGLEJS2"], + "allow_emulator": true, + "storage": [ + {"name":"flipper.app.js","url":"flipper.app.js"}, + {"name":"flipper.img","url":"flipper.icon.js","evaluate":true} + ] + }, + { "id": "ruuviwatch", + "name": "Ruuvi Watch", + "shortName":"Ruuvi Watch", + "icon": "ruuviwatch.png", + "version":"1.01", + "description": "Keep an eye on RuuviTag devices (https://ruuvi.com). Only shows RuuviTags using the v5 format.", + "readme":"README.md", + "tags": "bluetooth", + "supports": ["BANGLEJS"], + "storage": [ + {"name":"ruuviwatch.app.js","url":"ruuviwatch.app.js"}, + {"name":"ruuviwatch.img","url":"ruuviwatch.app-icon.js","evaluate":true} + ] } ] diff --git a/apps/93dub/ChangeLog b/apps/93dub/ChangeLog index c1b2588bb..1c18ca59b 100644 --- a/apps/93dub/ChangeLog +++ b/apps/93dub/ChangeLog @@ -3,3 +3,4 @@ 0.03: Code style cleanup 0.04: Set 00:00 to 12:00 for 12 hour time 0.05: Display time, even on Thursday +0.06: Fix light theme issue, where widgets would end up on a light strip diff --git a/apps/93dub/app.js b/apps/93dub/app.js index 1b0f69a94..f970eec5d 100644 --- a/apps/93dub/app.js +++ b/apps/93dub/app.js @@ -122,7 +122,13 @@ function draw(){ queueDraw(); } - +/** + * This watch is mostly dark, it does not make sense to respect the + * light theme as you end up with a white strip at the top for the + * widgets and black watch. So set the colours to the dark theme. + * + */ +g.setTheme({bg:"#000",fg:"#fff",dark:true}).clear(); draw(); //the following section is also from waveclk diff --git a/apps/andark/ChangeLog b/apps/andark/ChangeLog new file mode 100644 index 000000000..341868930 --- /dev/null +++ b/apps/andark/ChangeLog @@ -0,0 +1,4 @@ +0.01: Release +0.02: Rename app +0.03: Add type "clock" +0.04: changed update cylce, when locked diff --git a/apps/andark/README.md b/apps/andark/README.md new file mode 100644 index 000000000..3770c1017 --- /dev/null +++ b/apps/andark/README.md @@ -0,0 +1,10 @@ +# Analog Clock + +## Features + +* second hand +* date +* battery percantage +* no widgets + + diff --git a/apps/andark/andark_icon.png b/apps/andark/andark_icon.png new file mode 100644 index 000000000..cded02071 Binary files /dev/null and b/apps/andark/andark_icon.png differ diff --git a/apps/andark/andark_screen.png b/apps/andark/andark_screen.png new file mode 100644 index 000000000..2ac54c1cd Binary files /dev/null and b/apps/andark/andark_screen.png differ diff --git a/apps/andark/app.js b/apps/andark/app.js new file mode 100644 index 000000000..efa00ce6f --- /dev/null +++ b/apps/andark/app.js @@ -0,0 +1,125 @@ +const c={"x":g.getWidth()/2,"y":g.getHeight()/2}; +let zahlpos=[]; +let unlock = false; + +function zeiger(len,dia,tim){ + const x =c.x+ Math.cos(tim)*len/2, + y =c.y + Math.sin(tim)*len/2, + d={"d":3,"x":dia/2*Math.cos(tim+Math.PI/2),"y":dia/2*Math.sin(tim+Math.PI/2)}, + pol=[c.x-d.x,c.y-d.y,c.x+d.x,c.y+d.y,x+d.x,y+d.y,x-d.x,y-d.y]; + return pol; + +} + +function draw(){ + const d=new Date(); + let m=d.getMinutes(), h=d.getHours(), s=d.getSeconds(); + //draw black rectangle in the middle to clear screen from scale and hands + g.setColor(0,0,0); + g.fillRect(10,10,2*c.x-10,2*c.x-10); + g.setColor(1,1,1); + + if(h>12){ + h=h-12; + } + //calculates the position of the minute, second and hour hand + h=2*Math.PI/12*(h+m/60)-Math.PI/2; + //more accurate + //m=2*Math.PI/60*(m+s/60)-Math.PI/2; + m=2*Math.PI/60*(m)-Math.PI/2; + + s=2*Math.PI/60*s-Math.PI/2; + g.setFontAlign(0,0); + g.setFont("Vector",10); + let dateStr = " "+require("locale").date(d)+" "; + g.drawString(dateStr, c.x, c.y+20, true); + // g.drawString(d.getDate(),1.4*c.x,c.y,true); + g.drawString(Math.round(E.getBattery()/5)*5+"%",c.x,c.y+40,true); + drawlet(); + //g.setColor(1,0,0); + const hz = zeiger(100,5,h); + g.fillPoly(hz,true); + // g.setColor(1,1,1); + const minz = zeiger(150,5,m); + g.fillPoly(minz,true); + if (unlock){ + const sekz = zeiger(150,2,s); + g.fillPoly(sekz,true); + } + g.fillCircle(c.x,c.y,4); + + + +} +//draws the scale once the app is startet +function drawScale(){ + for(let i=-14;i<47;i++){ + const win=i*2*Math.PI/60; + let d=2; + if(i%5==0){d=5;} + g.fillPoly(zeiger(300,d,win),true); + g.setColor(0,0,0); + g.fillRect(10,10,2*c.x-10,2*c.x-10); + g.setColor(1,1,1); + } +} + +//draws the numbers on the screen + +function drawlet(){ + g.setFont("Vector",20); + for(let i = 0;i<12;i++){ + g.drawString(zahlpos[i][0],zahlpos[i][1],zahlpos[i][2]); + } +} +//calcultes the Position of the numbers when app starts and saves them in an array +function setlet(){ + let sk=1; + for(let i=-10;i<50;i+=5){ + let win=i*2*Math.PI/60; + let xsk =c.x+2+Math.cos(win)*(c.x-10), + ysk =c.y+2+Math.sin(win)*(c.x-10); + if(sk==3){xsk-=10;} + if(sk==6){ysk-=10;} + if(sk==9){xsk+=10;} + if(sk==12){ysk+=10;} + if(sk==10){xsk+=3;} + zahlpos.push([sk,xsk,ysk]); + sk+=1; + } +} +setlet(); +// Clear the screen once, at startup +g.setBgColor(0,0,0); +g.clear(); +drawScale(); +draw(); + +let secondInterval= setInterval(draw, 1000); +// Stop updates when LCD is off, restart when on + +Bangle.on('lcdPower',on=>{ + if (secondInterval) clearInterval(secondInterval); + secondInterval = undefined; + if (on) { + secondInterval = setInterval(draw, 1000); + draw(); // draw immediately + }else{ + } +}); +Bangle.on('lock',on=>{ + if (secondInterval) clearInterval(secondInterval); + secondInterval = undefined; + if (!on) { + secondInterval = setInterval(draw, 1000); + unlock = true; + draw(); // draw immediately + }else{ + secondInterval = setInterval(draw, 60000); + unlock = false; + draw(); + } + }); + +// Show launcher when middle button pressed +Bangle.setUI("clock"); diff --git a/apps/andark/app_icon.js b/apps/andark/app_icon.js new file mode 100644 index 000000000..b213fe5c8 --- /dev/null +++ b/apps/andark/app_icon.js @@ -0,0 +1 @@ +require("heatshrink").decompress(atob("mEwgIEBoUAiAKCgUCBQUEColEAYUQhAmKCwgeCAAcCgEDjwEBkEAg8TBocNgYFDh8GAYMDxkPjEA8EAwkHJgIcBAoPfAoYWCBYYFIgfvAoX4FYRJEAp9gAomYNAOAArPwAogAC4AFiRoIFJLgIFJuADCg//Q4U//4FDj4FEAAV4Aoi0CSxBsCA==")) \ No newline at end of file diff --git a/apps/antonclk/ChangeLog b/apps/antonclk/ChangeLog index f88276a90..668047d7a 100644 --- a/apps/antonclk/ChangeLog +++ b/apps/antonclk/ChangeLog @@ -1,3 +1,4 @@ 0.01: New App! 0.02: Load widgets after setUI so widclk knows when to hide 0.03: Clock now shows day of week under date. +0.04: Clock can optionally show seconds, date optionally in ISO-8601 format, weekdays and uppercase configurable, too. diff --git a/apps/antonclk/README.md b/apps/antonclk/README.md new file mode 100644 index 000000000..41d3e4559 --- /dev/null +++ b/apps/antonclk/README.md @@ -0,0 +1,77 @@ +# Anton Clock - Large font digital watch with seconds and date + +Anton clock uses the "Anton" bold font to show the time in a clear, easily readable manner. On the Bangle.js 2, the time can be read easily even if the screen is locked and unlit. + +## Features + +The basic time representation only shows hours and minutes of the current time. However, Anton clock can show additional information: + +* Seconds can be shown, either always or only if the screen is unlocked. +* To help easy recognition, the seconds can be coloured in blue on the Bangle.js 2. +* Date can be shown in three different formats: + * ISO-8601: 2021-12-19 + * short local format: 19/12/2021, 19.12.2021 + * long local format: DEC 19 2021 +* Weekday can be shown (on seconds screen only instead of year) + +## Usage + +Install Anton clock through the Bangle.js app loader. +Configure it through the default Bangle.js configuration mechanism +(Settings app, "Apps" menu, "Anton clock" submenu). +If you like it, make it your default watch face +(Settings app, "System" menu, "Clock" submenu, select "Anton clock"). + +## Configuration + +Anton clock is configured by the standard settings mechanism of Bangle.js's operating system: +Open the "Settings" app, then the "Apps" submenu and below it the "Anton clock" menu. +You configure Anton clock through several "on/off" switches in two menus. + +### The main menu + +The main menu contains several settings covering Anton clock in general. + +* **Seconds...** - Opens the submenu for configuring the presentation of the current time's seconds. +* **Date** - Format of the date representation. Possible values are + * **Long** - "Long" date format in the current locale. Usually with the month as name, not number. + * **Short** - "Short" date format in the current locale. Usually with the month as number. + * **ISO8601** - Show the date in ISO-8601 format (YYYY-MM-DD), irrespective of the current locale. +* **Show Weekday** - Weekday is shown in the time presentation without seconds. +Weekday name depends on the current locale. +If seconds are shown, the weekday is never shown as there is not enough space on the watch face. +* **Uppercase** - Weekday name and month name in the long format are converted to upper case letters. +This can improve readability. +* **Vector font** - Use the built-in vector font for dates and weekday. +This can improve readability. +Otherwise, a scaled version of the built-in 6x8 pixels font is used. + +### The "Seconds" submenu + +The "Seconds" submenu configures how (and if) seconds are shown on the "Anton" watch face. + +* **Show** - Configure when the seconds should be shown at all: + * **Never** - Seconds are never shown. +In this case, hour and minute are a bit more centered on the screen and the clock will always only update every minute. +This saves battery power. + * **Unlocked** - Seconds are shown if the display is unlocked. +On locked displays, only hour, minutes, date and optionally the weekday are shown. +_This option is highly recommended on the Bangle.js 2!_ + * **Always** - Seconds are _always_ shown, irrespective of the display's unlock state. +_Enabling this option increases power consumption as the watch face will update once per second instead of once per minute._ +* **With ":"** - If enabled, a colon ":" is prepended to the seconds. +This resembles the usual time representation "hh:mm:ss", even though the seconds are printed on a separate line. +* **Color** - If enabled, seconds are shown in blue instead of black. +If the date is shown on the seconds screen, it is colored read instead of black. +This make the visual orientation much easier on the watch face. +* **Date** - It is possible to show the date together with the seconds: + * **No** - Date is _not_ shown in the seconds screen. +In this case, the seconds are centered below hour and minute. + * **Year** - Date is shown with day, month, and year. If "Date" in the main settings is configured to _ISO8601_, this is used here, too. Otherwise, the short local format is used. + * **Weekday** - Date is shown with day, month, and weekday. + +The date is coloured in red if the "Coloured" option is chosen. + +## Compatibility + +Anton clock makes use of core Bangle.js 2 features (coloured display, display lock state). It also runs on the Bangle.js 1 but these features are not available there due to hardware restrictions. diff --git a/apps/antonclk/app.js b/apps/antonclk/app.js index 7912dfc0f..1f3e49792 100644 --- a/apps/antonclk/app.js +++ b/apps/antonclk/app.js @@ -1,61 +1,203 @@ +// Clock with large digits using the "Anton" bold font + +var SETTINGSFILE = "antonclk.json"; + Graphics.prototype.setFontAnton = function(scale) { -// Actual height 69 (68 - 0) - g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAA/gAAAAAAAAAAP/gAAAAAAAAAH//gAAAAAAAAB///gAAAAAAAAf///gAAAAAAAP////gAAAAAAD/////gAAAAAA//////gAAAAAP//////gAAAAH///////gAAAB////////gAAAf////////gAAP/////////gAD//////////AA//////////gAA/////////4AAA////////+AAAA////////gAAAA///////wAAAAA//////8AAAAAA//////AAAAAAA/////gAAAAAAA////4AAAAAAAA///+AAAAAAAAA///gAAAAAAAAA//wAAAAAAAAAA/8AAAAAAAAAAA/AAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////AAAAAB///////8AAAAH////////AAAAf////////wAAA/////////4AAB/////////8AAD/////////+AAH//////////AAP//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wA//8AAAAAB//4A//wAAAAAAf/4A//gAAAAAAP/4A//gAAAAAAP/4A//gAAAAAAP/4A//wAAAAAAf/4A///////////4Af//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH//////////AAD/////////+AAB/////////8AAA/////////4AAAP////////gAAAD///////+AAAAAf//////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAP/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/AAAAAAAAAAA//AAAAAAAAAAA/+AAAAAAAAAAB/8AAAAAAAAAAD//////////gAH//////////gAP//////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/4AAAAB/gAAD//4AAAAf/gAAP//4AAAB//gAA///4AAAH//gAB///4AAAf//gAD///4AAA///gAH///4AAD///gAP///4AAH///gAP///4AAP///gAf///4AAf///gAf///4AB////gAf///4AD////gA////4AH////gA////4Af////gA////4A/////gA//wAAB/////gA//gAAH/////gA//gAAP/////gA//gAA///8//gA//gAD///w//gA//wA////g//gA////////A//gA///////8A//gA///////4A//gAf//////wA//gAf//////gA//gAf/////+AA//gAP/////8AA//gAP/////4AA//gAH/////gAA//gAD/////AAA//gAB////8AAA//gAA////wAAA//gAAP///AAAA//gAAD//8AAAA//gAAAP+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/+AAAAAD/wAAB//8AAAAP/wAAB///AAAA//wAAB///wAAB//wAAB///4AAD//wAAB///8AAH//wAAB///+AAP//wAAB///+AAP//wAAB////AAf//wAAB////AAf//wAAB////gAf//wAAB////gA///wAAB////gA///wAAB////gA///w//AAf//wA//4A//AAA//wA//gA//AAAf/wA//gB//gAAf/wA//gB//gAAf/wA//gD//wAA//wA//wH//8AB//wA///////////gA///////////gA///////////gA///////////gAf//////////AAf//////////AAP//////////AAP/////////+AAH/////////8AAH///+/////4AAD///+f////wAAA///8P////gAAAf//4H///+AAAAH//gB///wAAAAAP4AAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wAAAAAAAAAA//wAAAAAAAAAP//wAAAAAAAAB///wAAAAAAAAf///wAAAAAAAH////wAAAAAAA/////wAAAAAAP/////wAAAAAB//////wAAAAAf//////wAAAAH///////wAAAA////////wAAAP////////wAAA///////H/wAAA//////wH/wAAA/////8AH/wAAA/////AAH/wAAA////gAAH/wAAA///4AAAH/wAAA//+AAAAH/wAAA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAH/4AAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//8AAA/////+B///AAA/////+B///wAA/////+B///4AA/////+B///8AA/////+B///8AA/////+B///+AA/////+B////AA/////+B////AA/////+B////AA/////+B////gA/////+B////gA/////+B////gA/////+A////gA//gP/gAAB//wA//gf/AAAA//wA//gf/AAAAf/wA//g//AAAAf/wA//g//AAAA//wA//g//gAAA//wA//g//+AAP//wA//g////////gA//g////////gA//g////////gA//g////////gA//g////////AA//gf///////AA//gf//////+AA//gP//////+AA//gH//////8AA//gD//////4AA//gB//////wAA//gA//////AAAAAAAH////8AAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////gAAAAB///////+AAAAH////////gAAAf////////4AAB/////////8AAD/////////+AAH//////////AAH//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wAf//////////4A//wAD/4AAf/4A//gAH/wAAP/4A//gAH/wAAP/4A//gAP/wAAP/4A//gAP/4AAf/4A//wAP/+AD//4A///wP//////4Af//4P//////wAf//4P//////wAf//4P//////wAf//4P//////wAP//4P//////gAP//4H//////gAH//4H//////AAH//4D/////+AAD//4D/////8AAB//4B/////4AAA//4A/////wAAAP/4AP////AAAAB/4AD///4AAAAAAAAAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAADgA//gAAAAAAP/gA//gAAAAAH//gA//gAAAAB///gA//gAAAAP///gA//gAAAD////gA//gAAAf////gA//gAAB/////gA//gAAP/////gA//gAB//////gA//gAH//////gA//gA///////gA//gD///////gA//gf///////gA//h////////gA//n////////gA//////////gAA/////////AAAA////////wAAAA///////4AAAAA///////AAAAAA//////4AAAAAA//////AAAAAAA/////4AAAAAAA/////AAAAAAAA////8AAAAAAAA////gAAAAAAAA///+AAAAAAAAA///4AAAAAAAAA///AAAAAAAAAA//4AAAAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//gB///wAAAAP//4H///+AAAA///8P////gAAB///+f////4AAD///+/////8AAH/////////+AAH//////////AAP//////////gAP//////////gAf//////////gAf//////////wAf//////////wAf//////////wA///////////wA//4D//wAB//4A//wB//gAA//4A//gA//gAAf/4A//gA//AAAf/4A//gA//gAAf/4A//wB//gAA//4A///P//8AH//4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////gAP//////////gAP//////////AAH//////////AAD/////////+AAD///+/////8AAB///8f////wAAAf//4P////AAAAH//wD///8AAAAA/+AAf//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//gAAAAAAAAB///+AA/+AAAAP////gA//wAAAf////wA//4AAB/////4A//8AAD/////8A//+AAD/////+A///AAH/////+A///AAP//////A///gAP//////A///gAf//////A///wAf//////A///wAf//////A///wAf//////A///wA///////AB//4A//4AD//AAP/4A//gAB//AAP/4A//gAA//AAP/4A//gAA/+AAP/4A//gAB/8AAP/4A//wAB/8AAf/4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH/////////+AAD/////////8AAB/////////4AAAf////////wAAAP////////AAAAB///////4AAAAAD/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAB/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("EiAnGicnJycnJycnEw=="), 78+(scale<<8)+(1<<16)); + // Actual height 69 (68 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADgAAAAAAAAAAA/gAAAAAAAAAAP/gAAAAAAAAAH//gAAAAAAAAB///gAAAAAAAAf///gAAAAAAAP////gAAAAAAD/////gAAAAAA//////gAAAAAP//////gAAAAH///////gAAAB////////gAAAf////////gAAP/////////gAD//////////AA//////////gAA/////////4AAA////////+AAAA////////gAAAA///////wAAAAA//////8AAAAAA//////AAAAAAA/////gAAAAAAA////4AAAAAAAA///+AAAAAAAAA///gAAAAAAAAA//wAAAAAAAAAA/8AAAAAAAAAAA/AAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////AAAAAB///////8AAAAH////////AAAAf////////wAAA/////////4AAB/////////8AAD/////////+AAH//////////AAP//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wA//8AAAAAB//4A//wAAAAAAf/4A//gAAAAAAP/4A//gAAAAAAP/4A//gAAAAAAP/4A//wAAAAAAf/4A///////////4Af//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH//////////AAD/////////+AAB/////////8AAA/////////4AAAP////////gAAAD///////+AAAAAf//////4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/gAAAAAAAAAAP/gAAAAAAAAAAf/gAAAAAAAAAAf/gAAAAAAAAAAf/AAAAAAAAAAA//AAAAAAAAAAA/+AAAAAAAAAAB/8AAAAAAAAAAD//////////gAH//////////gAP//////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/4AAAAB/gAAD//4AAAAf/gAAP//4AAAB//gAA///4AAAH//gAB///4AAAf//gAD///4AAA///gAH///4AAD///gAP///4AAH///gAP///4AAP///gAf///4AAf///gAf///4AB////gAf///4AD////gA////4AH////gA////4Af////gA////4A/////gA//wAAB/////gA//gAAH/////gA//gAAP/////gA//gAA///8//gA//gAD///w//gA//wA////g//gA////////A//gA///////8A//gA///////4A//gAf//////wA//gAf//////gA//gAf/////+AA//gAP/////8AA//gAP/////4AA//gAH/////gAA//gAD/////AAA//gAB////8AAA//gAA////wAAA//gAAP///AAAA//gAAD//8AAAA//gAAAP+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB/+AAAAAD/wAAB//8AAAAP/wAAB///AAAA//wAAB///wAAB//wAAB///4AAD//wAAB///8AAH//wAAB///+AAP//wAAB///+AAP//wAAB////AAf//wAAB////AAf//wAAB////gAf//wAAB////gA///wAAB////gA///wAAB////gA///w//AAf//wA//4A//AAA//wA//gA//AAAf/wA//gB//gAAf/wA//gB//gAAf/wA//gD//wAA//wA//wH//8AB//wA///////////gA///////////gA///////////gA///////////gAf//////////AAf//////////AAP//////////AAP/////////+AAH/////////8AAH///+/////4AAD///+f////wAAA///8P////gAAAf//4H///+AAAAH//gB///wAAAAAP4AAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/wAAAAAAAAAA//wAAAAAAAAAP//wAAAAAAAAB///wAAAAAAAAf///wAAAAAAAH////wAAAAAAA/////wAAAAAAP/////wAAAAAB//////wAAAAAf//////wAAAAH///////wAAAA////////wAAAP////////wAAA///////H/wAAA//////wH/wAAA/////8AH/wAAA/////AAH/wAAA////gAAH/wAAA///4AAAH/wAAA//+AAAAH/wAAA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gA///////////gAAAAAAAAH/4AAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAH/wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB//8AAA/////+B///AAA/////+B///wAA/////+B///4AA/////+B///8AA/////+B///8AA/////+B///+AA/////+B////AA/////+B////AA/////+B////AA/////+B////gA/////+B////gA/////+B////gA/////+A////gA//gP/gAAB//wA//gf/AAAA//wA//gf/AAAAf/wA//g//AAAAf/wA//g//AAAA//wA//g//gAAA//wA//g//+AAP//wA//g////////gA//g////////gA//g////////gA//g////////gA//g////////AA//gf///////AA//gf//////+AA//gP//////+AA//gH//////8AA//gD//////4AA//gB//////wAA//gA//////AAAAAAAH////8AAAAAAAA////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////gAAAAB///////+AAAAH////////gAAAf////////4AAB/////////8AAD/////////+AAH//////////AAH//////////gAP//////////gAP//////////gAf//////////wAf//////////wAf//////////wAf//////////wAf//////////4A//wAD/4AAf/4A//gAH/wAAP/4A//gAH/wAAP/4A//gAP/wAAP/4A//gAP/4AAf/4A//wAP/+AD//4A///wP//////4Af//4P//////wAf//4P//////wAf//4P//////wAf//4P//////wAP//4P//////gAP//4H//////gAH//4H//////AAH//4D/////+AAD//4D/////8AAB//4B/////4AAA//4A/////wAAAP/4AP////AAAAB/4AD///4AAAAAAAAAH/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//AAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAAAAA//gAAAAAAADgA//gAAAAAAP/gA//gAAAAAH//gA//gAAAAB///gA//gAAAAP///gA//gAAAD////gA//gAAAf////gA//gAAB/////gA//gAAP/////gA//gAB//////gA//gAH//////gA//gA///////gA//gD///////gA//gf///////gA//h////////gA//n////////gA//////////gAA/////////AAAA////////wAAAA///////4AAAAA///////AAAAAA//////4AAAAAA//////AAAAAAA/////4AAAAAAA/////AAAAAAAA////8AAAAAAAA////gAAAAAAAA///+AAAAAAAAA///4AAAAAAAAA///AAAAAAAAAA//4AAAAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//gB///wAAAAP//4H///+AAAA///8P////gAAB///+f////4AAD///+/////8AAH/////////+AAH//////////AAP//////////gAP//////////gAf//////////gAf//////////wAf//////////wAf//////////wA///////////wA//4D//wAB//4A//wB//gAA//4A//gA//gAAf/4A//gA//AAAf/4A//gA//gAAf/4A//wB//gAA//4A///P//8AH//4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////gAP//////////gAP//////////AAH//////////AAD/////////+AAD///+/////8AAB///8f////wAAAf//4P////AAAAH//wD///8AAAAA/+AAf//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//gAAAAAAAAB///+AA/+AAAAP////gA//wAAAf////wA//4AAB/////4A//8AAD/////8A//+AAD/////+A///AAH/////+A///AAP//////A///gAP//////A///gAf//////A///wAf//////A///wAf//////A///wAf//////A///wA///////AB//4A//4AD//AAP/4A//gAB//AAP/4A//gAA//AAP/4A//gAA/+AAP/4A//gAB/8AAP/4A//wAB/8AAf/4Af//////////wAf//////////wAf//////////wAf//////////wAf//////////wAP//////////gAP//////////gAH//////////AAH/////////+AAD/////////8AAB/////////4AAAf////////wAAAP////////AAAAB///////4AAAAAD/////wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAf/AAB/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAA//AAD/8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("EiAnGicnJycnJycnEw=="), 78 + (scale << 8) + (1 << 16)); +}; + +Graphics.prototype.setFontAntonSmall = function(scale) { + // Actual height 53 (52 - 0) + g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAf8AAAAAAAAAAAAAAAAAAAAMAAAAAAAAD8AAAAAAAA/8AAAAAAAf/8AAAAAAH//8AAAAAB///8AAAAA////8AAAAP////8AAAD/////8AAB//////8AAf//////8AH///////4A///////+AA///////AAA//////wAAA/////8AAAA////+AAAAA////gAAAAA///4AAAAAA//8AAAAAAA//AAAAAAAA/wAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/////wAAA//////8AAB//////+AAH///////gAH///////gAP///////wAf///////4Af///////4A////////8A////////8A////////8A//AAAAD/8A/8AAAAA/8A/8AAAAA/8A/8AAAAA/8A/+AAAAB/8A////////8A////////8A////////8Af///////4Af///////4AP///////wAP///////wAH///////gAD///////AAA//////8AAAP/////wAAAAAAAAAAAAAAAAAAAAAAAfwAAAAAAAA/4AAAAAAAA/4AAAAAAAB/wAAAAAAAB/wAAAAAAAD/wAAAAAAAD/gAAAAAAAH///////8AP///////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/4AAAP8AA//4AAA/8AB//4AAH/8AH//4AAP/8AP//4AA//8AP//4AB//8Af//4AD//8Af//4AP//8A///4Af//8A///4A///8A///4D///8A//AAH///8A/8AAP///8A/8AA//+/8A/8AD//8/8A/+Af//w/8A//////g/8A/////+A/8A/////8A/8Af////4A/8Af////wA/8AP////AA/8AP///+AA/8AH///8AA/8AD///wAA/8AA///AAA/8AAP/4AAA/8AAAAAAAAAAAAAAAAAAAAAAH4AAf/gAAA/4AAf/8AAD/4AAf//AAH/4AAf//gAP/4AAf//wAP/4AAf//wAf/4AAf//4Af/4AAf//4A//4AAf//8A//4AAf//8A//4AAP//8A//A/8AB/8A/8A/8AA/8A/8B/8AA/8A/8B/8AA/8A/+D//AB/8A////////8A////////8A////////8Af///////4Af///////4Af///////wAP///////gAH//9////gAD//4///+AAB//wf//4AAAP/AH//gAAAAAAAAAAAAAAAAAAAAAAAAAAAH/wAAAAAAB//wAAAAAAP//wAAAAAD///wAAAAA////wAAAAH////wAAAB/////wAAAf/////wAAD//////wAA///////wAA/////h/wAA////wB/wAA///8AB/wAA///AAB/wAA//gAAB/wAA////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8A////////8AAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAAAAAAAAAAAAAAAAAAAAAP/4AA////4P/+AA////4P//AA////4P//gA////4P//wA////4P//wA////4P//4A////4P//4A////4P//8A////4P//8A////4P//8A/8H/AAB/8A/8H+AAA/8A/8P+AAA/8A/8P+AAA/8A/8P/gAD/8A/8P/////8A/8P/////8A/8P/////8A/8P/////4A/8H/////4A/8H/////wA/8D/////wA/8B/////gA/8A////+AA/8AP///4AAAAAB///AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////wAAAf/////8AAB///////AAH///////gAP///////wAP///////wAf///////4Af///////4A////////8A////////8A////////8A/+AH/AB/8A/8AP+AA/8A/4Af+AA/8A/8Af+AA/8A/8Af/gH/8A//4f////8A//4f////8A//4f////8Af/4f////4Af/4f////4AP/4P////wAP/4P////gAH/4H////AAD/4D///+AAB/4B///4AAAP4AP//gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/8AAAAAAAA/8AAAAAAAA/8AAAAAB8A/8AAAAB/8A/8AAAAf/8A/8AAAH//8A/8AAA///8A/8AAH///8A/8AA////8A/8AD////8A/8Af////8A/8B/////8A/8P/////8A/8//////8A////////AA///////AAA//////gAAA/////4AAAA/////AAAAA////4AAAAA////AAAAAA///8AAAAAA///gAAAAAA//+AAAAAAA//wAAAAAAA/+AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/gD//gAAA//4P//8AAD//8f///AAH//+////gAH///////wAP///////4AP///////8Af///////8Af///////+Af///////+A////////+A//B//AB/+A/+A/+AA/+A/8Af+AA/+A/+Af+AA/+A//A//AB/+A////////+Af///////+Af///////+Af///////8Af///////8AP///////4AH///////4AH//+////wAD//+////AAA//4P//+AAAP/gH//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH//gAfgAAA///8A/8AAB///+A//AAH////A//gAH////g//wAP////g//wAf////w//4Af////w//4A/////w//8A/////w//8A/////w//8A//gP/wA/8A/8AD/wA/8A/8AD/wAf8A/8AD/gA/8A/+AH/AB/8A////////8A////////8A////////8Af///////4Af///////4Af///////wAP///////wAH///////gAD//////+AAA//////4AAAP/////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAP+AA/4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=="), 46, atob("DhgeFB4eHh4eHh4eDw=="), 60 + (scale << 8) + (1 << 16)); +}; + +// variables defined from settings +var secondsMode; +var secondsColoured; +var secondsWithColon; +var dateOnMain; +var dateOnSecs; +var weekDay; +var upperCase; +var vectorFont; + +// dynamic variables +var drawTimeout; +var queueMillis = 1000; +var secondsScreen = true; + +var isBangle1 = (g.getWidth() == 240); + +/* For development purposes +require('Storage').writeJSON(SETTINGSFILE, { + secondsMode: "Always", // "Never", "Unlocked", "Always" + secondsColoured: true, + secondsWithColon: true, + dateOnMain: "Long", // "Short", "Long", "ISO8601" + dateOnSecs: "Year", // "No", "Year", "Weekday", LEGACY: true/false + weekDay: true, + upperCase: true, + vectorFont: true, +}); +/* */ + +/* OR (also for development purposes) +require('Storage').erase(SETTINGSFILE); +/* */ + +// Helper method for loading the settings +function def(value, def) { + return (value !== undefined ? value : def); } -// timeout used to update every minute -var drawTimeout; +// Load settings +function loadSettings() { + var settings = require('Storage').readJSON(SETTINGSFILE, true) || {}; + secondsMode = def(settings.secondsMode, "Never"); + secondsColoured = def(settings.secondsColoured, true); + secondsWithColon = def(settings.secondsWithColon, true); + dateOnMain = def(settings.dateOnMain, "Long"); + dateOnSecs = def(settings.dateOnSecs, "Year"); + weekDay = def(settings.weekDay, true); + upperCase = def(settings.upperCase, true); + vectorFont = def(settings.vectorFont, false); -// schedule a draw for the next minute + // Legacy + if (dateOnSecs === true) + dateOnSecs = "Year"; + if (dateOnSecs === false) + dateOnSecs = "No"; +} + +// schedule a draw for the next second or minute function queueDraw() { if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = setTimeout(function() { drawTimeout = undefined; draw(); - }, 60000 - (Date.now() % 60000)); + }, queueMillis - (Date.now() % queueMillis)); } - -function draw() { - var x = g.getWidth()/2; - var y = g.getHeight()/2; - g.reset(); - var date = new Date(); - var timeStr = require("locale").time(date,1); - var dateStr = require("locale").date(date).toUpperCase(); - var dowStr = require("locale").dow(date).toUpperCase(); - // draw time - g.setFontAlign(0,0).setFont("Anton"); - g.clearRect(0,y-40,g.getWidth(),y+35); // clear the background - g.drawString(timeStr,x,y); - // draw date - y += 40; - g.setFontAlign(0,0).setFont("6x8",2); - g.clearRect(0,y-8,g.getWidth(),y+8); // clear the background - g.drawString(dateStr,x,y); - //draw day of week - y += 16; - g.clearRect(0,y-8,g.getWidth(),y+8); // clear the background - g.drawString(dowStr,x,y); - // queue draw in one minute - queueDraw(); -} - -// Clear the screen once, at startup -g.clear(); -// draw immediately at first, queue update -draw(); -// Stop updates when LCD is off, restart when on -Bangle.on('lcdPower',on=>{ - if (on) { +function updateState() { + if (Bangle.isLCDOn()) { + if ((secondsMode === "Unlocked" && !Bangle.isLocked()) || secondsMode === "Always") { + secondsScreen = true; + queueMillis = 1000; + } else { + secondsScreen = false; + queueMillis = 60000; + } draw(); // draw immediately, queue redraw } else { // stop draw timer if (drawTimeout) clearTimeout(drawTimeout); drawTimeout = undefined; } +} + +function isoStr(date) { + return date.getFullYear() + "-" + ("0" + (date.getMonth() + 1)).substr(-2) + "-" + ("0" + date.getDate()).substr(-2); +} + +function doColor() { + return !isBangle1 && !Bangle.isLocked() && secondsColoured; +} + +// Actually draw the watch face +function draw() { + var x = g.getWidth() / 2; + var y = g.getHeight() / 2 - (secondsMode !== "Never" ? 24 : (vectorFont ? 12 : 0)); + g.reset(); + /* This is to mark the widget areas during development. + g.setColor("#888") + .fillRect(0, 0, g.getWidth(), 23) + .fillRect(0, g.getHeight() - 23, g.getWidth(), g.getHeight()).reset(); + /* */ + g.clearRect(0, 24, g.getWidth(), g.getHeight() - 24); // clear whole background (w/o widgets) + var date = new Date(); // Actually the current date, this one is shown + var timeStr = require("locale").time(date, 1); // Hour and minute + g.setFontAlign(0, 0).setFont("Anton").drawString(timeStr, x, y); // draw time + if (secondsScreen) { + y += 65; + var secStr = (secondsWithColon ? ":" : "") + ("0" + date.getSeconds()).substr(-2); + if (doColor()) + g.setColor(0, 0, 1); + g.setFont("AntonSmall"); + if (dateOnSecs !== "No") { // A bit of a complex drawing with seconds on the right and date on the left + g.setFontAlign(1, 0).drawString(secStr, g.getWidth() - (isBangle1 ? 32 : 2), y); // seconds + y -= (vectorFont ? 15 : 13); + x = g.getWidth() / 4 + (isBangle1 ? 12 : 4) + (secondsWithColon ? 0 : g.stringWidth(":") / 2); + var dateStr2 = (dateOnMain === "ISO8601" ? isoStr(date) : require("locale").date(date, 1)); + var year; + var md; + var yearfirst; + if (dateStr2.match(/\d\d\d\d$/)) { // formatted date ends with year + year = (dateOnSecs === "Year" ? dateStr2.slice(-4) : require("locale").dow(date, 1)); + md = dateStr2.slice(0, -4); + if (!md.endsWith(".")) // keep separator before the year only if it is a dot (31.12. but 31/12) + md = md.slice(0, -1); + yearfirst = false; + } else { // formatted date begins with year + if (!dateStr2.match(/^\d\d\d\d/)) // if year position cannot be detected... + dateStr2 = isoStr(date); // ...use ISO date format instead + year = (dateOnSecs === "Year" ? dateStr2.slice(0, 4) : require("locale").dow(date, 1)); + md = dateStr2.slice(5); // never keep separator directly after year + yearfirst = true; + } + if (dateOnSecs === "Weekday" && upperCase) + year = year.toUpperCase(); + g.setFontAlign(0, 0); + if (vectorFont) + g.setFont("Vector", 24); + else + g.setFont("6x8", 2); + if (doColor()) + g.setColor(1, 0, 0); + g.drawString(md, x, (yearfirst ? y + (vectorFont ? 26 : 16) : y)); + g.drawString(year, x, (yearfirst ? y : y + (vectorFont ? 26 : 16))); + } else { + g.setFontAlign(0, 0).drawString(secStr, x, y); // Just the seconds centered + } + } else { // No seconds screen: Show date and optionally day of week + y += (vectorFont ? 50 : (secondsMode !== "Never") ? 52 : 40); + var dateStr = (dateOnMain === "ISO8601" ? isoStr(date) : require("locale").date(date, (dateOnMain === "Long" ? 0 : 1))); + if (upperCase) + dateStr = dateStr.toUpperCase(); + g.setFontAlign(0, 0); + if (vectorFont) + g.setFont("Vector", 24); + else + g.setFont("6x8", 2); + g.drawString(dateStr, x, y); + if (weekDay) { + var dowStr = require("locale").dow(date); + if (upperCase) + dowStr = dowStr.toUpperCase(); + g.drawString(dowStr, x, y + (vectorFont ? 26 : 16)); + } + } + + // queue next draw + queueDraw(); +} + +// Init the settings of the app +loadSettings(); +// Clear the screen once, at startup +g.clear(); +// Set dynamic state and perform initial drawing +updateState(); +// Register hooks for LCD on/off event and screen lock on/off event +Bangle.on('lcdPower', on => { + updateState(); +}); +Bangle.on('lock', on => { + updateState(); }); // Show launcher when middle button pressed Bangle.setUI("clock"); // Load widgets Bangle.loadWidgets(); Bangle.drawWidgets(); + +// end of file \ No newline at end of file diff --git a/apps/antonclk/app.png b/apps/antonclk/app.png index d96f17758..a38093c5f 100644 Binary files a/apps/antonclk/app.png and b/apps/antonclk/app.png differ diff --git a/apps/antonclk/screenshot.png b/apps/antonclk/screenshot.png index c66f8bdd8..e949b8a24 100644 Binary files a/apps/antonclk/screenshot.png and b/apps/antonclk/screenshot.png differ diff --git a/apps/antonclk/settings.js b/apps/antonclk/settings.js new file mode 100644 index 000000000..08fde512e --- /dev/null +++ b/apps/antonclk/settings.js @@ -0,0 +1,99 @@ +// Settings menu for the enhanced Anton clock + +(function(back) { + var FILE = "antonclk.json"; + // Load settings + var settings = Object.assign({ + secondsOnUnlock: false, + }, require('Storage').readJSON(FILE, true) || {}); + + function writeSettings() { + require('Storage').writeJSON(FILE, settings); + } + + // Helper method which uses int-based menu item for set of string values + function stringItems(startvalue, writer, values) { + return { + value: (startvalue === undefined ? 0 : values.indexOf(startvalue)), + format: v => values[v], + min: 0, + max: values.length - 1, + wrap: true, + step: 1, + onchange: v => { + writer(values[v]); + writeSettings(); + } + }; + } + + // Helper method which breaks string set settings down to local settings object + function stringInSettings(name, values) { + return stringItems(settings[name], v => settings[name] = v, values); + } + + var mainmenu = { + "": { + "title": "Anton clock" + }, + "< Back": () => back(), + "Seconds...": () => E.showMenu(secmenu), + "Date": stringInSettings("dateOnMain", ["Short", "Long", "ISO8601"]), + "Show Weekday": { + value: (settings.weekDay !== undefined ? settings.weekDay : true), + format: v => v ? "On" : "Off", + onchange: v => { + settings.weekDay = v; + writeSettings(); + } + }, + "Uppercase": { + value: (settings.upperCase !== undefined ? settings.upperCase : false), + format: v => v ? "On" : "Off", + onchange: v => { + settings.upperCase = v; + writeSettings(); + } + }, + "Vector font": { + value: (settings.vectorFont !== undefined ? settings.vectorFont : false), + format: v => v ? "On" : "Off", + onchange: v => { + settings.vectorFont = v; + writeSettings(); + } + }, + }; + + // Submenu + var secmenu = { + "": { + "title": "Show seconds..." + }, + "< Back": () => E.showMenu(mainmenu), + "Show": stringInSettings("secondsMode", ["Never", "Unlocked", "Always"]), + "With \":\"": { + value: (settings.secondsWithColon !== undefined ? settings.secondsWithColon : false), + format: v => v ? "On" : "Off", + onchange: v => { + settings.secondsWithColon = v; + writeSettings(); + } + }, + "Color": { + value: (settings.secondsColoured !== undefined ? settings.secondsColoured : false), + format: v => v ? "On" : "Off", + onchange: v => { + settings.secondsColoured = v; + writeSettings(); + } + }, + "Date": stringInSettings("dateOnSecs", ["No", "Year", "Weekday"]) + }; + + // Actually display the menu + E.showMenu(mainmenu); + +}); + +// end of file diff --git a/apps/awairmonitor/ChangeLog b/apps/awairmonitor/ChangeLog index 0cc9a42b0..71d6399c4 100644 --- a/apps/awairmonitor/ChangeLog +++ b/apps/awairmonitor/ChangeLog @@ -1 +1,3 @@ 0.01: Beta version for Bangle 2 paired with Chrome (2021/12/11) +0.02: The app is now a clock, the data is greyed after the connection is lost (2021/12/22) +0.03: Set the Awair's IP directly on the webpage (2021/12/27) diff --git a/apps/awairmonitor/README.md b/apps/awairmonitor/README.md index 69894fea2..f4c7c42c4 100644 --- a/apps/awairmonitor/README.md +++ b/apps/awairmonitor/README.md @@ -5,11 +5,10 @@ Displays the level of CO2, VOC, PM 2.5, Humidity and Temperature, from your Awai * What you need: * A BangleJS 2 * An Awair device [with local API enabled](https://support.getawair.com/hc/en-us/articles/360049221014-Awair-Local-API-Feature) - * The web app [awair_to_bangle.html](awair_to_bangle.html) that will retrive the data from your Awair device and sent it to your BangleJS 2 through Chrome's Bluetooth LE connection + * The web app [awair_to_bangle.html](awair_to_bangle.html) that will retrieve the data from your Awair device and sent it to your BangleJS 2 through Chrome's Bluetooth LE connection * How to get started - * Open awair_to_bangle.html with a text/code editor and input the IP address of your Awair on top (const awair_ip_1 = "192.168.xx.xx") * Launch the Awair Monitor app on your BangleJS - * Open awair_to_bangle.html on Chrome and click "Connect BangleJS" - it connects to your watch the same way as the Bangle app store + * Open awair_to_bangle.html on Chrome (desktop or Android), input the IP address of your Awair device, and click "Connect BangleJS" - it connects to your watch the same way as the Bangle app store * Once connected to the watch with the app running, the watch app is updated once per second  diff --git a/apps/awairmonitor/app.js b/apps/awairmonitor/app.js index a5a1d1a72..9123a9c2c 100644 --- a/apps/awairmonitor/app.js +++ b/apps/awairmonitor/app.js @@ -30,6 +30,8 @@ var bt_temp_history = new Array(10).fill(0); var internal_last_update = -1; +var display_frozen = false; + function draw() { g.reset().clearRect(0,24,g.getWidth(),g.getHeight()); @@ -47,14 +49,8 @@ function draw() { g.drawString("Humi", 125, 100); g.drawString("Temp", 160, 100); - g.setFont("HaxorNarrow7x17"); - g.drawString(""+bt_current_co2, 18, 110); - g.drawString(""+bt_current_voc, 53, 110); - g.drawString(""+bt_current_pm25, 88, 110); - g.drawString(""+bt_current_humi, 123, 110); - g.drawString(""+bt_current_temp, 158, 110); - if (last_update != bt_last_update) { + display_frozen = false; last_update = bt_last_update; internal_last_update = last_update; if (last_update % 10 == 0) { @@ -65,16 +61,29 @@ function draw() { bt_temp_history.shift(); bt_temp_history.push(bt_current_temp); } } - + if (internal_last_update == -1) { g.drawString("Waiting for connection", 88, 164); - } else if (internal_last_update > last_update + 5) { + } else if ((internal_last_update > last_update + 5) && (internal_last_update < last_update + 60)) { g.drawString("Trying to reconnect since " + (internal_last_update - last_update), 88, 164); + } else if (internal_last_update > last_update + 5) { + display_frozen = true; + g.drawString("Waiting for connection", 88, 164); } + if (display_frozen) { g.setColor("#888"); } + + g.setFont("HaxorNarrow7x17"); + g.drawString(""+bt_current_co2, 18, 110); + g.drawString(""+bt_current_voc, 53, 110); + g.drawString(""+bt_current_pm25, 88, 110); + g.drawString(""+bt_current_humi, 123, 110); + g.drawString(""+bt_current_temp, 158, 110); for (i = 0; i < 10; i++) { - // max height = 32 + if (display_frozen) { g.setColor("#888"); } + + // max height = 32 g.drawLine(10+i*2, 150-(Math.min(Math.max(bt_co2_history[i],400), 1200)-400)/25, 10+i*2, 150); g.drawLine(45+i*2, 150-(Math.min(Math.max(bt_voc_history[i],0), 1440)-0)/45, 45+i*2, 150); g.drawLine(80+i*2, 150-(Math.min(Math.max(bt_pm25_history[i],0), 32)-0)/1, 80+i*2, 150); @@ -91,6 +100,7 @@ function draw() { } // init +Bangle.setUI("clock"); require("FontHaxorNarrow7x17").add(Graphics); g.clear(); Bangle.loadWidgets(); diff --git a/apps/awairmonitor/awair_to_bangle.html b/apps/awairmonitor/awair_to_bangle.html index 2926cca9e..69c52499f 100644 --- a/apps/awairmonitor/awair_to_bangle.html +++ b/apps/awairmonitor/awair_to_bangle.html @@ -7,15 +7,15 @@ // Don't forget to enable the Local API on your Awair before using this // https://support.getawair.com/hc/en-us/articles/360049221014-Awair-Local-API-Feature -const awair_ip_1 = "192.168.2.2"; // <- INPUT YOUR AWAIR IP ADDRESS HERE const awair_name_1 = "Awair"; var bt_connection; var is_connected = false; var reconnect_counter = 5; var reconnect_attempt_counter = 1; +var is_chart_started = false; -window.onload = function() { +function initChart() { var chart_co2; var chart_voc; var chart_pm; @@ -23,6 +23,8 @@ window.onload = function() { var chart_humidity; var dataPoints_1 = []; var posx = 0; + + var awair_ip_1 = document.getElementById('inputawairip').value; $.getJSON("http://"+awair_ip_1+"/air-data/latest", function(data) { $.each(data, function(key, value){ @@ -105,11 +107,12 @@ window.onload = function() { let current_humi = dataPoints_1['humid'][dataPoints_1['humid'].length-1].y; let current_temp = dataPoints_1['temp'][dataPoints_1['temp'].length-1].y; let last_update = dataPoints_1['temp'].length-1; - if (is_connected && bt_connection.isOpen) { + + if (is_connected && bt_connection && bt_connection.isOpen) { bt_connection.write('\x10bt_current_co2='+current_co2+';bt_current_voc='+current_voc+';bt_current_pm25='+current_pm25+';bt_current_humi='+current_humi+';bt_current_temp='+current_temp+';bt_last_update='+last_update+';\n'); console.log("Sent data through Bluetooth"); - } else if (is_connected && !bt_connection.isOpen) { + } else if (is_connected && bt_connection && !bt_connection.isOpen) { console.log("Disconnected - Next attempt to reconnect in " + reconnect_counter); reconnect_counter--; @@ -131,7 +134,6 @@ window.onload = function() { } } - setTimeout(function(){updateChart()}, 1000); }); } @@ -148,10 +150,16 @@ function connectBT() { bt_connection = c; is_connected = true; reconnect_attempt_counter = 1; + if (!is_chart_started) { + initChart(); + is_chart_started = true; + } }); } function disconnectBT() { + console.log("Disconnect Bluetooth button pressed. bt_connection value below.") + console.log(bt_connection); if (is_connected && bt_connection) { bt_connection.close(); is_connected = false; @@ -167,23 +175,21 @@ function disconnectBT() {
How to use
-
+
Step 1: Enable the Local API on your Awair: https://support.getawair.com/hc/en-us/articles/360049221014-Awair-Local-API-Feature
-
-Step 2: Modify this HTML file to input the IP address of your Awair on top (const awair_ip_1 = "192.168.xx.xx")
-
-Step 3: Launch the Awair Monitor app on your BangleJS
-
-Step 4: Click "Connect BangleJS"
-
-Step 5: Optionally, open the web inspector's console (Right click > Inspector > Console) to read the bluetooth logs
+
+Step 2: Launch the Awair Monitor app on your BangleJS
+
+Step 3: Input your Awair IP address and click the Connect button:
+
+
+
+Step 4: Optionally, open the web inspector's console (Right click > Inspector > Console) to read the Bluetooth logs
+
+Step 5: Once you are done, click the Disconnect button to properly close the Blutooth connection
+