Merge branch 'espruino:master' into scaledlauncher
|
|
@ -1,2 +1,4 @@
|
|||
apps/animclk/V29.LBM.js
|
||||
apps/banglerun/rollup.config.js
|
||||
apps/schoolCalendar/fullcalendar/main.js
|
||||
apps/authentiwatch/qr_packed.js
|
||||
|
|
|
|||
136
apps.json
|
|
@ -32,7 +32,7 @@
|
|||
{
|
||||
"id": "messages",
|
||||
"name": "Messages",
|
||||
"version": "0.03",
|
||||
"version": "0.05",
|
||||
"description": "App to display notifications from iOS and Gadgetbridge",
|
||||
"icon": "app.png",
|
||||
"type": "app",
|
||||
|
|
@ -45,12 +45,14 @@
|
|||
{"name":"messages.wid.js","url":"widget.js"},
|
||||
{"name":"messages","url":"lib.js"}
|
||||
],
|
||||
"data": [{"name":"messages.json"}],
|
||||
"sortorder": -9
|
||||
},
|
||||
{
|
||||
"id": "android",
|
||||
"name": "Android Integration",
|
||||
"version": "0.01",
|
||||
"shortName": "Android",
|
||||
"version": "0.03",
|
||||
"description": "(BETA) App to display notifications from Gadgetbridge on Android. This will eventually replace the Gadgetbridge widget.",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,system,messages,notifications",
|
||||
|
|
@ -61,12 +63,12 @@
|
|||
{"name":"android.img","url":"app-icon.js","evaluate":true},
|
||||
{"name":"android.boot.js","url":"boot.js"}
|
||||
],
|
||||
"sortorder": -9
|
||||
"sortorder": -8
|
||||
},
|
||||
{
|
||||
"id": "ios",
|
||||
"name": "iOS Integration",
|
||||
"version": "0.01",
|
||||
"version": "0.03",
|
||||
"description": "(BETA) App to display notifications from iOS devices",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,system,ios,apple,messages,notifications",
|
||||
|
|
@ -77,7 +79,7 @@
|
|||
{"name":"ios.img","url":"app-icon.js","evaluate":true},
|
||||
{"name":"ios.boot.js","url":"boot.js"}
|
||||
],
|
||||
"sortorder": -9
|
||||
"sortorder": -8
|
||||
},
|
||||
{
|
||||
"id": "health",
|
||||
|
|
@ -141,6 +143,7 @@
|
|||
"icon": "app.png",
|
||||
"tags": "tool,system",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"screenshots": [{"url":"bangle1-about-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"about.app.js","url":"app-bangle1.js","supports": ["BANGLEJS"]},
|
||||
|
|
@ -216,7 +219,7 @@
|
|||
"id": "welcome",
|
||||
"name": "Welcome",
|
||||
"shortName": "Welcome",
|
||||
"version": "0.13",
|
||||
"version": "0.14",
|
||||
"description": "Appears at first boot and explains how to use Bangle.js",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"screenshot_welcome.png"}],
|
||||
|
|
@ -242,6 +245,7 @@
|
|||
"tags": "start,welcome",
|
||||
"supports": ["BANGLEJS"],
|
||||
"custom": "custom.html",
|
||||
"screenshots": [{"url":"bangle1-customized-welcome-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"mywelcome.boot.js","url":"boot.js"},
|
||||
{"name":"mywelcome.app.js","url":"app.js"},
|
||||
|
|
@ -278,6 +282,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-morphing-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"mclock.app.js","url":"clock-morphing.js"},
|
||||
{"name":"mclock.img","url":"clock-morphing-icon.js","evaluate":true}
|
||||
|
|
@ -292,6 +297,7 @@
|
|||
"icon": "app.png",
|
||||
"tags": "",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"bangle1-moon-phase-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"moonphase.app.js","url":"app.js"},
|
||||
|
|
@ -422,6 +428,7 @@
|
|||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-sweep-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"sweepclock.app.js","url":"sweepclock.js"},
|
||||
{"name":"sweepclock.img","url":"sweepclock-icon.js","evaluate":true}
|
||||
|
|
@ -472,6 +479,7 @@
|
|||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"bangle1-impercise-word-clock-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"impwclock.app.js","url":"clock-impword.js"},
|
||||
|
|
@ -555,6 +563,7 @@
|
|||
"supports" : ["BANGLEJS","BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle2-cube-scramble-screenshot.png"},{"url":"bangle1-cube-scramble-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"cubescramble.app.js","url":"cube-scramble.js"},
|
||||
{"name":"cubescramble.img","url":"cube-scramble-icon.js","evaluate":true}
|
||||
|
|
@ -658,7 +667,7 @@
|
|||
{
|
||||
"id": "gpsrec",
|
||||
"name": "GPS Recorder",
|
||||
"version": "0.24",
|
||||
"version": "0.25",
|
||||
"description": "Application that allows you to record a GPS track. Can run in background",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,outdoors,gps,widget",
|
||||
|
|
@ -745,7 +754,7 @@
|
|||
"description": "Show currently installed apps, free space, and allow their deletion from the watch",
|
||||
"icon": "files.png",
|
||||
"tags": "tool,system,files",
|
||||
"supports": ["BANGLEJS"],
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"storage": [
|
||||
{"name":"files.app.js","url":"files.js"},
|
||||
{"name":"files.img","url":"files-icon.js","evaluate":true}
|
||||
|
|
@ -779,6 +788,7 @@
|
|||
"tags": "battery",
|
||||
"supports": ["BANGLEJS", "BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle2-charge-animation-screenshot.png"},{"url":"bangle-charge-animation-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"chargeanim.app.js","url":"app.js"},
|
||||
{"name":"chargeanim.boot.js","url":"boot.js"},
|
||||
|
|
@ -984,6 +994,7 @@
|
|||
"readme": "README.md",
|
||||
"interface": "interface.html",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-stopwatch-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"swatch.app.js","url":"stopwatch.js"},
|
||||
{"name":"swatch.img","url":"stopwatch-icon.js","evaluate":true}
|
||||
|
|
@ -1185,6 +1196,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-vibrate-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"vibrclock.app.js","url":"app.js"},
|
||||
{"name":"vibrclock.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -1200,6 +1212,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle2-simple-v-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"svclock.app.js","url":"vclock-simple.js"},
|
||||
{"name":"svclock.img","url":"vclock-simple-icon.js","evaluate":true}
|
||||
|
|
@ -1215,6 +1228,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle2-dev-clock-screenshot.png"},{"url":"bangle1-dev-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"dclock.app.js","url":"clock-dev.js"},
|
||||
{"name":"dclock.img","url":"clock-dev-icon.js","evaluate":true}
|
||||
|
|
@ -1246,6 +1260,7 @@
|
|||
"tags": "party,parrot,lol",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-party-parrot-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"pparrot.app.js","url":"party-parrot.js"},
|
||||
{"name":"pparrot.img","url":"party-parrot-icon.js","evaluate":true}
|
||||
|
|
@ -1261,6 +1276,7 @@
|
|||
"tags": "rings,hypnosis,psychadelic",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-hypno-rings-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"hrings.app.js","url":"hypno-rings.js"},
|
||||
{"name":"hrings.img","url":"hypno-rings-icon.js","evaluate":true}
|
||||
|
|
@ -1328,6 +1344,7 @@
|
|||
"icon": "show-color.png",
|
||||
"type": "app",
|
||||
"tags": "tool",
|
||||
"screenshots": [{"url":"bangle1-view-color-screenshot.png"}],
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
|
|
@ -1343,6 +1360,7 @@
|
|||
"icon": "clock-mixed.png",
|
||||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"screenshots": [{"url":"bangle1-mixed-clock-screenshot.png"}],
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
|
|
@ -1360,6 +1378,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-binary-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"bclock.app.js","url":"clock-binary.js"},
|
||||
{"name":"bclock.img","url":"clock-binary-icon.js","evaluate":true}
|
||||
|
|
@ -1373,6 +1392,7 @@
|
|||
"icon": "clock-tris.png",
|
||||
"tags": "game",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"bangle1-clock-tris-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"clotris.app.js","url":"clock-tris.js"},
|
||||
|
|
@ -1432,6 +1452,7 @@
|
|||
"tags": "pomodoro,cooking,tools",
|
||||
"supports": ["BANGLEJS", "BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle2-pomodoro-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"pomodo.app.js","url":"pomodoro.js"},
|
||||
{"name":"pomodo.img","url":"pomodoro-icon.js","evaluate":true}
|
||||
|
|
@ -1448,6 +1469,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle2-large-digit-blob-clock-screenshot.png"},{"url":"bangle1-large-digit-blob-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"blobclk.app.js","url":"clock-blob.js"},
|
||||
{"name":"blobclk.img","url":"clock-blob-icon.js","evaluate":true}
|
||||
|
|
@ -1507,6 +1529,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"berlin-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"berlinc.app.js","url":"berlin-clock.js"},
|
||||
{"name":"berlinc.img","url":"berlin-clock-icon.js","evaluate":true}
|
||||
|
|
@ -1521,6 +1544,7 @@
|
|||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"bangle1-center-clock-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"ctrclk.app.js","url":"app.js"},
|
||||
|
|
@ -1535,6 +1559,7 @@
|
|||
"icon": "app.png",
|
||||
"type": "app",
|
||||
"tags": "",
|
||||
"screenshots": [{"url":"bangle1-demo-loop-screenshot1.png"},{"url":"bangle1-demo-loop-screenshot2.png"},{"url":"bangle1-demo-loop-screenshot3.png"},{"url":"bangle1-demo-loop-screenshot4.png"}],
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
|
|
@ -1567,6 +1592,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-pipboy-themed-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"pipboy.app.js","url":"app.js"},
|
||||
{"name":"pipboy.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -1613,6 +1639,7 @@
|
|||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-workout-HRM-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"wohrm.app.js","url":"app.js"},
|
||||
{"name":"wohrm.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -1657,6 +1684,7 @@
|
|||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": false,
|
||||
"screenshots": [{"url":"bangle1-mario-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"marioclock.app.js","url":"marioclock-app.js"},
|
||||
{"name":"marioclock.img","url":"marioclock-icon.js","evaluate":true}
|
||||
|
|
@ -1695,13 +1723,13 @@
|
|||
{
|
||||
"id": "barclock",
|
||||
"name": "Bar Clock",
|
||||
"version": "0.08",
|
||||
"version": "0.09",
|
||||
"description": "A simple digital clock showing seconds as a bar",
|
||||
"icon": "clock-bar.png",
|
||||
"screenshots": [{"url":"screenshot.png"},{"url":"screenshot_pm.png"}],
|
||||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
|
|
@ -1719,6 +1747,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle2-dot-clcok-screenshot.png"},{"url":"bangle1-dot-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"dotclock.app.js","url":"clock-dot.js"},
|
||||
{"name":"dotclock.img","url":"clock-dot-icon.js","evaluate":true}
|
||||
|
|
@ -1828,6 +1857,7 @@
|
|||
"tags": "game,fun",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-rpg-dice-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"rpgdice.app.js","url":"app.js"},
|
||||
{"name":"rpgdice.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -1856,6 +1886,7 @@
|
|||
"tags": "clock,minion",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-minion-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"minionclk.app.js","url":"app.js"},
|
||||
{"name":"minionclk.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -1933,7 +1964,7 @@
|
|||
"icon": "custom.png",
|
||||
"type": "bootloader",
|
||||
"tags": "tool,system",
|
||||
"supports": ["BANGLEJS"],
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"custom": "custom.html",
|
||||
"storage": [
|
||||
{"name":"custom"}
|
||||
|
|
@ -1948,6 +1979,7 @@
|
|||
"icon": "app.png",
|
||||
"tags": "stopwatch,chrono,timer,chronometer",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"screenshots": [{"url":"bangle1-dev-stopwatch-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"devstopwatch.app.js","url":"app.js"},
|
||||
|
|
@ -1981,6 +2013,7 @@
|
|||
"tags": "app,learn,visual",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-NATO-alphabet-screenshot.png"},{"url":"bangle1-NATO-alphabet-screenshot2.png"}],
|
||||
"storage": [
|
||||
{"name":"nato.app.js","url":"nato.js"},
|
||||
{"name":"nato.img","url":"nato-icon.js","evaluate":true}
|
||||
|
|
@ -1997,6 +2030,7 @@
|
|||
"tags": "numerals,clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-numerals-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"numerals.app.js","url":"numerals.app.js"},
|
||||
{"name":"numerals.img","url":"numerals-icon.js","evaluate":true},
|
||||
|
|
@ -2123,13 +2157,14 @@
|
|||
{
|
||||
"id": "metronome",
|
||||
"name": "Metronome",
|
||||
"version": "0.06",
|
||||
"version": "0.07",
|
||||
"readme": "README.md",
|
||||
"description": "Makes the watch blinking and vibrating with a given rate",
|
||||
"icon": "metronome_icon.png",
|
||||
"tags": "tool",
|
||||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-metronome-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"metronome.app.js","url":"metronome.js"},
|
||||
{"name":"metronome.img","url":"metronome-icon.js","evaluate":true},
|
||||
|
|
@ -2145,6 +2180,7 @@
|
|||
"icon": "blackjack.png",
|
||||
"tags": "game",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"bangle1-black-jack-game-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"blackjack.app.js","url":"blackjack.app.js"},
|
||||
|
|
@ -2178,6 +2214,7 @@
|
|||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-SWL-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"swlclk.app.js","url":"app.js"},
|
||||
{"name":"swlclk.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -2255,6 +2292,7 @@
|
|||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-pong-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"pong.app.js","url":"app.js"},
|
||||
{"name":"pong.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -2317,6 +2355,7 @@
|
|||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-large-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"largeclock.app.js","url":"largeclock.js"},
|
||||
{"name":"largeclock.img","url":"largeclock-icon.js","evaluate":true},
|
||||
|
|
@ -2368,6 +2407,7 @@
|
|||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-timer-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"simpletimer.app.js","url":"app.js"},
|
||||
{"name":".tfnames","url":"gesture-tfnames.js","evaluate":true},
|
||||
|
|
@ -2384,6 +2424,7 @@
|
|||
"icon": "beebclock.png",
|
||||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"screenshots": [{"url":"bangle1-beeb-clock-screenshot.png"}],
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
|
|
@ -2417,6 +2458,7 @@
|
|||
"tags": "tools,health",
|
||||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"screenshots": [{"url":"bangle1-get-up-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"getup.app.js","url":"app.js"},
|
||||
|
|
@ -2495,6 +2537,7 @@
|
|||
"version": "0.01",
|
||||
"description": "La palla predice il futuro",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"bangle1-magic-8-ball-italiano-screenshot.png"}],
|
||||
"tags": "game",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
|
|
@ -2608,6 +2651,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-vertical-watch-face-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"verticalface.app.js","url":"app.js"},
|
||||
{"name":"verticalface.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -2635,6 +2679,7 @@
|
|||
"icon": "life.png",
|
||||
"tags": "game",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"bangle1-game-of-life-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"life.app.js","url":"life.min.js"},
|
||||
|
|
@ -2682,6 +2727,7 @@
|
|||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"bangle1-mixed-clock-2-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"miclock2.app.js","url":"clock-mixed.js"},
|
||||
|
|
@ -2817,6 +2863,7 @@
|
|||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-CPR-assist-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"cprassist.app.js","url":"cprassist.js"},
|
||||
{"name":"cprassist.img","url":"cprassist-icon.js","evaluate":true},
|
||||
|
|
@ -2860,6 +2907,7 @@
|
|||
"icon": "counter_icon.png",
|
||||
"tags": "tool",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"bangle1-counter-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"counter.app.js","url":"counter.js"},
|
||||
|
|
@ -3239,6 +3287,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"screenshots": [{"url":"bangle1-lazy-clock-screenshot.png"}],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"lazyclock.app.js","url":"lazyclock-app.js"},
|
||||
|
|
@ -3340,6 +3389,7 @@
|
|||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-slow-mo-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"slomoclock.app.js","url":"app.js"},
|
||||
{"name":"slomoclock.img","url":"app-icon.js","evaluate":true},
|
||||
|
|
@ -3654,7 +3704,7 @@
|
|||
"id": "gbmusic",
|
||||
"name": "Gadgetbridge Music Controls",
|
||||
"shortName": "Music Controls",
|
||||
"version": "0.06",
|
||||
"version": "0.07",
|
||||
"description": "Control the music on your Gadgetbridge-connected phone",
|
||||
"icon": "icon.png",
|
||||
"screenshots": [{"url":"screenshot_v1.png"},{"url":"screenshot_v2.png"}],
|
||||
|
|
@ -3679,6 +3729,7 @@
|
|||
"icon": "battleship-icon.png",
|
||||
"tags": "game",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"bangle1-battle-ship-screenshot.png"}],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
|
|
@ -3882,6 +3933,7 @@
|
|||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"bangle1-mystic-clock-screenshot.png"}],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
|
|
@ -3898,6 +3950,7 @@
|
|||
"icon": "hcclock-icon.png",
|
||||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"screenshots": [{"url":"bangle1-high-contrast-clock-screenshot.png"}],
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
|
|
@ -3979,6 +4032,7 @@
|
|||
"tags": "clock",
|
||||
"supports": ["BANGLEJS"],
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-vector-clock-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"vectorclock.app.js","url":"app.js"},
|
||||
{"name":"vectorclock.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -4008,6 +4062,7 @@
|
|||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator": true,
|
||||
"screenshots": [{"url":"bangle1-choozi-screenshot1.png"},{"url":"bangle1-choozi-screenshot2.png"}],
|
||||
"storage": [
|
||||
{"name":"choozi.app.js","url":"app.js"},
|
||||
{"name":"choozi.img","url":"app-icon.js","evaluate":true}
|
||||
|
|
@ -4245,11 +4300,18 @@
|
|||
"id": "emojuino",
|
||||
"name": "Emojuino",
|
||||
"shortName": "Emojuino",
|
||||
"version": "0.01",
|
||||
"version": "0.02",
|
||||
"description": "Emojis & Espruino: broadcast Unicode emojis via Bluetooth Low Energy.",
|
||||
"icon": "emojuino.png",
|
||||
"screenshots": [
|
||||
{ "url": "screenshot-tx.png" },
|
||||
{ "url": "screenshot-swipe.png" },
|
||||
{ "url": "screenshot-welcome.png" }
|
||||
],
|
||||
"type": "app",
|
||||
"tags": "emoji",
|
||||
"supports" : [ "BANGLEJS2" ],
|
||||
"allow_emulator": true,
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{ "name": "emojuino.app.js", "url": "emojuino.js" },
|
||||
|
|
@ -4260,8 +4322,8 @@
|
|||
"id": "cliclockJS2Enhanced",
|
||||
"name": "Commandline-Clock JS2 Enhanced",
|
||||
"shortName": "CLI-Clock JS2",
|
||||
"version": "0.1",
|
||||
"description": "Simple CLI-Styled Clock with enhancements. Modes that are hard to use and unneded are removed (BPM, battery info, memory ect) credit to hughbarney for the original code and design",
|
||||
"version": "0.02",
|
||||
"description": "Simple CLI-Styled Clock with enhancements. Modes that are hard to use and unneded are removed (BPM, battery info, memory ect) credit to hughbarney for the original code and design. Also added HID media controlls, just swipe on the clock face to controll the media! Gadgetbride support coming soon(hopefully) Thanks to t0m1o1 for media controls!",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"screengrab.png"}],
|
||||
"type": "clock",
|
||||
|
|
@ -4293,7 +4355,7 @@
|
|||
"name": "LCARS Clock",
|
||||
"shortName":"LCARS",
|
||||
"icon": "lcars.png",
|
||||
"version":"0.02",
|
||||
"version":"0.05",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"description": "Library Computer Access Retrieval System (LCARS) clock.",
|
||||
"type": "clock",
|
||||
|
|
@ -4316,8 +4378,10 @@
|
|||
"description": "Famous binary watch",
|
||||
"tags": "clock",
|
||||
"type": "clock",
|
||||
"storage": [
|
||||
"storage": [
|
||||
{"name":"binwatch.app.js","url":"app.js"},
|
||||
{"name":"binwatch.bg176.img","url":"Background176_center.img"},
|
||||
{"name":"binwatch.bg240.img","url":"Background240_center.img"},
|
||||
{"name":"binwatch.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
|
|
@ -4353,5 +4417,37 @@
|
|||
{"name":"authentiwatch.img","url":"app-icon.js","evaluate":true}
|
||||
],
|
||||
"data": [{"name":"authentiwatch.json"}]
|
||||
},
|
||||
{ "id": "schoolCalendar",
|
||||
"name": "School Calendar",
|
||||
"shortName":"SCalendar",
|
||||
"icon": "CalenderLogo.png",
|
||||
"version": "0.01",
|
||||
"description": "A simple calendar that you can see your upcoming events that you create in the customizer. Keep in note that your events reapeat weekly.(Beta)",
|
||||
"tags": "tool",
|
||||
"readme":"README.md",
|
||||
"custom":"custom.html",
|
||||
"supports": ["BANGLEJS"],
|
||||
"screenshots": [{"url":"screenshot_basic.png"},{"url":"screenshot_info.png"}],
|
||||
"storage": [
|
||||
{"name":"schoolCalendar.app.js"},
|
||||
{"name":"schoolCalendar.img","url":"app-icon.js","evaluate":true}
|
||||
],
|
||||
"data": [
|
||||
{"name":"app.json"}
|
||||
]
|
||||
},
|
||||
{ "id": "timecal",
|
||||
"name": "TimeCal",
|
||||
"shortName":"TimeCal",
|
||||
"icon": "icon.png",
|
||||
"version":"0.01",
|
||||
"description": "TimeCal shows the Time along with a 3 week calendar",
|
||||
"tags": "clock",
|
||||
"type": "clock",
|
||||
"supports":["BANGLEJS2"],
|
||||
"storage": [
|
||||
{"name":"timecal.app.js","url":"timecal.app.js"}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 15 KiB |
|
|
@ -1 +1,4 @@
|
|||
0.01: New App!
|
||||
0.02: Remove messages on disconnect
|
||||
Fix music control
|
||||
0.03: Handling of message actions (ok/clear)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
/* TODO: Call handling, fitness */
|
||||
var HANDLERS = {
|
||||
// {t:"notify",id:int, src,title,subject,body,sender,tel:string} add
|
||||
"notify" : function() { event.t="add";require("messages").pushMessage(event); },
|
||||
"notify" : function() { Object.assign(event,{t:"add",positive:true, negative:true});require("messages").pushMessage(event); },
|
||||
// {t:"notify~",id:int, title:string} // modified
|
||||
"notify~" : function() { event.t="modify";require("messages").pushMessage(event); },
|
||||
// {t:"notify-",id:int} // remove
|
||||
|
|
@ -33,7 +33,16 @@
|
|||
// {t:"musicinfo", artist,album,track,dur,c(track count),n(track num}
|
||||
"musicinfo" : function() {
|
||||
require("messages").pushMessage(Object.assign(event, {t:"modify",id:"music",title:"Music"}));
|
||||
}
|
||||
},
|
||||
// {"t":"call","cmd":"incoming/end","name":"Bob","number":"12421312"})
|
||||
"call" : function() {
|
||||
Object.assign(event, {
|
||||
t:event.cmd=="incoming"?"add":"remove",
|
||||
id:"call", src:"Phone",
|
||||
positive:true, negative:true,
|
||||
title:event.name||"Call", body:"Incoming call\n"+event.number});
|
||||
require("messages").pushMessage(event);
|
||||
},
|
||||
};
|
||||
var h = HANDLERS[event.t];
|
||||
if (h) h(); else console.log("GB Unknown",event);
|
||||
|
|
@ -42,6 +51,7 @@
|
|||
// Battery monitor
|
||||
function sendBattery() { gbSend({ t: "status", bat: E.getBattery() }); }
|
||||
NRF.on("connect", () => setTimeout(sendBattery, 2000));
|
||||
NRF.on("disconnect", () => require("messages").clearAll()); // remove all messages on disconnect
|
||||
setInterval(sendBattery, 10*60*1000);
|
||||
// Health tracking
|
||||
Bangle.on('health', health=>{
|
||||
|
|
@ -50,6 +60,12 @@
|
|||
// Music control
|
||||
Bangle.musicControl = cmd => {
|
||||
// play/pause/next/previous/volumeup/volumedown
|
||||
gbSend({ t: "music", m:cmd });
|
||||
}
|
||||
gbSend({ t: "music", n:cmd });
|
||||
};
|
||||
// Message response
|
||||
Bangle.messageResponse = (msg,response) => {
|
||||
if (msg.id=="call") return gbSend({ t: "call", n:response?"ACCEPT":"REJECT" });
|
||||
if (isFinite(msg.id)) return gbSend({ t: "notify", n:response?"OPEN":"DISMISS" });
|
||||
// error/warn here?
|
||||
};
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -5,4 +5,5 @@
|
|||
0.05: Clock does not start if app Languages is not installed
|
||||
0.06: Improve accuracy
|
||||
0.07: Update to use Bangle.setUI instead of setWatch
|
||||
0.08: Use theme colors, Layout library
|
||||
0.08: Use theme colors, Layout library
|
||||
0.09: Fix time/date disappearing after fullscreen notification
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ function renderBar(l) {
|
|||
return;
|
||||
}
|
||||
const width = this.fraction*l.w;
|
||||
g.fillRect(l.x, l.y, width-1, l.y+l.height-1);
|
||||
g.fillRect(l.x, l.y, l.x+width-1, l.y+l.height-1);
|
||||
}
|
||||
|
||||
const Layout = require("Layout");
|
||||
|
|
@ -78,7 +78,7 @@ function dateText(date) {
|
|||
return `${dayName} ${dayMonth}`;
|
||||
}
|
||||
|
||||
draw = function draw() {
|
||||
draw = function draw(force) {
|
||||
if (!Bangle.isLCDOn()) {return;} // no drawing, also no new update scheduled
|
||||
const date = new Date();
|
||||
layout.time.label = timeText(date);
|
||||
|
|
@ -86,6 +86,10 @@ draw = function draw() {
|
|||
layout.date.label = dateText(date);
|
||||
const SECONDS_PER_MINUTE = 60;
|
||||
layout.bar.fraction = date.getSeconds()/SECONDS_PER_MINUTE;
|
||||
if (force) {
|
||||
Bangle.drawWidgets();
|
||||
layout.forgetLazyState();
|
||||
}
|
||||
layout.render();
|
||||
// schedule update at start of next second
|
||||
const millis = date.getMilliseconds();
|
||||
|
|
@ -96,7 +100,7 @@ draw = function draw() {
|
|||
Bangle.setUI("clock");
|
||||
Bangle.on("lcdPower", function(on) {
|
||||
if (on) {
|
||||
draw();
|
||||
draw(true);
|
||||
}
|
||||
});
|
||||
g.reset().clear();
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 4.6 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
Before Width: | Height: | Size: 6.3 KiB After Width: | Height: | Size: 6.2 KiB |
|
|
@ -1,3 +1,4 @@
|
|||
0.01: start of development
|
||||
0.02: first running version for BangleJs2
|
||||
0.03: corrected icon, added screen shot, extended description
|
||||
0.04: corrected format of background image (raw binary)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@
|
|||
require("Font7x11Numeric7Seg").add(Graphics);
|
||||
require("Font5x7Numeric7Seg").add(Graphics);
|
||||
|
||||
|
||||
/* constants and definitions */
|
||||
|
||||
/* Bangle 2: 176 x 176 */
|
||||
|
|
@ -63,7 +62,7 @@ const V2_BAT_SIZE_Y = 2;
|
|||
|
||||
const V2_SCREEN_SIZE_X = 176;
|
||||
const V2_SCREEN_SIZE_Y = 176;
|
||||
const V2_BACKGROUND_IMAGE = "Background176_center.png";
|
||||
const V2_BACKGROUND_IMAGE = "binwatch.bg176.img";
|
||||
const V2_BG_COLOR = 0;
|
||||
const V2_FG_COLOR = 1;
|
||||
|
||||
|
|
@ -91,7 +90,7 @@ const V1_BAT_SIZE_X = 3;
|
|||
const V1_BAT_SIZE_Y = 5;
|
||||
const V1_SCREEN_SIZE_X = 240;
|
||||
const V1_SCREEN_SIZE_Y = 240;
|
||||
const V1_BACKGROUND_IMAGE = "Background240_center.png";
|
||||
const V1_BACKGROUND_IMAGE = "binwatch.bg240.img";
|
||||
const V1_BG_COLOR = 1;
|
||||
const V1_FG_COLOR = 0;
|
||||
|
||||
|
|
@ -293,7 +292,7 @@ function setRuntimeValues(resolution) {
|
|||
bat_size_x = V1_BAT_SIZE_X;
|
||||
bat_size_y = V1_BAT_SIZE_Y;
|
||||
|
||||
setWatch(toggleDateTime, BTN1, { repeat : true, edge: "falling"});
|
||||
setWatch(toggleDateTime, BTN1, { repeat : true, edge: "falling"});
|
||||
|
||||
} else {
|
||||
x_step = V2_X_STEP;
|
||||
|
|
@ -362,8 +361,7 @@ function draw() {
|
|||
updateVTime();
|
||||
g.clear();
|
||||
g.drawImages([{image:cgimg},
|
||||
{image:require("Storage").read(backgroundImage)},
|
||||
// { x:bt_x, y:bt_y, rotate: 0, image:require("Storage").read("bt-icon.png")},
|
||||
{image:require("Storage").read(backgroundImage)}
|
||||
]);
|
||||
drawBT(g, NRF.getSecurityStatus().connected);
|
||||
// Bangle.drawWidgets();
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
|
@ -0,0 +1,2 @@
|
|||
0.01: Submitted to App Loader
|
||||
0.02: Removed unneded code, added HID controlls thanks to t0m1o1 for his code :p
|
||||
|
|
@ -4,24 +4,96 @@ var fontsizeTime = g.getWidth()>200 ? 4 : 4;
|
|||
var fontheight = 10*fontsize;
|
||||
var fontheightTime = 10*fontsizeTime;
|
||||
var locale = require("locale");
|
||||
var marginTop = 40;
|
||||
var marginTop = 25;
|
||||
var flag = false;
|
||||
|
||||
var hrtOn = false;
|
||||
var hrtStr = "Hrt: ??? bpm";
|
||||
var storage = require('Storage');
|
||||
|
||||
const NONE_MODE = "none";
|
||||
const ID_MODE = "id";
|
||||
const VER_MODE = "ver";
|
||||
const BATT_MODE = "batt";
|
||||
const MEM_MODE = "mem";
|
||||
const STEPS_MODE = "step";
|
||||
const HRT_MODE = "hrt";
|
||||
const NONE_FN_MODE = "no_fn";
|
||||
const HRT_FN_MODE = "fn_hrt";
|
||||
const settings = storage.readJSON('setting.json',1) || { HID: false };
|
||||
|
||||
var sendHid, next, prev, toggle, up, down, profile;
|
||||
var lasty = 0;
|
||||
var lastx = 0;
|
||||
|
||||
if (settings.HID=="kbmedia") {
|
||||
profile = 'Music';
|
||||
sendHid = function (code, cb) {
|
||||
try {
|
||||
NRF.sendHIDReport([1,code], () => {
|
||||
NRF.sendHIDReport([1,0], () => {
|
||||
if (cb) cb();
|
||||
});
|
||||
});
|
||||
} catch(e) {
|
||||
print(e);
|
||||
}
|
||||
};
|
||||
next = function (cb) { sendHid(0x01, cb); };
|
||||
prev = function (cb) { sendHid(0x02, cb); };
|
||||
toggle = function (cb) { sendHid(0x10, cb); };
|
||||
up = function (cb) {sendHid(0x40, cb); };
|
||||
down = function (cb) { sendHid(0x80, cb); };
|
||||
} else {
|
||||
E.showPrompt("Enable HID?",{title:"HID disabled"}).then(function(enable) {
|
||||
if (enable) {
|
||||
settings.HID = "kbmedia";
|
||||
require("Storage").write('setting.json', settings);
|
||||
setTimeout(load, 1000, "hidmsicswipe.app.js");
|
||||
} else setTimeout(load, 1000);
|
||||
});
|
||||
}
|
||||
|
||||
if (next) {
|
||||
setWatch(function(e) {
|
||||
var len = e.time - e.lastTime;
|
||||
E.showMessage('lock');
|
||||
setTimeout(drawApp, 1000);
|
||||
Bangle.setLocked(true);
|
||||
}, BTN1, { edge:"falling",repeat:true,debounce:50});
|
||||
Bangle.on('drag', function(e) {
|
||||
if(!e.b){
|
||||
console.log(lasty);
|
||||
console.log(lastx);
|
||||
if(lasty > 40){
|
||||
writeLine('Down', 3);
|
||||
// setTimeout(drawApp, 1000);
|
||||
// Bluetooth.println(JSON.stringify({t:"music", n:"volumedown"}));
|
||||
down(() => {});
|
||||
}
|
||||
else if(lasty < -40){
|
||||
writeLine('Up', 3);
|
||||
// setTimeout(drawApp, 1000);
|
||||
//Bluetooth.println(JSON.stringify({t:"music", n:"volumeup"}));
|
||||
|
||||
up(() => {});
|
||||
} else if(lastx < -40){
|
||||
writeLine('Prev', 3);
|
||||
// setTimeout(drawApp, 1000);
|
||||
// Bluetooth.println(JSON.stringify({t:"music", n:"previous"}));
|
||||
prev(() => {});
|
||||
} else if(lastx > 40){
|
||||
writeLine('Next', 3);
|
||||
// setTimeout(drawApp, 1000);
|
||||
// Bluetooth.println(JSON.stringify({t:"music", n:"next"}));
|
||||
next(() => {});
|
||||
} else if(lastx==0 && lasty==0){
|
||||
writeLine('play/pause', 3);
|
||||
//setTimeout(drawApp, 1000);
|
||||
// Bluetooth.println(JSON.stringify({t:"music", n:"play"}));
|
||||
|
||||
toggle(() => {});
|
||||
}
|
||||
lastx = 0;
|
||||
lasty = 0;
|
||||
}
|
||||
else{
|
||||
lastx = lastx + e.dx;
|
||||
lasty = lasty + e.dy;
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
let infoMode = NONE_MODE;
|
||||
let functionMode = NONE_FN_MODE;
|
||||
|
||||
let textCol = g.theme.dark ? "#0f0" : "#080";
|
||||
|
||||
|
|
@ -33,13 +105,12 @@ function drawAll(){
|
|||
function updateRest(now){
|
||||
writeLine(locale.dow(now),1);
|
||||
writeLine(locale.date(now,1),2);
|
||||
drawInfo(5);
|
||||
}
|
||||
function updateTime(){
|
||||
if (!Bangle.isLCDOn()) return;
|
||||
let now = new Date();
|
||||
writeLine(locale.time(now,1),0);
|
||||
writeLine(flag?" ":"_",3);
|
||||
writeLine(flag?" ":"_ ",3);
|
||||
flag = !flag;
|
||||
if(now.getMinutes() == 0)
|
||||
updateRest(now);
|
||||
|
|
@ -65,142 +136,13 @@ function writeLine(str,line){
|
|||
var y = marginTop+(line-1)*fontheight+fontheightTime;
|
||||
g.setFont("6x8",fontsize);
|
||||
g.setColor(textCol).setFontAlign(-1,-1);
|
||||
g.clearRect(0,y,((str.length+1)*20),y+fontheight-1);
|
||||
g.clearRect(0,y,((str.length+10)*40),y+fontheightTime-1);
|
||||
writeLineStart(line);
|
||||
g.drawString(str,25,y);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function drawInfo(line) {
|
||||
let val;
|
||||
let str = "";
|
||||
let col = textCol; // green
|
||||
|
||||
//console.log("drawInfo(), infoMode=" + infoMode + " funcMode=" + functionMode);
|
||||
|
||||
switch(functionMode) {
|
||||
case NONE_FN_MODE:
|
||||
break;
|
||||
case HRT_FN_MODE:
|
||||
col = g.theme.dark ? "#0ff": "#088"; // cyan
|
||||
str = "HRM: " + (hrtOn ? "ON" : "OFF");
|
||||
drawModeLine(line,str,col);
|
||||
return;
|
||||
}
|
||||
|
||||
switch(infoMode) {
|
||||
case NONE_MODE:
|
||||
col = g.theme.bg;
|
||||
str = "";
|
||||
break;
|
||||
case HRT_MODE:
|
||||
str = hrtStr;
|
||||
break;
|
||||
case STEPS_MODE:
|
||||
str = "Steps: " + stepsWidget().getSteps();
|
||||
break;
|
||||
case ID_MODE:
|
||||
val = NRF.getAddress().split(":");
|
||||
str = "Id: " + val[4] + val[5];
|
||||
break;
|
||||
case VER_MODE:
|
||||
str = "Fw: " + process.env.VERSION;
|
||||
break;
|
||||
case MEM_MODE:
|
||||
val = process.memory();
|
||||
str = "Memory: " + Math.round(val.usage*100/val.total) + "%";
|
||||
break;
|
||||
case BATT_MODE:
|
||||
default:
|
||||
str = "Battery: " + E.getBattery() + "%";
|
||||
}
|
||||
|
||||
drawModeLine(line,str,col);
|
||||
}
|
||||
|
||||
function drawModeLine(line, str, col) {
|
||||
g.setColor(col);
|
||||
var y = marginTop+line*fontheight;
|
||||
g.fillRect(0, y, 239, y+fontheight-1);
|
||||
g.setColor(g.theme.bg).setFontAlign(0, 0);
|
||||
g.drawString(str, g.getWidth()/2, y+fontheight/2);
|
||||
}
|
||||
|
||||
function changeInfoMode() {
|
||||
switch(functionMode) {
|
||||
case NONE_FN_MODE:
|
||||
break;
|
||||
case HRT_FN_MODE:
|
||||
hrtOn = !hrtOn;
|
||||
Bangle.buzz();
|
||||
Bangle.setHRMPower(hrtOn ? 1 : 0);
|
||||
if (hrtOn) infoMode = HRT_MODE;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(infoMode) {
|
||||
case NONE_MODE:
|
||||
if (stepsWidget() !== undefined)
|
||||
infoMode = hrtOn ? HRT_MODE : STEPS_MODE;
|
||||
else
|
||||
infoMode = VER_MODE;
|
||||
break;
|
||||
case HRT_MODE:
|
||||
if (stepsWidget() !== undefined)
|
||||
infoMode = STEPS_MODE;
|
||||
else
|
||||
infoMode = VER_MODE;
|
||||
break;
|
||||
case STEPS_MODE:
|
||||
infoMode = ID_MODE;
|
||||
break;
|
||||
case ID_MODE:
|
||||
infoMode = VER_MODE;
|
||||
break;
|
||||
case VER_MODE:
|
||||
infoMode = BATT_MODE;
|
||||
break;
|
||||
case BATT_MODE:
|
||||
infoMode = MEM_MODE;
|
||||
break;
|
||||
case MEM_MODE:
|
||||
default:
|
||||
infoMode = NONE_MODE;
|
||||
}
|
||||
}
|
||||
|
||||
function changeFunctionMode() {
|
||||
//console.log("changeFunctionMode()");
|
||||
switch(functionMode) {
|
||||
case NONE_FN_MODE:
|
||||
functionMode = HRT_FN_MODE;
|
||||
break;
|
||||
case HRT_FN_MODE:
|
||||
default:
|
||||
functionMode = NONE_FN_MODE;
|
||||
}
|
||||
//console.log(functionMode);
|
||||
|
||||
}
|
||||
|
||||
function stepsWidget() {
|
||||
if (WIDGETS.activepedom !== undefined) {
|
||||
return WIDGETS.activepedom;
|
||||
} else if (WIDGETS.wpedom !== undefined) {
|
||||
return WIDGETS.wpedom;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
Bangle.on('HRM', function(hrm) {
|
||||
if(hrm.confidence > 90){
|
||||
hrtStr = "Hrt: " + hrm.bpm + " bpm";
|
||||
} else {
|
||||
hrtStr = "Hrt: ??? bpm";
|
||||
}
|
||||
});
|
||||
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
|
@ -211,6 +153,5 @@ Bangle.on('lcdPower',function(on) {
|
|||
var click = setInterval(updateTime, 1000);
|
||||
// Show launcher when button pressed
|
||||
Bangle.setUI("clockupdown", btn=>{
|
||||
if (btn<0) changeInfoMode();
|
||||
drawAll();
|
||||
});
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 3.1 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 2.1 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 2.4 KiB |
|
After Width: | Height: | Size: 9.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 3.7 KiB |
|
After Width: | Height: | Size: 3.5 KiB |
|
After Width: | Height: | Size: 3.0 KiB |
|
|
@ -1 +1,2 @@
|
|||
0.01: New App!
|
||||
0.02: Upgraded text to images, added welcome screen and subtitles.
|
||||
|
|
|
|||
|
|
@ -4,29 +4,48 @@
|
|||
*/
|
||||
|
||||
|
||||
// Emojis are integer pairs with the form [ image, Unicode code point ]
|
||||
// Emoji images are 96px x 96px, 4bpp (https://www.espruino.com/Image+Converter)
|
||||
// and adapted from Font Awesome 5
|
||||
const GRIN = "sFgwkBiIATDwoaUFi4ynQZ4uuGDzlTF1wwaFyowYFy4wWiAvZgIutGCgubSKRecMCQudMCBeeMCAufMBxegMBwuhMBheiMBgujMBRekMBQvvF0qQIL0xgIF94unSA4vuR1CQGF94upSAovuR1SQEF94urSAY/PCBivQF5z/DEBQ+DEB5ePCJYOEMBgNNF8MBHpogNHwqBNF/4vsEAovOX7TviBhYgFD5Q/EEJoANEAY/OLxgAQPx5edAH4A/AH4A/AH4A/AEUQF1sBF/4v/F/4vviILJBRQANEZYLJHQIMKFpYABQhIiKC4QaMIhBHLF6AAVEhRQIF8ZuCF5B6GACYjMF9ZrOF8jAiKRgvvSEJROBo5gYEBw+IMCwfPB5BgWDxBPHCCBeVJxBgdJqIvJMCQcTCRAwRFxJ8KChQwODKwVJGBouKbZgXLDBQVLPBoZLDYxDMLxocQACLXOMBwARFxxgfLx5gfFyBgdLyIwcFyaRbFygwZFywwXFzAwVFzQwTFzgwRFzwxOFsIyKDSg";
|
||||
const MEH = "sFgwkBiIATDwoaUFi4ynQZ4uuGDzlTF1wwaFyowYFy4wWiAvZgIutGCgubSKRecMCQudMCBeeMCAufMBxegMBwuhMBheiMBgujMBRekMBQvvF0qQIL0xgIF94unSA4vuR1CQGF94upSAovuR1SQEF94urSAY/PCBivQF5z/DEBQ+DEB5ePCJYOEMBgNNF8MBHpogNHwqBNF/4vsEAovOX7TviBhYgFD5Q/EEJoANEAY/OLxgAQPx5edAH4A/AH4A/AH4A/AEUQF1sBF/4v/F/4vviIvtiIv/F9qeBACDgNB5ouSECAOLFyaBMKAYvrByQvgSBS/fD4jAfXxwQMADxAQF8iQLADjeGF96QoFwxgnLw4vwSEwuIMEpeJMEouKMEZeLMEYuMMEJeNMEIuOMD5ePMD4uQMDpeRGDguTSLYuUGDIuWGC4uYGCouaGCYucGCIueGJwthGRQaUA";
|
||||
const FROWN = "sFgwkBiIATDwoaUFi4ynQZ4uuGDzlTF1wwaFyowYFy4wWiAvZgIutGCgubSKRecMCQudMCBeeMCAufMBxegMBwuhMBheiMBgujMBRekMBQvvF0qQIL0xgIF94unSA4vuR1CQGF94upSAovuR1SQEF94urSAY/PCBivQF5z/DEBQ+DEB5ePCJYOEMBgNNF8MBHpogNHwqBNF/4vsEAovOX7TviBhYgFD5Q/EEJoANEAY/OLxgAQPx5edAH4A/AH4A/AH4A/AEUQF1sBF/4v/F/4vUgMRAAQZWFqwxWCgIuZGCYvSFxIcUFzYdTOZyNKSKQdCCJwuNMB5NDLzZOPIKAviCJguPJxpNEF94RLRyBONIKAvHNRQvRCKAMUJpIvOZxx9WAEbSTADReHF+CQmFxBglLxJglFxRgjLxZgjFxhghLxpghFxxgfLx5gfFyBgdLyIwcFyaRbFygwZFywwXFzAwVFzQwTFzgwRFzwxOFsIyKDSg";
|
||||
const THUMBS_UP = "sFgwkBiIAaiAiBDzYAQKYZQcLyAwsF4qSpcoxgoF4xgnRwwvxSEwvvFw4vwYEwv/F/4AOiAv/R1Av/F/6+PgIv/RzwvjLxQvkFxTujLxYvjFxaOiLxgvvR1wviR3gviR3YviFxg6iF7AwVRxowhFzUAgIvuMCSObF6YucSCJedF6IudSARQIHQheeAAIgKGAYufF+CbMF/4v/WYQv/F/6yPF/6OeF9wgNL/4v/F/4vhEQIv/R/4v/F/7ueF/4v/Xx4v/F/4v/F/4v/F/4v/F7ogOF/6OSEAgHCiAvrAwQHHRz4v/F/4v/F58QF8cBE4wPDGLYvHB5aTaKwQvUMS4vYGCx8QF5AwULwgvWYiZJQIAowXDowvYGJyqRFx4bKDRQA==";
|
||||
const THUMBS_DOWN = "sFgwkBiIAbiAoGEroAHLZgttMcK9RXEZgmFyZgHDZA/JFyogFDZQwHFqovXLiyQHB5wtaF6gubF/4v/F/4vwgIv/F7wgPF/6QTF/4v/F/4v/F/4v/F/4AdF/4v/YCIv/F/4v9EQIv/R/4v/F/7ueL+gFBiMQF8oiBE4wHHF/6QQF/4v/YigvugInBiAvrM5QvvM4gvqMFgvDMD0BF55gegJPKgIvEMDoeLF4pgdJ5QuGF7gjHABaQbFyRgbFygvZFyqQOEixgYF8RgMgIv/SH5gPYH6QfF8aQvMBgvjMBaQjMBYvkMBQv/SEAv/F/7APF/6QfF/4v/F/0BF8sQF/4vnF0rAJF9yOmSBAunF4xeoSAouqMAYTQA==";
|
||||
const HEART = "sFgwkBiIA/AH4A/AH4AogAADC1EQC4gaQCo8BIqYwRCyxdJDJoVLMJYuMGBIVNGBQYNDI5FOO5IXODI4WWI6BgGCywYTDIYVVO6gvXSAoYTDIQVTMAgYTDIJFUMAgYUACyOXAC7XWF7YurSAYvuR1iQCF/4v/F54utAH4A/AH4A/AH4A/AGMQF1sBF/4v/F58RF9sRF/4vgYFi+BMFouCF+CQqRwYvwSFQuEMFJeFMFIuGME5eHME4uIMEpeJMEouKMEZeLMEYuMMEJeNMEIuOMD5ePMD4uQMDpeRMDouSMDZeTMDYuUMDJeVMDIuWMC5eXMC4uYMCpeZMCouaMCZebMCYucMCJedF+CQQFzxgPFz5gPF8JgMXr5gPF0RgLL0ZgLF0hgJL0pgJF0xgHL05gHF1BgFL1JgFF1QwDF1gA/AH4A/AH4AJA=";
|
||||
const TX = "k8XwkBiIAYEYogLHBAUIiBNKGxooKEggvJCYYHDKxAMFAoRrOCRAsHCYqbNHQibLKAauOLBCJHQw6JMQBIJBRJDWJThK5JJJi5KbpaJKFBaKEE5ybGHRhcOACEQA";
|
||||
|
||||
|
||||
// Emojis are pairs with the form [ Image String, Unicode code point ]
|
||||
// For code points see https://unicode.org/emoji/charts/emoji-list.html
|
||||
const EMOJIS = [
|
||||
[ ':)', 0x1f642 ], // Slightly smiling
|
||||
[ ':|', 0x1f610 ], // Neutral
|
||||
[ ':(', 0x1f641 ], // Slightly frowning
|
||||
[ '+1', 0x1f44d ], // Thumbs up
|
||||
[ '-1', 0x1f44e ], // Thumbs down
|
||||
[ '<3', 0x02764 ], // Heart
|
||||
[ GRIN, 0x1f642 ], // Slightly smiling
|
||||
[ MEH, 0x1f610 ], // Neutral
|
||||
[ FROWN, 0x1f641 ], // Slightly frowning
|
||||
[ THUMBS_UP, 0x1f44d ], // Thumbs up
|
||||
[ THUMBS_DOWN, 0x1f44e ], // Thumbs down
|
||||
[ HEART, 0x02764 ], // Heart
|
||||
];
|
||||
const EMOJI_TRANSMISSION_MILLISECONDS = 5000;
|
||||
const BLINK_PERIOD_MILLISECONDS = 500;
|
||||
const TRANSMIT_BUZZ_MILLISECONDS = 200;
|
||||
const CYCLE_BUZZ_MILLISECONDS = 50;
|
||||
const WELCOME_MESSAGE = 'Emojuino:\r\n\r\n< Swipe >\r\nto select\r\n\r\nTap\r\nto transmit';
|
||||
|
||||
// Non-user-configurable constants
|
||||
const IMAGE_INDEX = 0;
|
||||
const CODE_POINT_INDEX = 1;
|
||||
const EMOJI_PX = 96;
|
||||
const EMOJI_X = (g.getWidth() - EMOJI_PX) / 2;
|
||||
const EMOJI_Y = (g.getHeight() - EMOJI_PX) / 2;
|
||||
const TX_X = 68;
|
||||
const TX_Y = 12;
|
||||
const FONT_SIZE = 24;
|
||||
const BTN_WATCH_OPTIONS = { repeat: true, debounce: 20, edge: "falling" };
|
||||
const UNICODE_CODE_POINT_ELIDED_UUID = [ 0x49, 0x6f, 0x49, 0x44, 0x55,
|
||||
0x54, 0x46, 0x2d, 0x33, 0x32 ];
|
||||
|
||||
|
||||
|
||||
// Global variables
|
||||
let emojiIndex = 0;
|
||||
let isToggleOn = false;
|
||||
|
|
@ -72,6 +91,7 @@ function transmitEmoji(image, codePoint, duration) {
|
|||
require('ble_eddystone_uid').advertise(UNICODE_CODE_POINT_ELIDED_UUID,
|
||||
instance);
|
||||
isTransmitting = true;
|
||||
drawImage(EMOJIS[emojiIndex][IMAGE_INDEX], true);
|
||||
|
||||
let displayIntervalId = setInterval(toggleImage, BLINK_PERIOD_MILLISECONDS,
|
||||
image);
|
||||
|
|
@ -85,14 +105,14 @@ function terminateEmoji(displayIntervalId) {
|
|||
NRF.setAdvertising({ });
|
||||
isTransmitting = false;
|
||||
clearInterval(displayIntervalId);
|
||||
drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]);
|
||||
drawImage(EMOJIS[emojiIndex][IMAGE_INDEX], false);
|
||||
}
|
||||
|
||||
|
||||
// Toggle the display between image/off
|
||||
function toggleImage(image) {
|
||||
if(isToggleOn) {
|
||||
drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]);
|
||||
drawImage(EMOJIS[emojiIndex][IMAGE_INDEX], true);
|
||||
}
|
||||
else {
|
||||
g.clear();
|
||||
|
|
@ -102,9 +122,15 @@ function toggleImage(image) {
|
|||
|
||||
|
||||
// Draw the given emoji
|
||||
function drawImage(image) {
|
||||
function drawImage(image, isTx) {
|
||||
g.clear();
|
||||
g.drawString(image, g.getWidth() / 2, g.getHeight() / 2);
|
||||
g.drawImage(require("heatshrink").decompress(atob(image)), EMOJI_X, EMOJI_Y);
|
||||
if(isTx) {
|
||||
g.drawImage(require("heatshrink").decompress(atob(TX)), TX_X, TX_Y);
|
||||
}
|
||||
else {
|
||||
g.drawString("< Swipe >", g.getWidth() / 2, g.getHeight() - FONT_SIZE);
|
||||
}
|
||||
g.flip();
|
||||
}
|
||||
|
||||
|
|
@ -131,15 +157,15 @@ function handleDrag(event) {
|
|||
// Special function to handle display switch on
|
||||
Bangle.on('lcdPower', (on) => {
|
||||
if(on) {
|
||||
drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]);
|
||||
drawImage(EMOJIS[emojiIndex][IMAGE_INDEX], false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// On start: display the first emoji and handle drag and touch events
|
||||
g.clear();
|
||||
g.setFont('Vector', 80);
|
||||
g.setFont('Vector', FONT_SIZE);
|
||||
g.setFontAlign(0, 0);
|
||||
drawImage(EMOJIS[emojiIndex][IMAGE_INDEX]);
|
||||
g.drawString(WELCOME_MESSAGE, g.getWidth() / 2, g.getHeight() / 2);
|
||||
Bangle.on('touch', handleTouch);
|
||||
Bangle.on('drag', handleDrag);
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.6 KiB |
|
|
@ -1 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwghC/AEkIxAABwUiAAwKBC6+AC6ERiIXDGBAXPGA8JzIAByQXKGA4XUA4eDmYAGJwQXVxEizAXPIgIXDwWZC6uIxIwCC6eIGAQX/C9i/FC5mCCw0yC5wAMC/4Xnx//ABf4C/Xzdw8zn4XkL/5f/L+oUDI6YX3AB4XeAH4AdA=="))
|
||||
require("heatshrink").decompress(atob("mEw4cA///7c0AYMXlm3gf42s1yvb5xT/ABdJkmStu27YCCtMkCKOACJdm7YRCyARQyQRLBwIRDoARTgVLtu3K4tJl4RQkvpCJdbtwRBkm5CKGZCKGTCKGSsgR/R4gRHpIMBCInaCJIIBARAR/CJtPB5FLCI1KEhMSCLN//4AE/QRbI/5H/CI4PCGpwRXp4RIpZFDCIQiJAQIRWAH4AGA"))
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@
|
|||
0.04: Setting to disable touch controls, minor bugfix
|
||||
0.05: Setting to disable double/triple press control, remove touch controls setting, reduce fadeout flicker
|
||||
0.06: Bangle.js 2 support
|
||||
0.07: Fix "previous" button image
|
||||
|
|
|
|||
|
|
@ -303,7 +303,7 @@ function drawControls() {
|
|||
l.up.col = cc("volumeup" in tCommand);
|
||||
l.down.col = cc("volumedown" in tCommand);
|
||||
}
|
||||
l.prev.icon = (stat==="play") ? "pause" : "prev";
|
||||
l.prev.icon = (stat==="play") ? "pause" : "previous";
|
||||
l.prev.col = cc("prev" in tCommand || "pause" in tCommand);
|
||||
l.next.icon = (stat==="play") ? "next" : "play";
|
||||
l.next.col = cc("next" in tCommand || "play" in tCommand);
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 2.3 KiB |
|
|
@ -26,3 +26,4 @@
|
|||
0.22: Ensure Bangle.setGPSPower uses 'gpsrec' as a tag
|
||||
0.23: Fix issue where tracks wouldn't record when running from OpenStMap if a period hadn't been set up first
|
||||
0.24: Better support for Bangle.js 2, avoid widget area for Graphs, smooth graphs more
|
||||
0.25: Fix issue where if Bangle.js 2 got a GPS fix but no reported time, errors could be caused by the widget (fix #935)
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@
|
|||
fixToggle = !fixToggle;
|
||||
WIDGETS["gpsrec"].draw();
|
||||
if (hasFix) {
|
||||
if (fix.time===undefined) fix.time = new Date(); // Bangle.js 2 can provide a fix before time it seems
|
||||
var period = fix.time.getTime() - lastFixTime;
|
||||
if (period+500 > settings.period*1000) { // round up
|
||||
lastFixTime = fix.time.getTime();
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 5.2 KiB |
|
|
@ -1 +1,3 @@
|
|||
0.01: New App!
|
||||
0.02: Remove messages on disconnect
|
||||
0.03: Handling of message actions (ok/clear)
|
||||
|
|
|
|||
|
|
@ -95,7 +95,14 @@ E.on('AMS',a=>{
|
|||
Bangle.musicControl = cmd => {
|
||||
// play, pause, playpause, next, prev, volup, voldown, repeat, shuffle, skipforward, skipback, like, dislike, bookmark
|
||||
NRF.amsCommand(cmd);
|
||||
}
|
||||
};
|
||||
// Message response
|
||||
Bangle.messageResponse = (msg,response) => {
|
||||
if (isFinite(msg.id)) return NRF.sendANCSAction(msg.id, response);//true/false
|
||||
// error/warn here?
|
||||
};
|
||||
// remove all messages on disconnect
|
||||
NRF.on("disconnect", () => require("messages").clearAll());
|
||||
|
||||
/*
|
||||
// For testing...
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
|
@ -1,2 +1,5 @@
|
|||
0.01: Launch app
|
||||
0.01: Launch app.
|
||||
0.02: Swipe left/right to set an alarm.
|
||||
0.03: New design with different icons if gps, hrm or compass is on.
|
||||
0.04: Inluded LCARS Logo.
|
||||
0.05: Additional icons for (1) charging and (2) bat < 30%.
|
||||
|
|
@ -11,6 +11,9 @@ the [Pedometer widget](https://banglejs.com/apps/#pedometer%20widget).
|
|||
* Shows the number of daily steps
|
||||
* Swipe left/right to activate an alarm
|
||||
|
||||
## Icons
|
||||
<div>Icons made by <a href="https://www.flaticon.com/authors/smashicons" title="Smashicons">Smashicons</a>, <a href="https://www.freepik.com" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a></div>
|
||||
|
||||
|
||||
## Creator
|
||||
Made by [David Peer](https://github.com/peerdavid)
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 9.2 KiB |
|
|
@ -3,11 +3,48 @@
|
|||
*/
|
||||
const locale = require('locale');
|
||||
var alarm = -1;
|
||||
var hrmValue = "-";
|
||||
|
||||
var img = {
|
||||
var backgroundImage = {
|
||||
width : 176, height : 151, bpp : 3,
|
||||
transparent : 0,
|
||||
buffer : require("heatshrink").decompress(atob("gF58+eAR14IN1fvv374CN7yD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/AH4A/AH4A/AB1z588+YCN+RBuj158+eARyD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf4AUhyD/gEDQaHz4BCuQaNAIN0PQaHIIN0BQaF5IN0AQaHPkBBug6DQ8iEvQaE8yBBuhyDPAQNAINsBQaACBkhCuQaACpVo0cQaACo4CFGjyD/AAMPQf4ACQf4ADgiD+AH4A/AH8J02atICIwEAgPnz15AR3gEgM27dt2wCTF4IABgYROgN9+/fAR14ILsaQBKDakwjKF5oABKZ6DwgxTPQeEmQf5cPQeMBLhyDxgJTRQd0JKaKDuhKD/gENQf6D/F4VNQf8AKaKDvKBYnBAGZQKzBB1QZOwIGqDJsBA2QZJA3QZGYIPCDH4CD/0xA4QY+wIPKDGwCD/tpB6Qf6DHthA5QY1oIPSD/QY9gQf/bIPaD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/AF8JQYgCdsEHnnz54CJgIdLwEAhqDEATtggPnz15ARHkgIdLIIKAgQcCAgQcAA/gAA=="))
|
||||
transparent : 2,
|
||||
buffer : require("heatshrink").decompress(atob("AAdx48cATojCufPnnzASocCyVJkgCdyAkCh158+eASsAgMHQDyDggKAeQcKAgQYodZgRoFpAkCAG0QJQtwIPMSQYtAIPLOGQfSADAQRA5Qf6D6g/gQf8H/iD/n//wCD9gP/Qf5BBQf5BC+CD9h5BB/yD8jl/IIPx46D6g4/BQYU//+AQe8B/6DD//Hj/x4CD2v/4AQJBC4ED/4IBQegvBPQJBERgSD1j/wgB9BAASACn/gQepECIIaACg/8QeY1DQYjCD/+AQeUHQZSPDwUIkACDQdT7DIJEfQYIAxg44DIJHwIOU/fwYAERgUDIOUBPQhBE/hB1QZRBFjlx44CDuBBpg4CCHwdxIIcfIIPnz15AQeAQdT+CIIXgZwJBDHAM8+fPAQbOqQY0AIIkcAQKDxg44BIIX4RgX/GoICCQeR3BIIXARIfwJoSDyfYI4B//+BAaABn/gAoKDxfYNx459BJQnx/4FCQeUAv7EBIIv//AFCQeUAgPH/lwAwUHQYPAQe0An6EBAAfj/wMDQeZ9B/jIC//HgCJDQe3gAYICCgF+Qe8B/4IGIIiD0nAHGhyD3ABqD0ABiD/Qf4ADjiD/gEnQYuQQf6D7gaDFzxB5gFzQYnz4JB5hyDFATfkEwUN23btoCVgEBQYoCcIIRhZDYMJQf4ABjiD/AH4A/AH4AGiFx48cATokCufPnnzASocCyVJkgCdyAkCj158+eASsAgKAfQcEJQDyDhNA8QoMEAQIqCACweEASkCNAtIHbIAfdI1wIPMSQYtAQf6D7QAYCCIHKD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/AH4A/AH4A/AH4Asjlx44CDsBB57dt2wCDQfWevPnAQaD/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf4Akjlx44CDQfQA/AH4A/AH4A/ABM8+fPAQfwIPPnz15AQeAQf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf6D/Qf4AZjiD/gEHQYuQQf6D7gaDFzxB5gFzQYnz48cuICZEwQdZgECQYoCb8hBChMkyVJASsAgPHQYgCcQboABQf4ABfzACIQbg="))
|
||||
}
|
||||
|
||||
var iconPlanet = {
|
||||
width : 50, height : 50, bpp : 3,
|
||||
transparent : 5,
|
||||
buffer : require("heatshrink").decompress(atob("23btoCD6PHjlx9oLGAQuGiVJkmSpIRK2lxEYQCDCJOGjEhEYNBwUI5drEw/xEYwCB8oRGDoMhwmSsAFBkGM237NZICGj15OgnaDoOGI4cgwUa5dv332EwdHEZACB8+evYRCtAdBEAQpDscs3379+9HAW8EZPHz158+WSQQjFwUYsMs2QjBEwPrSRZuCJQN5TAJuCEYkhwUS5cvJQRxCNxZKDOIXgJQkh0mYtMk2XLJQXv1u0EZSVDOIWsJQsSpMkyVJljgB9gmB7YjLOgtq4BKEsIjCAQNLlgCBt+9EZwCCj8sJQpxB00aJoYCB5cBEZ4CB+RKFJoeGjAjCoOGzBKaAQeGJQQFBwJKSsAjIcweSBwRKRjojKOgYFCxZKRtAaBjHrlm4FJUN3hKQi3ShAjB2XLAQQmI7dHJR97tsh9gjEAQLpHlu2+PnExvF23an3794mF2BKFm3btsevImMjwRB23v3wmB3xNF5BuDCIPb8+eEwOeExIRCtojCJo5uEEwRxBEwRuJHAdI+YmCTYlgJQIREtrjCEwLdHCIiYBhF7OgnJSQgmFjhxCOgiSDAQvSX4QmB90IkQRIX4gmCEZICDvwmCBY3QA"))
|
||||
}
|
||||
|
||||
var iconGps = {
|
||||
width : 50, height : 50, bpp : 3,
|
||||
transparent : 2,
|
||||
buffer : require("heatshrink").decompress(atob("pMkyQCFpH0BAwCJv/6CJ8l589CJ0kyf//wIDpVEChM8+/fBAdZ8QRIp++///0gIBlMkxI4IuZKB+/SKAPHzpKJ/YkB//pKAP2BYeXhIFDx88+fPvqYBnibEkmUAofv34lC/RQBBYdcmPCXIYjBEwPfvnzJoILBQoUlHAUuJQYmCDodw48cuBKGTA0WEYIEBJQ6YEQwMMuImBJQyYEkmZFAVkyVSJQ6YCyUcmPDjgmBTAJKETAlJiS4ETANPJQpxCJQtxTALgBEwnfvohBI4NZkmWpNlcAgAD/wzBEYaYCy8cJQiYEyIjCTAWS3wlGTAVIEwkerJKFTAkmOIclToK8GAAIPBIgImCufHyxxG59pEIS8DvfypMr968HEwOHEwfx8+cEYkpCIeSoiYByVf/uSkmTEQP7ZIiYDnl5AQNwBYgCGyOn38k2+2pIRKyVeuPPj1x4ccCJVKSgP/5cJA4NSExMps+cSoMMKAIVCCg7SBpd7TANZkmUHBMevPnjlwcwXCCJFEzYDBA4WWKIIRHpEw4+eNwUxEwKYIkVJk1IyIKFHA+DR4VcJQYCBJRBoCkxHBAgNkyyYKkmXEYaYMAQMSEYKYNAQOHEwnSfBYjBAgVaCJdJJSMkTAK8KYQyVKAQ4jBNxiYEcBCYJXIkgA="))
|
||||
}
|
||||
|
||||
var iconCompass = {
|
||||
width : 50, height : 50, bpp : 3,
|
||||
transparent : 2,
|
||||
buffer : require("heatshrink").decompress(atob("pMkyQCDl//AAPSBYwCFv4RCAAOkCJNLCAgACCJm2rNn34FB+g1Jvny5cs2XPn///QRI9uWEYP2rNly5NHNYN82YjB/4mC5YmBOgkl//9y1bsuW/4CB/Nlz//9I4D3/8I4M8EAICB55NCL4g/BIgRKBAQtnL4lf+QdCI4YCD2Y4DSQPZtojHsuerI4Dv/flnzEZB3CHAJuB8ojIAQY4CNwJHI2XHTAY4B/4gJrGBAoSqBpf2EZMQmRxEv/5Nw9YyVCAoO+rf/0v/Nw/PjFB4ZxCn/+y7dBJQyNBkAIDz/6/7dBJQsYsMEhgsE//+7IjFsTYBwAIE/4ABEYs8uPEiFyF4gRBXIImEBAPSpAjDtuX//9+YmERgMcuODBAU9+xKCr68Ev4lBNwm//IJCnhxDDQPx4xuFJQhBDDQXwTwpKBSos8//HjlwYQyVG34aB2zCG//1Nw6SFAQTgD/JuD+wjFrbgCr/yMQI+B/lxEY08UgPpl4jCNwP+I4wCBUgOk3/8DoXxI44CBn/0yREDzx0EAQlndANJv4gJAQf3/VJkq8CJoZuGXIPpkg4BOIZuI5/9CII4BEZAmDNwIRBHAJxDNxH+CII4CSQW+NALgBtomBt5uCHAbjB2ZoCAQPyJQP/NwIRCkm//4gBIgP/SQn/CImSYALjDviSDQAYUDL4ImEEYYRGL4X/76PCI4P/SQYCFl4MBAAgRJEwYRPOgZrHpMgA"))
|
||||
}
|
||||
|
||||
var iconAlarm = {
|
||||
width : 50, height : 50, bpp : 3,
|
||||
transparent : 1,
|
||||
buffer : require("heatshrink").decompress(atob("kmSpICEp//BAwCJn/+CJ8k//5CKAABCJs8uPH//x48EI5YjCAARNKEYUcv//jgFBExEnEYoAC+QmHIgIgC/gpCuPBCI2fIgU4AQXjA4P8CIuTEYZKBAolwHApXBEAWP//jxwpBAALaFDoYCIiQmDDIP4EAT+CEwnJEwYjLAQLaFEYomDKALmDNwoCIOIZuD8AkFgCYDHAQjMAQTdDNwOAEg0Dx0/cYeREZtxQYOTHgJuHOIvkXJy8DNwIACJQ8Ah4NDAAfxEZARHOIIkHg4jQAQb1CQ4KVJgEOnDIBSoIjNAQPBcAaVJcAKVBcDGOcD7OBMQM48BuH8f//JKCnhKNggRBkmfTQJxBEwhuD/gRCyVHJRlyCIVJXgYmB8ZQBAoIKBXIQmCOIt/NxAUCOIImCIgIpCBAJuDAQZEE/huIAQWTDgImBTYQGC8gRFcYpKFCI8kDwQAFCJBfBEAX/+IjBiQRIEw4jJAQc8v//NYwCIOgJrIJpA1OcwbaFAQWQA="))
|
||||
}
|
||||
|
||||
var iconCharging = {
|
||||
width : 50, height : 50, bpp : 3,
|
||||
transparent : 5,
|
||||
buffer : require("heatshrink").decompress(atob("23btugAwUBtoICARG0h048eODQYCJ6P/AAUCCJfbo4SDxYRLtEcuPHjlwgoRJ7RnIloUHoYjDAQfAExEAwUIkACEkSAIEYwCBhZKH6EIJI0CJRFHEY0BJRWBSgf//0AJRYSE4BKLj4SE8BKLv4RD/hK/JS2AXY0gXwRKG4cMmACCJQMAg8csEFJQsBAwfasEAm379u0gFbcBfHzgFBz1xMQZKBjY/D0E2+BOChu26yVEEYdww+cgAFCg+cgIfB6RKF4HbgEIkGChEAthfCJQ0eEAIjBBAMxk6GCJQtgtyVBwRKBAQMbHAJKGXIIFCgACBhl54qVG2E+EAJKBJoWAm0WJQ6SCXgdxFgMLJQvYjeAEAUwFIUitEtJQ14NwUHgEwKYZKGwOwNYX7XgWCg3CJQ5rB4MevPnAoPDJRJrCgEG/ECAoNsJRUwoEesIIBiJKI3CVDti/CJRKVDiJHBSo0YsOGjED8AjBcAcIgdhcAXAPIUAcAYIBcA4dBAQUG8BrBgBuCgOwcBEeXIK2BBAIFBgRqBGoYAChq8CcYUE4FbUYOACQsHzgjDgwFBCIImBAQsDtwYD7cAloRI22B86YBw5QBgoRJ7dAgYEDCJaeBJoMcsARMAQNoJIIRE6A"))
|
||||
}
|
||||
|
||||
var iconNoBattery = {
|
||||
width : 50, height : 50, bpp : 3,
|
||||
transparent : 2,
|
||||
buffer : require("heatshrink").decompress(atob("pMkyQCoycMmHDhgLEqVECg1Bw0YsOGBAdKpMSEwwjCmHCBAYDBHA4jCjFpBAUpkmJJR0lkmRL49Fy1ZsuWBAWkyQRGxcs2XLAQe0ymSNw9t23bAQnSyVICI1IEYoCBqSAIkwjF7dupMiQA5KH/KSIJQ+5SRBKH2fkSRBKH8iSHJRHPSRBKIH4PSCJBKFn1JhYRIJQqSBkdtJRscSQLgBJRliAwONcAJKM9MkyAFBJRm/AwM2AoJKMUgNCFIJKM7A8BOgRKMmVJg8MJRqSBAwMGJRqSBzVpJRu5kmTpMhJRmz8mQ2emJRqABm3cyK/BJRWPSQUauRKMSQVmpFbJRdSpMLOIODX4JKJpVJkYgB+gCBJRQDBEAQCDJREpkmNEAQCDJQ8lkmQEYpKJ0mScAIjEJRGUyVEcAJKNSQLgBJRqSBiVIJRqSBkTgBJRoDBAIJKNSQOJAoJKN0mRAoJKOyQFCSp4CikAA="))
|
||||
}
|
||||
|
||||
Graphics.prototype.setFontAntonioMedium = function(scale) {
|
||||
|
|
@ -38,56 +75,67 @@ function draw(queue){
|
|||
g.clearRect(0, 24, g.getWidth(), g.getHeight());
|
||||
|
||||
// Draw background image
|
||||
g.drawImage(img, 0, 24);
|
||||
g.drawImage(backgroundImage, 0, 24);
|
||||
|
||||
// Draw raster
|
||||
// g.drawLine(112, 100, 112, 165);
|
||||
for(var x=1; x<7; x++){
|
||||
g.drawLine(110+x*10, 100, 110+x*10, 160);
|
||||
}
|
||||
|
||||
for(var y=0; y<6; y++){
|
||||
g.drawLine(113, 105+y*10, 175, 105+y*10);
|
||||
}
|
||||
|
||||
// Draw symbol
|
||||
var bat = E.getBattery();
|
||||
|
||||
var iconImg =
|
||||
alarm >= 0 ? iconAlarm :
|
||||
Bangle.isCharging() ? iconCharging :
|
||||
bat < 30 ? iconNoBattery :
|
||||
Bangle.isGPSOn() ? iconGps :
|
||||
Bangle.isCompassOn() ? iconCompass :
|
||||
iconPlanet;
|
||||
g.drawImage(iconImg, 120, 107);
|
||||
|
||||
// Alarm within symbol
|
||||
g.setFontAntonioMedium();
|
||||
if(alarm > 0){
|
||||
g.setFontAlign(0,0,0);
|
||||
g.drawString(alarm, 120+25, 107+25);
|
||||
g.setFontAlign(-1,-1,0);
|
||||
}
|
||||
|
||||
// Write time
|
||||
var currentDate = new Date();
|
||||
var timeStr = locale.time(currentDate,1);
|
||||
g.setFontAlign(0,0,0);
|
||||
g.setFontAntonioLarge();
|
||||
g.drawString(timeStr, 100, 50);
|
||||
g.drawString(timeStr, 60, 55);
|
||||
|
||||
// Write date
|
||||
g.setFontAlign(1,-1, 0);
|
||||
g.setFontAlign(-1,-1, 0);
|
||||
g.setFontAntonioMedium();
|
||||
|
||||
var dayName = locale.dow(currentDate, true).toUpperCase();
|
||||
var day = currentDate.getDate();
|
||||
g.drawString(day, 170, 30);
|
||||
g.drawString(dayName, 170, 50);
|
||||
g.drawString(day, 100, 35);
|
||||
g.drawString(dayName, 100, 55);
|
||||
|
||||
// Alarm
|
||||
// HRM
|
||||
g.setFontAlign(-1,-1,0);
|
||||
g.drawString("TMR:", 30, 107);
|
||||
var alrmText = alarm >= 0 ? "T-"+alarm : "OFF";
|
||||
g.drawString(alrmText, 65, 107);
|
||||
|
||||
// Draw battery
|
||||
var bat = E.getBattery();
|
||||
var charging = Bangle.isCharging() ? "*" : "";
|
||||
g.drawString("BAT:", 30, 127);
|
||||
g.drawString(charging + bat+ "%", 65, 127);
|
||||
g.drawString("HRM:", 28, 102);
|
||||
g.drawString(hrmValue, 63, 102);
|
||||
|
||||
// Draw steps
|
||||
var steps = getSteps();
|
||||
g.drawString("STEP:", 30, 147);
|
||||
g.drawString(steps, 65, 147);
|
||||
g.drawString("STEP:", 28, 122);
|
||||
g.drawString(steps, 63, 122);
|
||||
|
||||
// GPS
|
||||
var gpsText = Bangle.isGPSOn() ? "ON" : "OFF";
|
||||
g.drawString("GPS:", 115, 107);
|
||||
g.drawString(gpsText, 149, 107);
|
||||
|
||||
|
||||
// HRM
|
||||
var gpsText = Bangle.isHRMOn() ? "ON" : "OFF";
|
||||
g.drawString("HRM:", 115, 127);
|
||||
g.drawString(gpsText, 149, 127);
|
||||
|
||||
// CMP
|
||||
var compassText = Bangle.isCompassOn() ? "ON" : "OFF";
|
||||
g.drawString("CMP:", 115, 147);
|
||||
g.drawString(compassText, 149, 147);
|
||||
// Draw battery
|
||||
g.drawString("BAT:", 28, 142);
|
||||
g.drawString(bat+ "%", 63, 142);
|
||||
|
||||
// Queue draw in one minute
|
||||
if(queue){
|
||||
|
|
@ -113,6 +161,13 @@ function stepsWidget() {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
/*
|
||||
* HRM
|
||||
*/
|
||||
Bangle.on('HRM',function(hrm) {
|
||||
hrmValue = hrm.bpm;
|
||||
});
|
||||
|
||||
/*
|
||||
* Handle alarm
|
||||
*/
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 2.4 KiB After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 3.6 KiB |
|
After Width: | Height: | Size: 3.1 KiB |
|
|
@ -1,3 +1,5 @@
|
|||
0.01: New App!
|
||||
0.02: Add 'messages' library
|
||||
0.03: Fixes for Bangle.js 1
|
||||
0.04: Add require("messages").clearAll()
|
||||
0.05: Handling of message actions (ok/clear)
|
||||
|
|
|
|||
|
|
@ -16,7 +16,8 @@
|
|||
{"t":"add","id":1575479849,"src":"Hangouts","title":"A Name","body":"message contents"}
|
||||
// maps
|
||||
{"t":"add","id":1,"src":"Maps","title":"0 yd - High St","body":"Campton - 11:48 ETA","img":"GhqBAAAMAAAHgAAD8AAB/gAA/8AAf/gAP/8AH//gD/98B//Pg/4B8f8Afv+PP//n3/f5//j+f/wfn/4D5/8Aef+AD//AAf/gAD/wAAf4AAD8AAAeAAADAAA="}
|
||||
|
||||
// call
|
||||
{"t":"add","id":"call","src":"Phone","name":"Bob","number":"12421312",positive:true,negative:true}
|
||||
*/
|
||||
|
||||
var Layout = require("Layout");
|
||||
|
|
@ -55,9 +56,16 @@ function saveMessages() {
|
|||
function getBackImage() {
|
||||
return atob("FhYBAAAAEAAAwAAHAAA//wH//wf//g///BwB+DAB4EAHwAAPAAA8AADwAAPAAB4AAHgAB+AH/wA/+AD/wAH8AA==");
|
||||
}
|
||||
function getPosImage() {
|
||||
return atob("GRSBAAAAAYAAAcAAAeAAAfAAAfAAAfAAAfAAAfAAAfBgAfA4AfAeAfAPgfAD4fAA+fAAP/AAD/AAA/AAAPAAADAAAA==");
|
||||
}
|
||||
function getNegImage() {
|
||||
return atob("FhaBADAAMeAB78AP/4B/fwP4/h/B/P4D//AH/4AP/AAf4AB/gAP/AB/+AP/8B/P4P4fx/A/v4B//AD94AHjAAMA=");
|
||||
}
|
||||
function getMessageImage(msg) {
|
||||
if (msg.img) return atob(msg.img);
|
||||
var s = (msg.src||"").toLowerCase();
|
||||
if (s=="Phone") return atob("FxeBABgAAPgAAfAAB/AAD+AAH+AAP8AAP4AAfgAA/AAA+AAA+AAA+AAB+AAB+AAB+OAB//AB//gB//gA//AA/8AAf4AAPAA=");
|
||||
if (s=="skype") return atob("GhoBB8AAB//AA//+Af//wH//+D///w/8D+P8Afz/DD8/j4/H4fP5/A/+f4B/n/gP5//B+fj8fj4/H8+DB/PwA/x/A/8P///B///gP//4B//8AD/+AAA+AA==");
|
||||
if (s=="hangouts") return atob("FBaBAAH4AH/gD/8B//g//8P//H5n58Y+fGPnxj5+d+fmfj//4//8H//B//gH/4A/8AA+AAHAABgAAAA=");
|
||||
if (s=="whatsapp") return atob("GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA==");
|
||||
|
|
@ -154,6 +162,28 @@ function showMessage(msgid) {
|
|||
if (g.setFont(titleFont).stringWidth(title) > w)
|
||||
title = g.wrapString(title, w).join("\n");
|
||||
}
|
||||
var buttons = [
|
||||
{type:"btn", src:getBackImage(), cb:()=>checkMessages(true)}, // back
|
||||
msg.new?{type:"btn", src:atob("HRiBAD///8D///wj///Fj//8bj//x3z//Hvx/8/fx/j+/x+Ad/B4AL8Rh+HxwH+PHwf+cf5/+x/n/PH/P8cf+cx5/84HwAB4fgAD5/AAD/8AAD/wAAD/AAAD8A=="), cb:()=>{
|
||||
msg.new = false; // read mail
|
||||
saveMessages();
|
||||
checkMessages();
|
||||
}}:{}
|
||||
];
|
||||
if (msg.positive) {
|
||||
buttons.push({type:"btn", src:getPosImage(), cb:()=>{
|
||||
msg.new = false; saveMessages();
|
||||
Bangle.messageResponse(msg,true);
|
||||
checkMessages();
|
||||
}});
|
||||
}
|
||||
if (msg.negative) {
|
||||
buttons.push({type:"btn", src:getNegImage(), cb:()=>{
|
||||
msg.new = false; saveMessages();
|
||||
Bangle.messageResponse(msg,true);
|
||||
checkMessages();
|
||||
}});
|
||||
}
|
||||
layout = new Layout({ type:"v", c: [
|
||||
{type:"h", fillx:1, bgCol:colBg, c: [
|
||||
{ type:"img", src:getMessageImage(msg), pad:2 },
|
||||
|
|
@ -163,14 +193,7 @@ function showMessage(msgid) {
|
|||
]},
|
||||
]},
|
||||
{type:"txt", font:fontMedium, label:msg.body||"", wrap:true, fillx:1, filly:1, pad:2 },
|
||||
{type:"h",fillx:1, c: [
|
||||
{type:"btn", src:getBackImage(), cb:()=>checkMessages(true)}, // back
|
||||
msg.new?{type:"btn", src:atob("HRiBAD///8D///wj///Fj//8bj//x3z//Hvx/8/fx/j+/x+Ad/B4AL8Rh+HxwH+PHwf+cf5/+x/n/PH/P8cf+cx5/84HwAB4fgAD5/AAD/8AAD/wAAD/AAAD8A=="), cb:()=>{
|
||||
msg.new = false; // read mail
|
||||
saveMessages();
|
||||
checkMessages();
|
||||
}}:{}
|
||||
]}
|
||||
{type:"h",fillx:1, c: buttons}
|
||||
]});
|
||||
g.clearRect(Bangle.appRect);
|
||||
layout.render();
|
||||
|
|
@ -178,12 +201,15 @@ function showMessage(msgid) {
|
|||
|
||||
function checkMessages(forceShowMenu) {
|
||||
// If no messages, just show 'no messages' and return
|
||||
if (!MESSAGES.length)
|
||||
return E.showPrompt("No Messages",{
|
||||
if (!MESSAGES.length) {
|
||||
if (forceShowMenu) return E.showPrompt("No Messages",{
|
||||
title:"Messages",
|
||||
img:require("heatshrink").decompress(atob("kkk4UBrkc/4AC/tEqtACQkBqtUDg0VqAIGgoZFDYQIIM1sD1QAD4AIBhnqA4WrmAIBhc6BAWs8AIBhXOBAWz0AIC2YIC5wID1gkB1c6BAYFBEQPqBAYXBEQOqBAnDAIQaEnkAngaEEAPDFgo+IKA5iIOhCGIAFb7RqAIGgtUBA0VqobFgNVA")),
|
||||
buttons : {"Ok":1}
|
||||
}).then(() => { load() });
|
||||
load();
|
||||
return;
|
||||
}
|
||||
// we have >0 messages
|
||||
// If we have a new message, show it
|
||||
if (!forceShowMenu) {
|
||||
|
|
@ -194,7 +220,7 @@ function checkMessages(forceShowMenu) {
|
|||
// Otherwise show a menu
|
||||
E.showScroller({
|
||||
h : 48,
|
||||
c : MESSAGES.length+1,
|
||||
c : Math.min(MESSAGES.length+1,3), // workaround for 2v10.219 firmware (min 3 not needed for 2v11)
|
||||
draw : function(idx, r) {"ram"
|
||||
var msg = MESSAGES[idx-1];
|
||||
if (msg && msg.new) g.setBgColor(colBg);
|
||||
|
|
@ -235,4 +261,4 @@ function checkMessages(forceShowMenu) {
|
|||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
checkMessages();
|
||||
checkMessages(true); // force showing a menu
|
||||
|
|
|
|||
|
|
@ -28,10 +28,25 @@ exports.pushMessage = function(event) {
|
|||
// otherwise load after a delay, to ensure we have all the messages
|
||||
if (exports.messageTimeout) clearTimeout(exports.messageTimeout);
|
||||
exports.messageTimeout = setTimeout(function() {
|
||||
exports.messageTimeout = undefined;
|
||||
exports.messageTimeout = undefined;
|
||||
// if we're in a clock or it's important, go straight to messages app
|
||||
if (Bangle.CLOCK || event.important) return load("messages.app.js");
|
||||
if (!global.WIDGETS || !WIDGETS.messages) return Bangle.buzz(); // no widgets - just buzz to let someone know
|
||||
WIDGETS.messages.newMessage();
|
||||
WIDGETS.messages.show();
|
||||
}, 500);
|
||||
}
|
||||
exports.clearAll = function(event) {
|
||||
var messages, inApp = "undefined"!=typeof MESSAGES;
|
||||
if (inApp) {
|
||||
MESSAGES = [];
|
||||
messages = MESSAGES; // we're in an app that has already loaded messages
|
||||
} else // no app - empty messages
|
||||
messages = [];
|
||||
// Save all messages
|
||||
require("Storage").writeJSON("messages.json",messages);
|
||||
// update app if in app
|
||||
if (inApp) return onMessagesModified();
|
||||
// if we have a widget, update it
|
||||
if (global.WIDGETS && WIDGETS.messages)
|
||||
WIDGETS.messages.hide();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,11 +10,15 @@ WIDGETS["messages"]={area:"tl",width:0,draw:function() {
|
|||
Bangle.buzz(); // buzz every 4 seconds
|
||||
}
|
||||
setTimeout(()=>WIDGETS["messages"].draw(), 1000);
|
||||
},newMessage:function() {
|
||||
},show:function() {
|
||||
WIDGETS["messages"].t=Date.now(); // first time
|
||||
WIDGETS["messages"].l=Date.now()-10000; // last buzz
|
||||
if (WIDGETS["messages"].c!==undefined) return; // already called
|
||||
WIDGETS["messages"].width=64;
|
||||
Bangle.drawWidgets();
|
||||
Bangle.setLCDPower(1);// turns screen on
|
||||
},hide:function() {
|
||||
delete WIDGETS["messages"].t;
|
||||
delete WIDGETS["messages"].l;
|
||||
WIDGETS["messages"].width=0;
|
||||
Bangle.drawWidgets();
|
||||
}};
|
||||
|
|
|
|||
|
|
@ -4,3 +4,4 @@
|
|||
0.04: App shows instructions, Widgets remain visible, color changed
|
||||
0.05: Buzz intensity and beats per bar can be changed via settings-app
|
||||
0.06: Correct string position
|
||||
0.07: Add support for Bangle.sjs2
|
||||
|
|
@ -4,11 +4,12 @@ This metronome makes your watch blink and vibrate with a given rate.
|
|||
|
||||
## Usage
|
||||
|
||||
* Tap the screen at least three times. The app calculates the mean rate of your tapping. This rate is displayed in bmp while the text blinks and the watch softly vibrates with every beat.
|
||||
* Use `BTN1` to increase the bmp value by one.
|
||||
* Use `BTN3` to decrease the bmp value by one.
|
||||
* Tap the screen at least three times. The app calculates the mean rate of your tapping. This rate is displayed in bpm while the text blinks and the watch softly vibrates with every beat.
|
||||
* Use `BTN1` to increase the bpm value by one.
|
||||
* Use `BTN3` to decrease the bpm value by one.
|
||||
* You can change the bpm value any time by tapping the screen or using `BTN1` and `BTN3`.
|
||||
* Intensity of buzzing and the beats per bar (default 4) can be changed with the settings-app. The first beat per bar will be marked in red.
|
||||
* On Bangle.js 2 tapping the center of the screen initiates bpm. in- or decreasing bpm can by 1 can be done by tapping left or right site of the screen.
|
||||
|
||||
## Attributions
|
||||
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 3.6 KiB |
|
|
@ -3,10 +3,9 @@ var cindex=0; // index to iterate through colous
|
|||
var bpm=60; // ininital bpm value
|
||||
var time_diffs = [1000, 1000, 1000]; //array to calculate mean bpm
|
||||
var tindex=0; //index to iterate through time_diffs
|
||||
|
||||
|
||||
Bangle.setLCDTimeout(undefined); //do not deaktivate display while running this app
|
||||
|
||||
// set background colour
|
||||
g.setTheme({bg:"#000"});
|
||||
Bangle.setLCDTimeout(undefined); //do not deactivate display while running this app
|
||||
const storage = require("Storage");
|
||||
const SETTINGS_FILE = 'metronome.settings.json';
|
||||
|
||||
|
|
@ -15,7 +14,7 @@ function setting(key) {
|
|||
//define default settings
|
||||
const DEFAULTS = {
|
||||
'beatsperbar': 4,
|
||||
'buzzintens': 0.75,
|
||||
'buzzintens': 1.0,
|
||||
};
|
||||
if (!settings) { loadSettings(); }
|
||||
return (key in settings) ? settings[key] : DEFAULTS[key];
|
||||
|
|
@ -40,6 +39,10 @@ function changecolor() {
|
|||
7: { value: 0xFFFF, name: "White" },
|
||||
};
|
||||
g.setColor(colors[cindex].value);
|
||||
if ((process.env.HWVERSION==2 )) {
|
||||
g.drawLine(39,0,39,g.getWidth()/3);
|
||||
g.drawLine(136,0,136,g.getWidth()/3);
|
||||
}
|
||||
if (cindex == setting('beatsperbar')-1) {
|
||||
cindex = 0;
|
||||
}
|
||||
|
|
@ -50,43 +53,73 @@ function changecolor() {
|
|||
}
|
||||
|
||||
function updateScreen() {
|
||||
g.reset().clearRect(0, 50, 250, 150);
|
||||
g.reset().clearRect(0, 50, 250, 120);
|
||||
changecolor();
|
||||
try {
|
||||
Bangle.buzz(50, setting('buzzintens'));
|
||||
} catch(err) {
|
||||
}
|
||||
g.setFont("Vector",40).setFontAlign(0,0);
|
||||
g.drawString(Math.floor(bpm)+"bpm", g.getWidth()/2, 100);
|
||||
g.drawString(Math.floor(bpm)+"bpm", g.getWidth()/2, g.getWidth()/2);
|
||||
}
|
||||
|
||||
Bangle.on('touch', function(button) {
|
||||
// setting bpm by tapping the screen. Uses the mean time difference between several tappings.
|
||||
if (tindex < time_diffs.length) {
|
||||
if (Date.now()-tStart < 5000) {
|
||||
time_diffs[tindex] = Date.now()-tStart;
|
||||
}
|
||||
} else {
|
||||
tindex=0;
|
||||
time_diffs[tindex] = Date.now()-tStart;
|
||||
}
|
||||
tindex += 1;
|
||||
mean_time = 0.0;
|
||||
for(count = 0; count < time_diffs.length; count++) {
|
||||
mean_time += time_diffs[count];
|
||||
}
|
||||
time_diff = mean_time/count;
|
||||
//Write user instructuins to screen
|
||||
function printInstructions() {
|
||||
g.clear(1).setFont("4x6");
|
||||
g.setColor(-1); //set color to white
|
||||
g.drawString('Drum the beat on the center\nof the screen to set tempo.', 30, g.getWidth()/3*2+15);
|
||||
if(process.env.HWVERSION==1) {
|
||||
g.drawString('Use BTN1 to increase, and\nBTN3 to decrease bpm value by 1.', 30, g.getWidth()/3*2+30);
|
||||
}
|
||||
else {
|
||||
g.drawString('Touch left part of the screen\nto decrease, or the right site\nto increase bpm value by 1.', 30, g.getWidth()/3*2+30);
|
||||
}
|
||||
}
|
||||
|
||||
tStart = Date.now();
|
||||
clearInterval(time_diff);
|
||||
bpm = (60 * 1000/(time_diff));
|
||||
updateScreen();
|
||||
clearInterval(interval);
|
||||
interval = setInterval(updateScreen, 60000 / bpm);
|
||||
return bpm;
|
||||
Bangle.on('touch', function(zone, e) {
|
||||
// setting bpm by tapping the screen. Uses the mean time difference between several tappings.
|
||||
if ((process.env.HWVERSION==2 && e.x > 39 && e.x < 136) || process.env.HWVERSION==1){
|
||||
if (tindex < time_diffs.length) {
|
||||
if (Date.now()-tStart < 5000) {
|
||||
time_diffs[tindex] = Date.now()-tStart;
|
||||
}
|
||||
} else {
|
||||
tindex=0;
|
||||
time_diffs[tindex] = Date.now()-tStart;
|
||||
}
|
||||
tindex += 1;
|
||||
mean_time = 0.0;
|
||||
for (count = 0; count < time_diffs.length; count++) {
|
||||
mean_time += time_diffs[count];
|
||||
}
|
||||
time_diff = mean_time/count;
|
||||
|
||||
tStart = Date.now();
|
||||
clearInterval(time_diff);
|
||||
bpm = (60 * 1000/(time_diff));
|
||||
updateScreen();
|
||||
clearInterval(interval);
|
||||
interval = setInterval(updateScreen, 60000 / bpm);
|
||||
return bpm;
|
||||
}
|
||||
else if (e.x < 39) {
|
||||
if (bpm > 1) {
|
||||
bpm -= 1;
|
||||
clearInterval(interval);
|
||||
interval = setInterval(updateScreen, 60000 / bpm);
|
||||
}
|
||||
}
|
||||
else if (e.x > 136) {
|
||||
if (bpm > 1) {
|
||||
bpm += 1;
|
||||
clearInterval(interval);
|
||||
interval = setInterval(updateScreen, 60000 / bpm);
|
||||
}}
|
||||
});
|
||||
|
||||
// enable bpm finetuning via buttons.
|
||||
|
||||
// enable bpm finetuning
|
||||
if ((process.env.HWVERSION==1)) {
|
||||
setWatch(() => {
|
||||
bpm += 1;
|
||||
clearInterval(interval);
|
||||
|
|
@ -101,10 +134,10 @@ setWatch(() => {
|
|||
}
|
||||
}, BTN3, {repeat:true});
|
||||
|
||||
}
|
||||
interval = setInterval(updateScreen, 60000 / bpm);
|
||||
printInstructions();
|
||||
|
||||
g.clear(1).setFont("6x8");
|
||||
g.drawString('Touch the screen to set tempo.\nUse BTN1 to increase, and\nBTN3 to decrease bpm value by 1.', 25, 200);
|
||||
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 9.8 KiB |
|
After Width: | Height: | Size: 4.7 KiB |
|
After Width: | Height: | Size: 3.4 KiB |
|
After Width: | Height: | Size: 6.9 KiB |
|
|
@ -34,14 +34,12 @@ function getApp() {
|
|||
var ir = require("heatshrink").decompress(atob("jk0ggGDhvdAAXQCYwMEBxAMFAAIaH6c/+c9DgwMC/8zDg4aC/4YCHIwNB7/zHAwNCAgM/DQwqDAYIaHBonT/oNMFBAND74NNBhApEBrQAKBrrrGWpANZHBT7FBpYqIFAYcJBgkA5oMF7gNFFQwoFDgwMHHIoMIAAPM5gMKBrk0oANLmcwBu0zBrMDBv4AFN5gA/ADYA="));
|
||||
var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/+c3DgwMC/8yDg4aC/4YCHIwNBv/zHAwNCAgM/DQwqDAYIaHBolz+4NMFBANDv8nBpgMIFIgNaABQNddYy1IBrI4KfYoNLFRAoDDhIMEgHnBgt+BooqGFAoqGBg4OFBhAODBhQNcmUgBpczmAN2mYNZgYN/AApvMAH4Ab"));
|
||||
var igift = require("heatshrink").decompress(atob("q1QxH+ADOi0QbZ5nMHDQAbKgIACKa4ACKnJWVKghW0KgxWTKgxWyKhBWRKhBWwKhRWPKhRWuKhhWNKhhWtKpxWKKhys8KxBU8Ky5U+KypU/KyhU/KyhU/KynGKn5WTKn5WUKmHCADpJJE7uYABZUfKuuYKv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/AAv+Kv5VT/wADyIAaKpIlbABZSEKv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/ADNtKv6rdKzZVwKhAABy5V/Khw"));
|
||||
|
||||
var W=240,H=240;
|
||||
var blns = [];
|
||||
function updateFlake(f) {
|
||||
f.im = [ir,ig,ib][Math.round(Math.random()*100)%3];
|
||||
f.s = 0.4+Math.random()*0.5;
|
||||
}
|
||||
|
||||
for (var i=0;i<6;i++) {
|
||||
var f = {
|
||||
y:Math.random()*H,x:(0.5+(i<3?i:i+5))*W/11,
|
||||
|
|
@ -51,7 +49,6 @@ var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/
|
|||
updateFlake(f);
|
||||
blns.push(f);
|
||||
}
|
||||
|
||||
function draw() {
|
||||
blns.forEach(f=>{
|
||||
f.y-=f.v;f.r+=f.t;
|
||||
|
|
@ -71,7 +68,6 @@ var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/
|
|||
g.drawString(${JSON.stringify(line4)},x,y+=10);
|
||||
g.flip();
|
||||
}
|
||||
|
||||
g.clear();
|
||||
setInterval(draw,50);
|
||||
})()`;
|
||||
|
|
@ -79,7 +75,6 @@ var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/
|
|||
return `(function() {
|
||||
var isnow = require("heatshrink").decompress(atob("jEagQWTgfAAocf+gFDh4FDiARBggVB3AFBl3Agf8jfkn/AgX/v/9/+Agfv/2//YrBgfwh4wCgfghYFJCIYdFFIw1EIIpNFL44FFOIoAP"));
|
||||
var itree = require("heatshrink").decompress(atob("mtWxH+ADHHDTI0aGuXH5vNGmhqvTYIzBGtoxF6fTG4g4oGgQyBAAZssGoI0Ga1g1FGdo01ZgIAEGmHHNoLSuAAN/rdb0YFBGlgCBGYIABA4YArGYY1CGn4znAAM6GeVd5PQ5Iyurc/vQ0oGZFAn+d4XC3d5GddiGYIEBy+7zoEBGlFhoEcsQ9GT08+oFk1mkGdaVBMgNArnJ6/KzswGs/J6GlrlbqtbvPC5PCy8wGohniMIPJvIpCqmX3e7vI0BqhqlMIY0DqhtBqoEBa0xgBMIIoEqoABGQwzfsIhBv4qHABM50vQGjg1CGaN66DoBGt1ioGd5LoBGjo1PGYNhvLoCa7wnBqgvGA4YzCAgN5GUAsCqoDBmAHCAYU/wPQ0oSDGcBiDqkwAYcxoFd5PX6GdGjrIIqtUAAc3jk5vPC4fCy5pef5I2BTQMcnAHBy+7y95T0oADnFk1ekBpI2aGRUin7NGAA9hsIzVsIgHTAKZBZoPJ5LNDGhBpXGolcwOsrtcA4TNB3bNDGb/+sVin9AoGe6HX5InEvN/TkP+5XQwM/sRsBzqWB4QuKGjvC6HQ4QdDvKWBZYMwmAuHmFUCYNbqibX3fD5O7qolEZQQ0FBwgKDqgJBGiphEDwNUEgJbBFIQqCAgYOCB4IzCnE6GyhYFGoQnDABYzGAAQ1UAAo2NBoQSBnOB0t/Gjo2EABIPCoGe6HX4QzTGRIAEqtVF4QEBBQc4oE4y/J5PCvIxeABk/oADBvO73eXTyAyZMwM/Awd5vIOFGslAr2Av4PLNcU/jmA6HX5I1KasFcn8dTIOd5PJ4SZGGiNhAAIyNn0ckU+ZYe7AAJpJEYJnNGZk+n9kw9cBAcwGoN5aZg1JJJQABm8/oEjoDKC5ALCrUwqh/NrvQ6HDGp04n9doEdoE/sQJBZQZhCqgABGZk6zw0K/1dnVAoNAFwOlCYL1FubJBy4GCGh1AnOX4XC3YzHFYOeCgdV5PQ5OdD4rKBqqYNGYlbv+X3edGY3CGgKMDAAO7JAJgDAClcr2BEYgADaIZ0DL4uXGbDuB6HX5I1GsP+sNhOgWXIhBmWd4Od5PK4TwFGIJoBAYI2BAD0/jlcQoO7AAJaEGQQADGr0/sjNEvOdAoZmDGgw2ZsVAkeAZpQACGZI2VsU/kVGn1bZoPJZogpGGhA4GfRYwBoGC1mlBQbNFFoo0JNxAGCEod/wM6oFAn9iv/J6/Kzo1Ey9/MZQAKCg4GCFgTDEvPCSwI0BC5I0RN4ocEYYPQ5OdHgeXSwTFKGaJyKFYPC3f+MIdbpzFLAD4zB/1OqtbqtOGgYArGAIADGl9UAAI0wGQN5GoQ0vvIABGoI0uGYQABqo0zNOg0uaQY0/GllOGn40//w="));
|
||||
|
||||
var W=g.getWidth(),H=g.getHeight();
|
||||
var flakes = [];
|
||||
for (var i=0;i<10;i++) {
|
||||
|
|
@ -94,7 +89,6 @@ var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/
|
|||
f.v = f.s * (1+Math.random());
|
||||
flakes.push(f);
|
||||
}
|
||||
|
||||
function draw() {
|
||||
flakes.forEach(f=>{
|
||||
f.y+=f.v;f.r+=f.t;
|
||||
|
|
@ -111,7 +105,6 @@ var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/
|
|||
g.drawString(${JSON.stringify(line4)},x,y+=10);
|
||||
g.flip();
|
||||
}
|
||||
|
||||
g.clear();
|
||||
setInterval(draw,50);
|
||||
})();
|
||||
|
|
|
|||
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.5 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 3.9 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1 @@
|
|||
0.01: App is created with gradient background.
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
# School Calendar
|
||||
|
||||
School Calendar is a calendar that you can see your upcoming classes or schedule.
|
||||
|
||||
## Usage:
|
||||
Enter your calendar events on the customizer then upload. (all day events are not supported yet)
|
||||
|
||||
Once uploaded on the watch when in the table mode you can use BTN1 and BTN3 to scroll up and down on the list. (The red rectangle indicates your current position on the table and your yellow rectangle indicates your current schedule item or your next schedule item.)
|
||||
|
||||
If you press BTN2 it will go into detail mode, and you can see additional information about your schedule item. Also, in this mode you can scroll up and down with BTN1 and BTN3 to move around in the table. To exit detail mode press BTN2 again.
|
||||
|
||||
## Screenshots:
|
||||

|
||||

|
||||
|
||||
## Updates Coming Soon:
|
||||
- [ ] Notifications
|
||||
- [ ] All Day Events
|
||||
- [ ] Improved Rendering Screen
|
||||
- [ ] Better Graphics
|
||||
- [ ] Scrolling Table
|
||||
- [ ] Bangle.js V2 Compatibility
|
||||
- [ ] Full Calendar (Calendar that does not have repeating weekly events.)
|
||||
|
||||
## Creator
|
||||
Ronin0000
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwyBC/AH4A/AH4A/AH4A/AH4A/AH4A80s0AIIh/L/5f/EP4ATscsAIo9DBY4BVEJZf/L/5fRznzAIJfdEJZfpymyAJmSBpwPLBZRfqIYYBwL9OMuIBzL9VRAMRTDCJhfymBpkL+GEmABzL9UQAJelinOrPWzQDBymSCpe96+c6YnNL9N794tBAYoFD5152u21t1AoP332MuIPDVIJxB88c///AoODD4gFBLoYJBL9YBT888M4IHDNYPvvoDDznzD5pfq54BT737L4QHCVYQFCL4XTD5pfpueuAKOtqpRBxlRB5JfDEJpfqxwBIG4OOwkw/4AC+++xlxC5ZfBymyDoYlHAIJf0AImEiBbB0s0MIOtuoTJL4glML9NrtoBTLoJTBBpJfCyQfNL9VNAKZfB88cBpJfED5hfslgzEAoT3BxlxBYd795RB2uWC4tjAoQNBC4olFCIZfpFoIBJe4JJB+++AYe964XLL4YPLAIJfqhgBNueuAIJnBCp4BPL9Na9YBBsQBCAoY3BA4YBRC4INPL9oBS5YXWDoxfqJIIByL9NS1QBzL9WKAIgzBAooHFAMBfpMJABqLtYA/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4A/AH4ALA"))
|
||||
|
|
@ -0,0 +1,416 @@
|
|||
<html>
|
||||
<head>
|
||||
<style>
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
html, body, #map {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
#controls {
|
||||
padding: 10px;
|
||||
margin: 10px;
|
||||
border: 1px solid black;
|
||||
position:absolute;
|
||||
right:0px;bottom:0px;
|
||||
background-color: rgb(255, 255, 255);
|
||||
z-index: 100;
|
||||
}
|
||||
</style>
|
||||
<link href='fullcalendar/main.css' rel='stylesheet' />
|
||||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div>
|
||||
<p>Create your events on the week shown. Keep in note that your events repeat weekly.</p>
|
||||
<p>One you have created your events, Click <button id="upload" class="btn btn-primary">Upload</button>.</p>
|
||||
<p>All day events are not supported. A feature that lets you get the calendar from your watch will be added in a future update.</p>
|
||||
</div>
|
||||
|
||||
<script src='fullcalendar/main.js'></script>
|
||||
<script src="../../core/lib/customize.js"></script>
|
||||
|
||||
<script>
|
||||
var calendar;
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
var calendarEl = document.getElementById('calendar');
|
||||
calendar = new FullCalendar.Calendar(calendarEl, {
|
||||
initialView: 'timeGridWeek',
|
||||
headerToolbar: {
|
||||
left: '',
|
||||
center: 'title',
|
||||
right: 'timeGridWeek,listWeek'
|
||||
},
|
||||
navLinks: true, // can click day/week names to navigate views
|
||||
editable: true,
|
||||
selectable: true,
|
||||
selectMirror: true,
|
||||
nowIndicator: true,
|
||||
editable: true,
|
||||
height: 600,
|
||||
initialDate: '2018-06-03', // will be parsed as local
|
||||
select: function(arg) {
|
||||
var title = prompt('Event Title:');
|
||||
if (title) {
|
||||
calendar.addEvent({
|
||||
title: title,
|
||||
start: arg.start,
|
||||
end: arg.end,
|
||||
allDay: arg.allDay
|
||||
})
|
||||
}
|
||||
calendar.unselect()
|
||||
|
||||
},
|
||||
eventClick: function(arg) {
|
||||
if (confirm('Are you sure you want to delete this event?')) {
|
||||
arg.event.remove()
|
||||
}
|
||||
},
|
||||
});
|
||||
calendar.render();
|
||||
});
|
||||
|
||||
// When the 'upload' button is clicked...
|
||||
document.getElementById("upload").addEventListener("click", function () {
|
||||
//Cacultate data:
|
||||
var calendarEvents = calendar.getEvents();
|
||||
let schedule = []
|
||||
//--------------------
|
||||
for(i=0;i<calendarEvents.length;i++){
|
||||
var calendarEntry = {}
|
||||
calendarEntry['cn'] = calendarEvents[i].title;
|
||||
calendarEntry['dow'] = calendarEvents[i].start.getDate()-3;
|
||||
calendarEntry['sh'] = calendarEvents[i].start.getHours();
|
||||
calendarEntry['sm'] = calendarEvents[i].start.getMinutes();
|
||||
calendarEntry['eh'] = calendarEvents[i].end.getHours();
|
||||
calendarEntry['em'] = calendarEvents[i].end.getMinutes();
|
||||
schedule.push(calendarEntry)
|
||||
}
|
||||
// build the app's text using a templated String
|
||||
var app = `
|
||||
require("Font8x12").add(Graphics);
|
||||
require("Font7x11Numeric7Seg", 2).add(Graphics);
|
||||
var file = require("Storage").open("calendarItems.csv","w");
|
||||
let nIntervId;
|
||||
function redrawScreen() {
|
||||
layout.render(layout.background);
|
||||
layout.render(layout.buttons);
|
||||
draw();
|
||||
}
|
||||
function updateDay(ffunction,day){
|
||||
if(ffunction == 1){
|
||||
switch (day) {
|
||||
case 0:
|
||||
return "Sunday";
|
||||
case 1:
|
||||
day = "Monday";
|
||||
break;
|
||||
case 2:
|
||||
day = "Tuesday";
|
||||
break;
|
||||
case 3:
|
||||
day = "Wednesday";
|
||||
break;
|
||||
case 4:
|
||||
day = "Thursday";
|
||||
break;
|
||||
case 5:
|
||||
day = "Friday";
|
||||
break;
|
||||
case 6:
|
||||
day = "Saturday";
|
||||
}
|
||||
return day;
|
||||
}else if(ffunction == 2){
|
||||
switch (day) {
|
||||
case 0:
|
||||
return "Sun";
|
||||
case 1:
|
||||
day = "Mon";
|
||||
break;
|
||||
case 2:
|
||||
day = "Tue";
|
||||
break;
|
||||
case 3:
|
||||
day = "Wed";
|
||||
break;
|
||||
case 4:
|
||||
day = "Thu";
|
||||
break;
|
||||
case 5:
|
||||
day = "Fri";
|
||||
break;
|
||||
case 6:
|
||||
day = "Sat";
|
||||
}
|
||||
return day;
|
||||
}else if(ffunction == 3){
|
||||
switch (day) {
|
||||
case 0:
|
||||
return "S";
|
||||
case 1:
|
||||
day = "M";
|
||||
break;
|
||||
case 2:
|
||||
day = "T";
|
||||
break;
|
||||
case 3:
|
||||
day = "W";
|
||||
break;
|
||||
case 4:
|
||||
day = "R";
|
||||
break;
|
||||
case 5:
|
||||
day = "F";
|
||||
break;
|
||||
case 6:
|
||||
day = "S";
|
||||
}
|
||||
return day;
|
||||
}
|
||||
}
|
||||
function getScheduleTable() {
|
||||
let schedule = ${JSON.stringify(schedule)};
|
||||
logDebug(JSON.stringify(schedule));
|
||||
return schedule;
|
||||
}
|
||||
|
||||
function findNextScheduleIndex() {
|
||||
var schedule = getScheduleTable();
|
||||
var currentDate = new Date();
|
||||
var minuteOfWeek = (currentDate.getDay()*3600)+(currentDate.getHours()*60)+currentDate.getMinutes();
|
||||
//var minuteOfWeek = (4*3600)+(16*60)+0;
|
||||
var currentPosition;
|
||||
for(currentPosition = 0;currentPosition < schedule.length; currentPosition++){
|
||||
var scheduleItemStartMinuteOfWeek = schedule[currentPosition].dow*3600 + schedule[currentPosition].eh*60+schedule[currentPosition].em;
|
||||
if(scheduleItemStartMinuteOfWeek > minuteOfWeek) {
|
||||
return currentPosition;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
function getUpArrow() {return require("heatshrink").decompress(atob("hkOyANKmv9AIIjRCoYZRlvdAI8U3YVK3oBJC4Mc7YVRC4sc7gVCzoBNC4oZDGowXGR58lvoBFC9FcAIoXongBFC58dngBFC6EcAIoPHA"));}
|
||||
function getDownArrow() {return require("heatshrink").decompress(atob("hkOyALImv9AIojPmvdAIoXPlvdAIoXQ3oBFC9GdAIoXnkt9AIoPPAI8U3cc7cc7gBBDIVcAJYXFGYwXOLpU8AI4XBO5sdjgBFR54ZFBpIA=="));}
|
||||
function getMenuIcon() {return require("heatshrink").decompress(atob("iEQyBC/AEU+rwBEn02js17st3stvklrkljkc/cc3cUzYBBD5AdUD4oA/P/4A/P/4A/ADoA=="));}
|
||||
function getDotIcon() {return require("heatshrink").decompress(atob("iEQyBC/AA0t3oBBA4ndAIIPGA4gAFkt9lt9AYIHEzoBBBIwRED41cks8AYIJGA44RGP8xtGP44RJBYh1CAIIHHBJJ/KroBBPoqBFB4YRDAA8dngHHBJKdq3oBDBI4RNP4l9AIYHHBJJBJks8AIIHTAH4ABA="));}
|
||||
var currentPositionTable = 0;
|
||||
var numberOfItemsShown = 8;
|
||||
//Table Positions:
|
||||
var rectStart = 45;
|
||||
var rectEnd = 65;
|
||||
var rectStartX = 10;
|
||||
var rectEndX = 210;
|
||||
//Scences:
|
||||
LIST = 1;
|
||||
INFORMATION = 2;
|
||||
currentStage = LIST;
|
||||
function splitter(str, l){
|
||||
var strs = [];
|
||||
while(str.length > l){
|
||||
var pos = str.substring(0, l).lastIndexOf(' ');
|
||||
pos = pos <= 0 ? l : pos;
|
||||
strs.push(str.substring(0, pos));
|
||||
var i = str.indexOf(' ', pos)+1;
|
||||
if(i < pos || i > pos+l)
|
||||
i = pos;
|
||||
str = str.substring(i);
|
||||
}
|
||||
strs.push(str);
|
||||
return strs;
|
||||
}
|
||||
function updateMinutesToCurrentTime(currentMinuteFunction) {
|
||||
if (currentMinuteFunction<10){
|
||||
currentMinuteUpdatedFunction = "0"+currentMinuteFunction;
|
||||
}else{
|
||||
currentMinuteUpdatedFunction = currentMinuteFunction;
|
||||
}
|
||||
return currentMinuteUpdatedFunction;
|
||||
}
|
||||
function renderBackground(l) {
|
||||
g.clearRect(0,0,240,20);
|
||||
g.drawImage(getBackgroundImage(),110,130,{scale:9,rotate:0});
|
||||
}
|
||||
function renderTable(l) {
|
||||
var foundNumber = findNextScheduleIndex();
|
||||
var yellowIndex = 3;
|
||||
if (foundNumber < 3) { yellowIndex = foundNumber; }
|
||||
for(var x = 0;x<=numberOfItemsShown;x++){
|
||||
g.setColor(255,255,255);
|
||||
g.drawRect(rectStartX,rectStart+(x*20),rectEndX,rectEnd+(20*x));
|
||||
}
|
||||
g.setColor(255,205,0);
|
||||
g.drawRect(rectStartX,rectStart+(yellowIndex*20),rectEndX,rectEnd+(20*yellowIndex));
|
||||
g.setColor(255,0,0);
|
||||
g.drawRect(rectStartX,rectStart+(currentPositionTable*20),rectEndX,rectEnd+(20*currentPositionTable));
|
||||
}
|
||||
function renderTableText(l) {
|
||||
var foundSchedule = getScheduleTable();
|
||||
var foundNumber = findNextScheduleIndex();
|
||||
var startNumber = foundNumber - 2;
|
||||
if (startNumber < 0) { startNumber = 0; }
|
||||
var endNumber = startNumber + 8 - (foundNumber - startNumber);
|
||||
if (endNumber > foundSchedule.length-1) { endNumber = foundSchedule.length-1; }
|
||||
var scheduleHourUpdated;
|
||||
var scheduleMinuteUpdated;
|
||||
for(var currentNumber = startNumber; currentNumber<=endNumber; currentNumber++){
|
||||
scheduleMinuteUpdatedStart = updateMinutesToCurrentTime(foundSchedule[currentNumber].sm);
|
||||
scheduleHourUpdatedStart = foundSchedule[currentNumber].sh;
|
||||
scheduleMinuteUpdatedEnd = updateMinutesToCurrentTime(foundSchedule[currentNumber].em);
|
||||
scheduleHourUpdatedEnd = foundSchedule[currentNumber].eh;
|
||||
scheduleDecriptionUpdated = foundSchedule[currentNumber].cn.substring(0, 20);
|
||||
if(foundSchedule[currentNumber].cn.length >= 15){
|
||||
scheduleDecriptionUpdated = foundSchedule[currentNumber].cn.substring(0, 20)+"...";
|
||||
}
|
||||
schduleDay = updateDay(3,foundSchedule[currentNumber].dow);
|
||||
g.setFont("8x12");
|
||||
g.drawString(scheduleHourUpdatedStart+":"+scheduleMinuteUpdatedStart+"-"+scheduleHourUpdatedEnd+":"+scheduleMinuteUpdatedEnd+" "+schduleDay+" "+scheduleDecriptionUpdated,13,50+(currentNumber*20));
|
||||
}
|
||||
}
|
||||
function buttonsF(l){
|
||||
if(currentStage == LIST){
|
||||
g.drawImage(getDotIcon(),223.5,115);
|
||||
}else{
|
||||
g.drawImage(getMenuIcon(),223.5,115);
|
||||
}
|
||||
g.drawImage(getUpArrow(),225,30);
|
||||
g.drawImage(getDownArrow(),225,215);
|
||||
}
|
||||
function draw() {
|
||||
var currentDate = new Date();
|
||||
var currentDayOfWeek = currentDate.getDay();
|
||||
var currentHour = currentDate.getHours();
|
||||
var currentMinute = currentDate.getMinutes();
|
||||
var currentMinuteUpdated = updateMinutesToCurrentTime(currentMinute);
|
||||
if (layout) {
|
||||
if(currentStage == LIST){
|
||||
layout.time.label = currentHour+":"+currentMinuteUpdated;
|
||||
layout.time.x = 147;
|
||||
layout.time.y = 10;
|
||||
layout.render(layout.table);
|
||||
layout.render(layout.tableText);
|
||||
logDebug("Rendered"+currentPositionTable);
|
||||
}else{
|
||||
layout.time.label = currentHour+":"+currentMinuteUpdated;
|
||||
layout.time.x = 147;
|
||||
layout.time.y = 10;
|
||||
layout.render(layout.info);
|
||||
logDebug("Rendered"+currentPositionTable);
|
||||
}
|
||||
g.clearRect(150,0,220,35);
|
||||
layout.render(layout.time);
|
||||
}
|
||||
}
|
||||
function RedRectDown() {
|
||||
if(currentPositionTable > 0){
|
||||
currentPositionTable -= 1;
|
||||
if(currentStage == INFORMATION){
|
||||
redrawScreen();
|
||||
}else{
|
||||
draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
function RedRectUp() {
|
||||
if(currentPositionTable < numberOfItemsShown){
|
||||
currentPositionTable += 1;
|
||||
if(currentStage == INFORMATION){
|
||||
redrawScreen();
|
||||
}else{
|
||||
draw();
|
||||
}
|
||||
}
|
||||
}
|
||||
function renderMiniBackground(l){
|
||||
for(var i = 233;i<=240;i++){
|
||||
g.drawImage(getBackgroundImage(),i,123,{scale:10,rotate:0});
|
||||
}
|
||||
}
|
||||
function renderLoading(l){
|
||||
g.setFont("8x12");
|
||||
g.drawString("Loading...",240/2-20,240/2-20);
|
||||
}
|
||||
function renderInformation(l){
|
||||
var foundNumber = findNextScheduleIndex();
|
||||
var foundSchedule = getScheduleTable();
|
||||
var startNumber = foundNumber - 2;
|
||||
if (startNumber < 0) { startNumber = 0; }
|
||||
if ((startNumber+currentPositionTable) <= foundSchedule.length-1) {
|
||||
scheduleMinuteUpdatedStart = updateMinutesToCurrentTime(foundSchedule[foundNumber].sm);
|
||||
scheduleHourUpdatedStart = foundSchedule[foundNumber].sh;
|
||||
scheduleMinuteUpdatedEnd = updateMinutesToCurrentTime(foundSchedule[foundNumber].em);
|
||||
scheduleHourUpdatedEnd = foundSchedule[foundNumber].eh;
|
||||
scheduleDay = updateDay(1,foundSchedule[(startNumber+currentPositionTable)].dow);
|
||||
g.setColor(255,255,255);
|
||||
g.setFont("8x12",2);
|
||||
var splitClassNames = splitter(foundSchedule[(startNumber+currentPositionTable)].cn, 15);
|
||||
var currentY = 5;
|
||||
for (var j=0; j < splitClassNames.length; j++) {
|
||||
g.drawString(splitClassNames[j],13,currentY+50);
|
||||
currentY = currentY + 25;
|
||||
}
|
||||
g.setFont("8x12");
|
||||
g.drawString(schduleDay,13,currentY+50);
|
||||
g.drawString(scheduleHourUpdatedStart+":"+scheduleMinuteUpdatedStart+"-"+scheduleHourUpdatedEnd+":"+scheduleMinuteUpdatedEnd,13,currentY+15+50);
|
||||
}
|
||||
}
|
||||
var Layout = require("Layout");
|
||||
var layout = new Layout(
|
||||
{type:"h", c: [
|
||||
{type:"custom", render:renderTableText, id:"tableText"},
|
||||
{type:"custom", render:buttonsF, id:"buttons"},
|
||||
{type:"custom", render:renderBackground, id:"background"},
|
||||
{type:"custom", render:renderTable, id:"table"},
|
||||
{type:"custom", render:renderMiniBackground, id:"miniBackground"},
|
||||
{type:"custom", render:renderLoading, id:"loading"},
|
||||
{type:"custom", render:renderInformation, id:"info"},
|
||||
{type:"txt", font:"7x11Numeric7Seg:2", label:"00:00", id:"time"},
|
||||
]},
|
||||
{type:"v", c:[
|
||||
]},
|
||||
{btns:[
|
||||
{label:"", cb: RedRectUp()},
|
||||
{label:"", cb: l=>print("Two")},
|
||||
{label:"", cb: RedRectDown()}
|
||||
]});
|
||||
function getBackgroundImage() {return require("heatshrink").decompress(atob("j0ZyEKIf4A4gIB6gQB6gYB6ggB6goB6gwB6g4B6hAABAYIBHBZIVLAK8IhIBXgAThhQB6hYB6hgB6hoB6hwB6h4B6iAB6iIB6iQBHiAJOB54XSiYB6igB6ioB6iwB6i4B5A="));}
|
||||
function logDebug(message) {console.log(message);}
|
||||
function changeScene(){
|
||||
layout.render(layout.buttons);
|
||||
if(currentStage == INFORMATION){
|
||||
currentStage = LIST;
|
||||
nIntervId = setInterval(redrawScreen, 100000);
|
||||
}else if(currentStage == LIST){
|
||||
currentStage = INFORMATION;
|
||||
clearInterval();
|
||||
}
|
||||
layout.render(layout.background);
|
||||
layout.render(layout.buttons);
|
||||
draw();
|
||||
}
|
||||
// timeout used to update every minute
|
||||
var drawTimeout;
|
||||
setInterval(draw, 15000);
|
||||
setWatch(RedRectUp, BTN3, { repeat:true, edge:'rising', debounce : 50 });
|
||||
setWatch(RedRectDown, BTN1, { repeat:true, edge:'rising', debounce : 50 });
|
||||
setWatch(changeScene, BTN2, { repeat:true, edge:'rising', debounce : 50 });
|
||||
layout.update();
|
||||
layout.render(layout.loading);
|
||||
layout.render(layout.background);
|
||||
layout.render(layout.buttons);
|
||||
draw();
|
||||
file.write(JSON.stringify(schedule));
|
||||
`;
|
||||
// send finished app (in addition to contents of app.json)
|
||||
sendCustomizedApp({
|
||||
storage: [
|
||||
{ name: "schoolCalendar.app.js", url: "app.js", content: app },
|
||||
]
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<div id='calendar'></div>
|
||||
</body>
|
||||
</html>
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2021 Adam Shaw
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of this software and associated documentation files (the
|
||||
"Software"), to deal in the Software without restriction, including
|
||||
without limitation the rights to use, copy, modify, merge, publish,
|
||||
distribute, sublicense, and/or sell copies of the Software, and to
|
||||
permit persons to whom the Software is furnished to do so, subject to
|
||||
the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be
|
||||
included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
||||
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
||||
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
|
||||
# FullCalendar Interaction Plugin
|
||||
|
||||
Provides functionality for event drag-n-drop, resizing, dateClick, and selectable actions
|
||||
|
||||
[View the docs »](https://fullcalendar.io/docs/editable)
|
||||
|
||||
This package was created from the [FullCalendar monorepo »](https://github.com/fullcalendar/fullcalendar)
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"name": "@fullcalendar/interaction",
|
||||
"version": "5.9.0",
|
||||
"title": "FullCalendar Interaction Plugin",
|
||||
"description": "Provides functionality for event drag-n-drop, resizing, dateClick, and selectable actions",
|
||||
"docs": "https://fullcalendar.io/docs/editable",
|
||||
"dependencies": {
|
||||
"@fullcalendar/common": "workspace:~5.9.0",
|
||||
"tslib": "^2.1.0"
|
||||
},
|
||||
"main": "main.cjs.js",
|
||||
"module": "main.js",
|
||||
"types": "main.d.ts",
|
||||
"jsdelivr": "main.global.min.js",
|
||||
"browserGlobal": "FullCalendarInteraction",
|
||||
"homepage": "https://fullcalendar.io/",
|
||||
"bugs": "https://fullcalendar.io/reporting-bugs",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/fullcalendar/fullcalendar.git",
|
||||
"homepage": "https://github.com/fullcalendar/fullcalendar"
|
||||
},
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "Adam Shaw",
|
||||
"email": "arshaw@arshaw.com",
|
||||
"url": "http://arshaw.com/"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@fullcalendar/core-preact": "workspace:*"
|
||||
}
|
||||
}
|
||||