Merge branch 'master' of github.com:espruino/BangleApps
commit
9a6866f407
|
|
@ -1,3 +1,4 @@
|
||||||
0.01: First release
|
0.01: First release
|
||||||
0.02: Improve battery life, sprite resolution, fix launcher issue and unaligned text bug
|
0.02: Improve battery life, sprite resolution, fix launcher issue and unaligned text bug
|
||||||
0.03: Reduce code size, refresh once a minute and faster refresh
|
0.03: Reduce code size, refresh once a minute and faster refresh
|
||||||
|
0.04: Show a random kana every minute to improve learning
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,17 @@
|
||||||
A simple watchface design with hiragana and katakana
|
A simple watchface design with hiragana and katakana
|
||||||
cards for learning.
|
cards for learning.
|
||||||
|
|
||||||
|
## Changelog
|
||||||
|
|
||||||
|
0.01: First release
|
||||||
|
0.02: Improve battery life, sprite resolution, fix launcher issue and unaligned text bug
|
||||||
|
0.03: Reduce code size, refresh once a minute and faster refresh
|
||||||
|
0.04: Show a random kana every minute to improve learning
|
||||||
|
|
||||||
## Author
|
## Author
|
||||||
|
|
||||||
Written by pancake in 2022, powered by insomnia
|
Written by pancake in 2022, powered by insomnia
|
||||||
|
|
||||||
## Screenshots
|
## Screenshots
|
||||||
|
|
||||||

|

|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,18 @@ function next () {
|
||||||
updateWatch(ohhmm);
|
updateWatch(ohhmm);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function randKana() {
|
||||||
|
try {
|
||||||
|
const keys = Object.keys(katakana);
|
||||||
|
const total = keys.length;
|
||||||
|
let index = 0 | (Math.random() * total);
|
||||||
|
curkana = keys[index];
|
||||||
|
kana = hiramode ? hiragana[curkana] : katakana[curkana];
|
||||||
|
} catch (e) {
|
||||||
|
randKana();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function prev () {
|
function prev () {
|
||||||
let oldk = '';
|
let oldk = '';
|
||||||
let count = 0;
|
let count = 0;
|
||||||
|
|
@ -233,6 +245,7 @@ function tickWatch () {
|
||||||
}
|
}
|
||||||
const hhmm = zpad(now.getHours()) + ':' + zpad(now.getMinutes());
|
const hhmm = zpad(now.getHours()) + ':' + zpad(now.getMinutes());
|
||||||
if (hhmm !== ohhmm) {
|
if (hhmm !== ohhmm) {
|
||||||
|
randKana();
|
||||||
updateWatch(hhmm);
|
updateWatch(hhmm);
|
||||||
ohhmm = hhmm;
|
ohhmm = hhmm;
|
||||||
}
|
}
|
||||||
|
|
@ -257,3 +270,4 @@ setInterval(tickWatch, 1000 * 60);
|
||||||
|
|
||||||
// show launcher when button pressed
|
// show launcher when button pressed
|
||||||
Bangle.setUI('clock');
|
Bangle.setUI('clock');
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"id": "kanawatch",
|
"id": "kanawatch",
|
||||||
"name": "Kanawatch",
|
"name": "Kanawatch",
|
||||||
"shortName": "Kanawatch",
|
"shortName": "Kanawatch",
|
||||||
"version": "0.03",
|
"version": "0.04",
|
||||||
"type": "clock",
|
"type": "clock",
|
||||||
"description": "Learn Hiragana and Katakana",
|
"description": "Learn Hiragana and Katakana",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
|
|
|
||||||
|
|
@ -60,3 +60,4 @@
|
||||||
0.45: Added new app colors and icons
|
0.45: Added new app colors and icons
|
||||||
0.46: Add 'Vibrate Timer' option to set how long to vibrate for, and fix Repeat:off
|
0.46: Add 'Vibrate Timer' option to set how long to vibrate for, and fix Repeat:off
|
||||||
Fix message removal from widget bar (previously caused exception as .hide has been removed)
|
Fix message removal from widget bar (previously caused exception as .hide has been removed)
|
||||||
|
0.47: Add new Icons (Nextbike, Mattermost, etc.)
|
||||||
|
|
|
||||||
|
|
@ -116,7 +116,7 @@ exports.getMessageImage = function(msg) {
|
||||||
if (s=="alarm" || s =="alarmclockreceiver") return atob("GBjBAP////8AAAAAAAACAEAHAOAefng5/5wTgcgHAOAOGHAMGDAYGBgYGBgYGBgYGBgYDhgYBxgMATAOAHAHAOADgcAB/4AAfgAAAAAAAAA=");
|
if (s=="alarm" || s =="alarmclockreceiver") return atob("GBjBAP////8AAAAAAAACAEAHAOAefng5/5wTgcgHAOAOGHAMGDAYGBgYGBgYGBgYGBgYDhgYBxgMATAOAHAHAOADgcAB/4AAfgAAAAAAAAA=");
|
||||||
if (s=="bibel") return atob("GBgBAAAAA//wD//4D//4H//4H/f4H/f4H+P4H4D4H4D4H/f4H/f4H/f4H/f4H/f4H//4H//4H//4GAAAEAAAEAAACAAAB//4AAAA");
|
if (s=="bibel") return atob("GBgBAAAAA//wD//4D//4H//4H/f4H/f4H+P4H4D4H4D4H/f4H/f4H/f4H/f4H/f4H//4H//4H//4GAAAEAAAEAAACAAAB//4AAAA");
|
||||||
if (s=="bring") return atob("GBgBAAAAAAAAAAAAAAAAAHwAAFoAAf+AA/+AA/+AA/+AA/eAA+eAA0+AAx+AA7+AA/+AA//AA/+AAf8AAAIAAAAAAAAAAAAAAAAA");
|
if (s=="bring") return atob("GBgBAAAAAAAAAAAAAAAAAHwAAFoAAf+AA/+AA/+AA/+AA/eAA+eAA0+AAx+AA7+AA/+AA//AA/+AAf8AAAIAAAAAAAAAAAAAAAAA");
|
||||||
if (s=="calendar") return atob("GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgAGB//+B//+B//+B9m2B//+B//+Btm2B//+B//+Btm+B//+B//+A//8AAAAAAAAAAAAA==");
|
if (s=="calendar" || s=="etar") return atob("GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgAGB//+B//+B//+B9m2B//+B//+Btm2B//+B//+Btm+B//+B//+A//8AAAAAAAAAAAAA==");
|
||||||
if (s=="corona-warn") return atob("GBgBAAAAABwAAP+AAf/gA//wB/PwD/PgDzvAHzuAP8EAP8AAPAAAPMAAP8AAH8AAHzsADzuAB/PAB/PgA//wAP/gAH+AAAwAAAAA");
|
if (s=="corona-warn") return atob("GBgBAAAAABwAAP+AAf/gA//wB/PwD/PgDzvAHzuAP8EAP8AAPAAAPMAAP8AAH8AAHzsADzuAB/PAB/PgA//wAP/gAH+AAAwAAAAA");
|
||||||
if (s=="discord") return atob("GBgBAAAAAAAAAAAAAIEABwDgDP8wH//4H//4P//8P//8P//8Pjx8fhh+fzz+f//+f//+e//ePH48HwD4AgBAAAAAAAAAAAAAAAAA");
|
if (s=="discord") return atob("GBgBAAAAAAAAAAAAAIEABwDgDP8wH//4H//4P//8P//8P//8Pjx8fhh+fzz+f//+f//+e//ePH48HwD4AgBAAAAAAAAAAAAAAAAA");
|
||||||
if (s=="facebook" || s=="messenger") return atob("GBiBAAAAAAAAAAAYAAD/AAP/wAf/4A/48A/g8B/g+B/j+B/n+D/n/D8A/B8A+B+B+B/n+A/n8A/n8Afn4APnwADnAAAAAAAAAAAAAA==");
|
if (s=="facebook" || s=="messenger") return atob("GBiBAAAAAAAAAAAYAAD/AAP/wAf/4A/48A/g8B/g+B/j+B/n+D/n/D8A/B8A+B+B+B/n+A/n8A/n8Afn4APnwADnAAAAAAAAAAAAAA==");
|
||||||
|
|
@ -128,7 +128,9 @@ exports.getMessageImage = function(msg) {
|
||||||
if (s=="instagram") return atob("GBiBAAAAAAAAAAAAAAAAAAP/wAYAYAwAMAgAkAh+EAjDEAiBEAiBEAiBEAiBEAjDEAh+EAgAEAwAMAYAYAP/wAAAAAAAAAAAAAAAAA==");
|
if (s=="instagram") return atob("GBiBAAAAAAAAAAAAAAAAAAP/wAYAYAwAMAgAkAh+EAjDEAiBEAiBEAiBEAiBEAjDEAh+EAgAEAwAMAYAYAP/wAAAAAAAAAAAAAAAAA==");
|
||||||
if (s=="kalender") return atob("GBgBBgBgBQCgff++RQCiRgBiQAACf//+QAACQAACR//iRJkiRIEiR//iRNsiRIEiRJkiR//iRIEiRIEiR//iQAACQAACf//+AAAA");
|
if (s=="kalender") return atob("GBgBBgBgBQCgff++RQCiRgBiQAACf//+QAACQAACR//iRJkiRIEiR//iRNsiRIEiRJkiR//iRIEiRIEiR//iQAACQAACf//+AAAA");
|
||||||
if (s=="lieferando") return atob("GBgBABgAAH5wAP9wAf/4A//4B//4D//4H//4P/88fV8+fV4//V4//Vw/HVw4HVw4HBg4HBg4HBg4HDg4Hjw4Hj84Hj44Hj44Hj44");
|
if (s=="lieferando") return atob("GBgBABgAAH5wAP9wAf/4A//4B//4D//4H//4P/88fV8+fV4//V4//Vw/HVw4HVw4HBg4HBg4HBg4HDg4Hjw4Hj84Hj44Hj44Hj44");
|
||||||
|
if (s=="mattermost") return atob("GBgBAAAAAPAAA+EAB4MADgcYHAcYOA8MOB8OeD8GcD8GcH8GcD8HcD8HeBwHeAAOfAAOfgAePwA8P8D8H//4D//wB//gAf/AAH4A");
|
||||||
if (s=="n26") return atob("GBgBAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAOIAAOIAAPIAANoAANoAAM4AAMYAAMYAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAA");
|
if (s=="n26") return atob("GBgBAAAAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAOIAAOIAAPIAANoAANoAAM4AAMYAAMYAAAAAAAAAAAAAAP8AAAAAAAAAAAAAAAAA");
|
||||||
|
if (s=="nextbike") return atob("GBgBAAAAAAAAAAAAAAAAAAAAAACAfgDAPwDAP4HAH4N4H8f8D82GMd8CMDsDMGMDMGGGGMHOD4D8AAAAAAAAAAAAAAAAAAAAAAAA");
|
||||||
if (s=="nina") return atob("GBgBAAAABAAQCAAICAAIEAAEEgAkJAgSJBwSKRxKSj4pUn8lVP+VVP+VUgAlSgApKQBKJAASJAASEgAkEAAECAAICAAIBAAQAAAA");
|
if (s=="nina") return atob("GBgBAAAABAAQCAAICAAIEAAEEgAkJAgSJBwSKRxKSj4pUn8lVP+VVP+VUgAlSgApKQBKJAASJAASEgAkEAAECAAICAAIBAAQAAAA");
|
||||||
if (s=="outlook mail") return atob("HBwBAAAAAAAAAAAIAAAfwAAP/gAB/+AAP/5/A//v/D/+/8P/7/g+Pv8Dye/gPd74w5znHDnOB8Oc4Pw8nv/Dwe/8Pj7/w//v/D/+/8P/7/gf/gAA/+AAAfwAAACAAAAAAAAAAAA=");
|
if (s=="outlook mail") return atob("HBwBAAAAAAAAAAAIAAAfwAAP/gAB/+AAP/5/A//v/D/+/8P/7/g+Pv8Dye/gPd74w5znHDnOB8Oc4Pw8nv/Dwe/8Pj7/w//v/D/+/8P/7/gf/gAA/+AAAfwAAACAAAAAAAAAAAA=");
|
||||||
if (s=="paypal") return atob("GBgBAAAAAAAAAAAAAf+AAf/AAf/gA//gA//gA//wA//wA//wA//wB//wB//wB//gB/+AB/gAB/gAB/gAAPgAAPgAAAAAAAAAAAAA");
|
if (s=="paypal") return atob("GBgBAAAAAAAAAAAAAf+AAf/AAf/gA//gA//gA//wA//wA//wA//wB//wB//wB//gB/+AB/gAB/gAB/gAAPgAAPgAAAAAAAAAAAAA");
|
||||||
|
|
@ -142,13 +144,13 @@ exports.getMessageImage = function(msg) {
|
||||||
if (s=="teams") return atob("GBgBAAAAAAAAAAQAAB4AAD8IAA8cP/M+f/scf/gIeDgAfvvefvvffvvffvvffvvff/vff/veP/PeAA/cAH/AAD+AAD8AAAQAAAAA");
|
if (s=="teams") return atob("GBgBAAAAAAAAAAQAAB4AAD8IAA8cP/M+f/scf/gIeDgAfvvefvvffvvffvvffvvff/vff/veP/PeAA/cAH/AAD+AAD8AAAQAAAAA");
|
||||||
if (s=="telegram" || s=="telegram foss") return atob("GBiBAAAAAAAAAAAAAAAAAwAAHwAA/wAD/wAf3gD/Pgf+fh/4/v/z/P/H/D8P/Acf/AM//AF/+AF/+AH/+ADz+ADh+ADAcAAAMAAAAA==");
|
if (s=="telegram" || s=="telegram foss") return atob("GBiBAAAAAAAAAAAAAAAAAwAAHwAA/wAD/wAf3gD/Pgf+fh/4/v/z/P/H/D8P/Acf/AM//AF/+AF/+AH/+ADz+ADh+ADAcAAAMAAAAA==");
|
||||||
if (s=="threema") return atob("GBjB/4Yx//8AAAAAAAAAAAAAfgAB/4AD/8AH/+AH/+AP//AP2/APw/APw/AHw+AH/+AH/8AH/4AH/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=");
|
if (s=="threema") return atob("GBjB/4Yx//8AAAAAAAAAAAAAfgAB/4AD/8AH/+AH/+AP//AP2/APw/APw/AHw+AH/+AH/8AH/4AH/gAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=");
|
||||||
if (s=="to do") return atob("GBgBAAAAAAAAAAAwAAB4AAD8AAH+AAP/DAf/Hg//Px/+f7/8///4///wf//gP//AH/+AD/8AB/4AA/wAAfgAAPAAAGAAAAAAAAAA");
|
if (s=="to do" || s=="opentasks") return atob("GBgBAAAAAAAAAAAwAAB4AAD8AAH+AAP/DAf/Hg//Px/+f7/8///4///wf//gP//AH/+AD/8AB/4AA/wAAfgAAPAAAGAAAAAAAAAA");
|
||||||
if (s=="twitch") return atob("GBgBH//+P//+P//+eAAGeAAGeAAGeDGGeDOGeDOGeDOGeDOGeDOGeDOGeAAOeAAOeAAcf4/4f5/wf7/gf//Af/+AA/AAA+AAAcAA");
|
if (s=="twitch") return atob("GBgBH//+P//+P//+eAAGeAAGeAAGeDGGeDOGeDOGeDOGeDOGeDOGeDOGeAAOeAAOeAAcf4/4f5/wf7/gf//Af/+AA/AAA+AAAcAA");
|
||||||
if (s=="twitter") return atob("GhYBAABgAAB+JgA/8cAf/ngH/5+B/8P8f+D///h///4f//+D///g///wD//8B//+AP//gD//wAP/8AB/+AB/+AH//AAf/AAAYAAA");
|
if (s=="twitter") return atob("GhYBAABgAAB+JgA/8cAf/ngH/5+B/8P8f+D///h///4f//+D///g///wD//8B//+AP//gD//wAP/8AB/+AB/+AH//AAf/AAAYAAA");
|
||||||
if (s=="warnapp") return atob("GBgBAAAAAAAAAAAAAH4AAP8AA//AA//AD//gP//gf//4f//+/+P+/8H//8n//4n/fxh/fzg+Pj88Dn44AA4AAAwAAAwAAAgAAAAA");
|
if (s=="warnapp") return atob("GBgBAAAAAAAAAAAAAH4AAP8AA//AA//AD//gP//gf//4f//+/+P+/8H//8n//4n/fxh/fzg+Pj88Dn44AA4AAAwAAAwAAAgAAAAA");
|
||||||
if (s=="whatsapp") return atob("GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA==");
|
if (s=="whatsapp") return atob("GBiBAAB+AAP/wAf/4A//8B//+D///H9//n5//nw//vw///x///5///4///8e//+EP3/APn/wPn/+/j///H//+H//8H//4H//wMB+AA==");
|
||||||
if (s=="wordfeud") return atob("GBgCWqqqqqqlf//////9v//////+v/////++v/////++v8///Lu+v8///L++v8///P/+v8v//P/+v9v//P/+v+fx/P/+v+Pk+P/+v/PN+f/+v/POuv/+v/Ofdv/+v/NvM//+v/I/Y//+v/k/k//+v/i/w//+v/7/6//+v//////+v//////+f//////9Wqqqqqql");
|
if (s=="wordfeud") return atob("GBgCWqqqqqqlf//////9v//////+v/////++v/////++v8///Lu+v8///L++v8///P/+v8v//P/+v9v//P/+v+fx/P/+v+Pk+P/+v/PN+f/+v/POuv/+v/Ofdv/+v/NvM//+v/I/Y//+v/k/k//+v/i/w//+v/7/6//+v//////+v//////+f//////9Wqqqqqql");
|
||||||
if (s=="youtube") return atob("GBgBAAAAAAAAAAAAAAAAAf8AH//4P//4P//8P//8P5/8P4/8f4P8f4P8P4/8P5/8P//8P//8P//4H//4Af8AAAAAAAAAAAAAAAAA");
|
if (s=="youtube" || s=="newpipe") return atob("GBgBAAAAAAAAAAAAAAAAAf8AH//4P//4P//8P//8P5/8P4/8f4P8f4P8P4/8P5/8P//8P//8P//4H//4Af8AAAAAAAAAAAAAAAAA");
|
||||||
if (msg.id=="music") return atob("FhaBAH//+/////////////h/+AH/4Af/gB/+H3/7/f/v9/+/3/7+f/vB/w8H+Dwf4PD/x/////////////3//+A=");
|
if (msg.id=="music") return atob("FhaBAH//+/////////////h/+AH/4Af/gB/+H3/7/f/v9/+/3/7+f/vB/w8H+Dwf4PD/x/////////////3//+A=");
|
||||||
// if (s=="sms message" || s=="mail" || s=="gmail") // .. default icon (below)
|
// if (s=="sms message" || s=="mail" || s=="gmail") // .. default icon (below)
|
||||||
return atob("HBKBAD///8H///iP//8cf//j4//8f5//j/x/8//j/H//H4//4PB//EYj/44HH/Hw+P4//8fH//44///xH///g////A==");
|
return atob("HBKBAD///8H///iP//8cf//j4//8f5//j/x/8//j/H//H4//4PB//EYj/44HH/Hw+P4//8fH//44///xH///g////A==");
|
||||||
|
|
@ -168,6 +170,7 @@ exports.getMessageImageCol = function(msg,def) {
|
||||||
"bibel": "#54342c",
|
"bibel": "#54342c",
|
||||||
"bring": "#455a64",
|
"bring": "#455a64",
|
||||||
"discord": "#738adb",
|
"discord": "#738adb",
|
||||||
|
"etar": "#36a18b",
|
||||||
"facebook": "#4267b2",
|
"facebook": "#4267b2",
|
||||||
"gmail": "#ea4335",
|
"gmail": "#ea4335",
|
||||||
"gmx": "#1c449b",
|
"gmx": "#1c449b",
|
||||||
|
|
@ -178,8 +181,12 @@ exports.getMessageImageCol = function(msg,def) {
|
||||||
"instagram": "#dd2a7b",
|
"instagram": "#dd2a7b",
|
||||||
"lieferando": "#ee5c00",
|
"lieferando": "#ee5c00",
|
||||||
"messenger": "#0078ff",
|
"messenger": "#0078ff",
|
||||||
|
"mattermost": "#00f",
|
||||||
"n26": "#36a18b",
|
"n26": "#36a18b",
|
||||||
|
"nextbike": "#00f",
|
||||||
|
"newpipe": "#f00",
|
||||||
"nina": "#e57004",
|
"nina": "#e57004",
|
||||||
|
"opentasks": "#409f8f",
|
||||||
"outlook mail": "#0072c6",
|
"outlook mail": "#0072c6",
|
||||||
"paypal": "#003087",
|
"paypal": "#003087",
|
||||||
"post & dhl": "#f2c101",
|
"post & dhl": "#f2c101",
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"id": "messages",
|
"id": "messages",
|
||||||
"name": "Messages",
|
"name": "Messages",
|
||||||
"version": "0.46",
|
"version": "0.47",
|
||||||
"description": "App to display notifications from iOS and Gadgetbridge/Android",
|
"description": "App to display notifications from iOS and Gadgetbridge/Android",
|
||||||
"icon": "app.png",
|
"icon": "app.png",
|
||||||
"type": "app",
|
"type": "app",
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ The goal is to have types for everything, but that will take some time. Feel fre
|
||||||
|
|
||||||
## Using the types
|
## Using the types
|
||||||
|
|
||||||
All currently typed modules can be found in `/typescript/types.globals.d.ts`.
|
All currently typed modules can be found in `/typescript/types`.
|
||||||
The typing is an ongoing process. If anything is still missing, you can add it! It will automatically be available in your TS files.
|
The typing is an ongoing process. If anything is still missing, you can add it! It will automatically be available in your TS files.
|
||||||
|
|
||||||
## Compilation
|
## Compilation
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,6 @@
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "tsc",
|
"build": "tsc",
|
||||||
"build:types": "tsc ./types/globals.d.ts"
|
"build:types": "tsc ./types/main.d.ts"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,8 @@
|
||||||
"noUncheckedIndexedAccess": true,
|
"noUncheckedIndexedAccess": true,
|
||||||
"noUnusedLocals": true,
|
"noUnusedLocals": true,
|
||||||
"noUnusedParameters": true,
|
"noUnusedParameters": true,
|
||||||
"strict": true
|
"strict": true,
|
||||||
|
"typeRoots": ["./types"]
|
||||||
},
|
},
|
||||||
"include": ["../apps/**/*", "./**/*"],
|
"include": ["../apps/**/*", "./**/*"]
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,211 @@
|
||||||
|
type Accel = {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
z: number;
|
||||||
|
diff: number;
|
||||||
|
td: number;
|
||||||
|
mag: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Mag = {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
z: number;
|
||||||
|
dx: number;
|
||||||
|
dy: number;
|
||||||
|
dz: number;
|
||||||
|
heading: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type GPS = {
|
||||||
|
lat: number;
|
||||||
|
lon: number;
|
||||||
|
alt: number;
|
||||||
|
speed: number;
|
||||||
|
course: number;
|
||||||
|
time: Date;
|
||||||
|
stallites: number;
|
||||||
|
fix: number;
|
||||||
|
hdop: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type HealthStatus = {
|
||||||
|
movement: number;
|
||||||
|
steps: number;
|
||||||
|
bpm: number;
|
||||||
|
bpmConfidence: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type BangleOptions = {
|
||||||
|
wakeOnBTN1: boolean;
|
||||||
|
wakeOnBTN2: boolean;
|
||||||
|
wakeOnBTN3: boolean;
|
||||||
|
wakeOnFaceUp: boolean;
|
||||||
|
wakeOnTouch: boolean;
|
||||||
|
wakeOnTwist: boolean;
|
||||||
|
twistThreshold: number;
|
||||||
|
twistMaxY: number;
|
||||||
|
twistTimeout: number;
|
||||||
|
gestureStartThresh: number;
|
||||||
|
gestureEndThresh: number;
|
||||||
|
gestureInactiveCount: number;
|
||||||
|
gestureMinLength: number;
|
||||||
|
powerSave: boolean;
|
||||||
|
lockTimeout: number;
|
||||||
|
lcdPowerTimeout: number;
|
||||||
|
backlightTimeout: number;
|
||||||
|
hrmPollInterval: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Optional<T> = {
|
||||||
|
[key in keyof T]?: T[key];
|
||||||
|
};
|
||||||
|
|
||||||
|
type LCDMode = "direct" | "doublebuffered" | "120x120" | "80x80";
|
||||||
|
|
||||||
|
declare const Bangle: {
|
||||||
|
accelRd: ((register: any, length: number) => number[]) &
|
||||||
|
((register: any) => number);
|
||||||
|
accelWr: (register: any, data: number[] | number) => void;
|
||||||
|
appRect: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
w: number;
|
||||||
|
h: number;
|
||||||
|
x2: number;
|
||||||
|
y2: number;
|
||||||
|
};
|
||||||
|
beep: (time?: number, frequency?: number) => Promise<void>;
|
||||||
|
buzz: (time?: number, strength?: number) => Promise<void>;
|
||||||
|
compassRd: ((register: any, length: number) => number[]) &
|
||||||
|
((register: any) => number);
|
||||||
|
compassWr: (register: any, data: number[] | number) => void;
|
||||||
|
dbg: () => any;
|
||||||
|
drawWidgets: () => void;
|
||||||
|
F_BEEPSET: boolean;
|
||||||
|
getAccel: () => Accel;
|
||||||
|
getCompass: () => Mag;
|
||||||
|
getGPSFix: () => GPS;
|
||||||
|
getHealthStatus: (range?: "current" | "last" | "day") => HealthStatus;
|
||||||
|
getLCDMode: () => LCDMode;
|
||||||
|
getLogo: () => string;
|
||||||
|
getOptions: () => BangleOptions;
|
||||||
|
getStepCount: () => number;
|
||||||
|
hrmRd: ((register: any, length: number) => number[]) &
|
||||||
|
((register: any) => number);
|
||||||
|
ioWr: (mask: Pin, isOn: boolean) => void;
|
||||||
|
isCharging: () => boolean;
|
||||||
|
isCompassOn: () => boolean;
|
||||||
|
isGPSOn: () => boolean;
|
||||||
|
isHRMOn: () => boolean;
|
||||||
|
isLCDOn: () => boolean;
|
||||||
|
isLocked: () => boolean;
|
||||||
|
lcdWr: (register: any, data: number[] | number) => void;
|
||||||
|
loadWidgets: () => void;
|
||||||
|
off: () => void;
|
||||||
|
on: ((event: "accel", listener: (xyz: Accel) => void) => void) &
|
||||||
|
((
|
||||||
|
event: "aiGesture",
|
||||||
|
listener: (
|
||||||
|
gesture: string | number | undefined,
|
||||||
|
weights: number[]
|
||||||
|
) => void
|
||||||
|
) => void) &
|
||||||
|
((event: "charging", listener: (charging: boolean) => void) => void) &
|
||||||
|
((
|
||||||
|
event: "drag",
|
||||||
|
listener: (event: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
dx: number;
|
||||||
|
dy: number;
|
||||||
|
b: number;
|
||||||
|
}) => void
|
||||||
|
) => void) &
|
||||||
|
((event: "faceUp", listener: (up: boolean) => void) => void) &
|
||||||
|
((event: "gesture", listener: (xyz: Int8Array) => void) => void) &
|
||||||
|
((event: "GPS", listener: (gps: GPS) => void) => void) &
|
||||||
|
((
|
||||||
|
event: "GPS-raw",
|
||||||
|
listener: (nmea: string, dataLoss: boolean) => void
|
||||||
|
) => void) &
|
||||||
|
((event: "health", listener: (info: HealthStatus) => void) => void) &
|
||||||
|
((
|
||||||
|
event: "HRM",
|
||||||
|
listener: (hrm: {
|
||||||
|
bpm: number;
|
||||||
|
confidence: number;
|
||||||
|
raw: Uint8Array;
|
||||||
|
}) => void
|
||||||
|
) => void) &
|
||||||
|
((
|
||||||
|
event: "HRM-raw",
|
||||||
|
listener: (hrm: {
|
||||||
|
raw: number;
|
||||||
|
filt: number;
|
||||||
|
bpm: number;
|
||||||
|
confidence: number;
|
||||||
|
}) => void
|
||||||
|
) => void) &
|
||||||
|
((event: "lcdPower", listener: (on: boolean) => void) => void) &
|
||||||
|
((event: "lock", listener: (on: boolean) => void) => void) &
|
||||||
|
((event: "mag", listener: (mag: Mag) => void) => void) &
|
||||||
|
((event: "midnight", listener: () => void) => void) &
|
||||||
|
((
|
||||||
|
event: "pressure",
|
||||||
|
listener: (info: {
|
||||||
|
temperature: number;
|
||||||
|
pressure: number;
|
||||||
|
altitude: number;
|
||||||
|
}) => void
|
||||||
|
) => void) &
|
||||||
|
((event: "step", listener: (up: number) => void) => void) &
|
||||||
|
((event: "swipe", listener: (direction: number) => void) => void) &
|
||||||
|
((
|
||||||
|
event: "tap",
|
||||||
|
listener: (data: {
|
||||||
|
dir: string;
|
||||||
|
double: boolean;
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
z: number;
|
||||||
|
}) => void
|
||||||
|
) => void) &
|
||||||
|
((
|
||||||
|
event: "touch",
|
||||||
|
listener: (button: number, xy: { x: number; y: number }) => void
|
||||||
|
) => void) &
|
||||||
|
((event: "twist", listener: () => void) => void);
|
||||||
|
project: (latlon: { lat: number; lon: number }) => { x: number; y: number };
|
||||||
|
resetCompass: () => void;
|
||||||
|
setCompassPower: (isOn: boolean, appID: string) => boolean;
|
||||||
|
setGPSPower: (isOn: boolean, appID: string) => boolean;
|
||||||
|
setHRMPower: (isOn: boolean, appID: string) => boolean;
|
||||||
|
setLCDBrightness: (brightness: number) => void;
|
||||||
|
setLCDMode: (mode?: LCDMode) => void;
|
||||||
|
setLCDOffset: (y: number) => void;
|
||||||
|
setLCDPower: (isOn: boolean, appID: string) => boolean;
|
||||||
|
setLCDTimeout: (timeout: number) => void;
|
||||||
|
setLocked: (isLocked: boolean) => void;
|
||||||
|
setOptions: (options: Optional<BangleOptions>) => void;
|
||||||
|
setPollInterval: (timeout: number) => void;
|
||||||
|
setStepCount: (timeout: number) => void;
|
||||||
|
setUI: (
|
||||||
|
type?:
|
||||||
|
| "updown"
|
||||||
|
| "leftright"
|
||||||
|
| "clock"
|
||||||
|
| "clockupdown"
|
||||||
|
| {
|
||||||
|
mode: "custom";
|
||||||
|
back?: () => void;
|
||||||
|
touch?: (n: number, e: number) => void;
|
||||||
|
swipe?: (dir: number) => void;
|
||||||
|
drag?: (e: number) => void;
|
||||||
|
btn?: (n: number) => void;
|
||||||
|
},
|
||||||
|
callback?: (direction: number) => void
|
||||||
|
) => void;
|
||||||
|
showLauncher: () => void;
|
||||||
|
softOff: () => void;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,59 @@
|
||||||
|
/*~ This file declares the Espruino utility class.
|
||||||
|
*~ Reference: https://banglejs.com/reference#E
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare const E: {
|
||||||
|
showAlert: (() => Promise<undefined>) &
|
||||||
|
((message: string, title?: string) => Promise<number>);
|
||||||
|
showMenu: (() => undefined) &
|
||||||
|
((menu: {
|
||||||
|
// The "" value includes menu options.
|
||||||
|
""?: {
|
||||||
|
title?: string;
|
||||||
|
back?: () => void;
|
||||||
|
selected?: number;
|
||||||
|
fontHeight?: number;
|
||||||
|
x?: number;
|
||||||
|
y?: number;
|
||||||
|
x2?: number;
|
||||||
|
y2?: number;
|
||||||
|
cB?: number;
|
||||||
|
cF?: number;
|
||||||
|
cHB?: number;
|
||||||
|
cHF?: number;
|
||||||
|
predraw?: (gfx: GraphicsApi) => void;
|
||||||
|
preflip?: (gfx: GraphicsApi, less: boolean, more: boolean) => void;
|
||||||
|
} & {
|
||||||
|
// All the other key-value pairs are menu items.
|
||||||
|
[key: string]:
|
||||||
|
| undefined
|
||||||
|
| (() => void)
|
||||||
|
| {
|
||||||
|
value: boolean;
|
||||||
|
format?: (value: boolean) => string;
|
||||||
|
onchange?: (value: boolean) => void;
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
value: number;
|
||||||
|
min?: number;
|
||||||
|
max?: number;
|
||||||
|
step?: number;
|
||||||
|
format?: (value: number) => string;
|
||||||
|
onchange?: (value: number) => void;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}) => {
|
||||||
|
draw: () => void;
|
||||||
|
move: () => void;
|
||||||
|
select: () => void;
|
||||||
|
});
|
||||||
|
showPrompt: (() => Promise<undefined>) &
|
||||||
|
(<T extends any = boolean>(
|
||||||
|
message: string,
|
||||||
|
options?: {
|
||||||
|
title?: string;
|
||||||
|
buttons?: { [key: string]: T };
|
||||||
|
img?: string;
|
||||||
|
}
|
||||||
|
) => Promise<T>);
|
||||||
|
};
|
||||||
|
|
@ -1,185 +1,216 @@
|
||||||
// TODO all of these globals (copied from eslintrc) need to be typed at some point
|
/*~ This file declares the Espruino globals.
|
||||||
/* The typing status is listed on the left of the attribute, e.g.:
|
*~ Reference: https://banglejs.com/reference#_global
|
||||||
status "Attribute"
|
|
||||||
|
|
||||||
// Methods and Fields at https://banglejs.com/reference
|
|
||||||
"Array": "readonly",
|
|
||||||
"ArrayBuffer": "readonly",
|
|
||||||
"ArrayBufferView": "readonly",
|
|
||||||
started "Bangle": "readonly",
|
|
||||||
"BluetoothDevice": "readonly",
|
|
||||||
"BluetoothRemoteGATTCharacteristic": "readonly",
|
|
||||||
"BluetoothRemoteGATTServer": "readonly",
|
|
||||||
"BluetoothRemoteGATTService": "readonly",
|
|
||||||
"Boolean": "readonly",
|
|
||||||
"console": "readonly",
|
|
||||||
"DataView": "readonly",
|
|
||||||
"Date": "readonly",
|
|
||||||
"E": "readonly",
|
|
||||||
"Error": "readonly",
|
|
||||||
"Flash": "readonly",
|
|
||||||
"Float32Array": "readonly",
|
|
||||||
"Float64Array": "readonly",
|
|
||||||
"fs": "readonly",
|
|
||||||
"Function": "readonly",
|
|
||||||
started "Graphics": "readonly",
|
|
||||||
done "heatshrink": "readonly",
|
|
||||||
"I2C": "readonly",
|
|
||||||
"Int16Array": "readonly",
|
|
||||||
"Int32Array": "readonly",
|
|
||||||
"Int8Array": "readonly",
|
|
||||||
"InternalError": "readonly",
|
|
||||||
"JSON": "readonly",
|
|
||||||
"Math": "readonly",
|
|
||||||
"Modules": "readonly",
|
|
||||||
"NRF": "readonly",
|
|
||||||
"Number": "readonly",
|
|
||||||
"Object": "readonly",
|
|
||||||
"OneWire": "readonly",
|
|
||||||
"Pin": "readonly",
|
|
||||||
"process": "readonly",
|
|
||||||
"Promise": "readonly",
|
|
||||||
"ReferenceError": "readonly",
|
|
||||||
"RegExp": "readonly",
|
|
||||||
"Serial": "readonly",
|
|
||||||
"SPI": "readonly",
|
|
||||||
"Storage": "readonly",
|
|
||||||
"StorageFile": "readonly",
|
|
||||||
"String": "readonly",
|
|
||||||
"SyntaxError": "readonly",
|
|
||||||
"tensorflow": "readonly",
|
|
||||||
"TFMicroInterpreter": "readonly",
|
|
||||||
"TypeError": "readonly",
|
|
||||||
"Uint16Array": "readonly",
|
|
||||||
"Uint24Array": "readonly",
|
|
||||||
"Uint32Array": "readonly",
|
|
||||||
"Uint8Array": "readonly",
|
|
||||||
"Uint8ClampedArray": "readonly",
|
|
||||||
"Waveform": "readonly",
|
|
||||||
// Methods and Fields at https://banglejs.com/reference
|
|
||||||
"analogRead": "readonly",
|
|
||||||
"analogWrite": "readonly",
|
|
||||||
"arguments": "readonly",
|
|
||||||
"atob": "readonly",
|
|
||||||
"Bluetooth": "readonly",
|
|
||||||
"BTN": "readonly",
|
|
||||||
"BTN1": "readonly",
|
|
||||||
"BTN2": "readonly",
|
|
||||||
"BTN3": "readonly",
|
|
||||||
"BTN4": "readonly",
|
|
||||||
"BTN5": "readonly",
|
|
||||||
"btoa": "readonly",
|
|
||||||
"changeInterval": "readonly",
|
|
||||||
"clearInterval": "readonly",
|
|
||||||
"clearTimeout": "readonly",
|
|
||||||
"clearWatch": "readonly",
|
|
||||||
"decodeURIComponent": "readonly",
|
|
||||||
"digitalPulse": "readonly",
|
|
||||||
"digitalRead": "readonly",
|
|
||||||
"digitalWrite": "readonly",
|
|
||||||
"dump": "readonly",
|
|
||||||
"echo": "readonly",
|
|
||||||
"edit": "readonly",
|
|
||||||
"encodeURIComponent": "readonly",
|
|
||||||
"eval": "readonly",
|
|
||||||
"getPinMode": "readonly",
|
|
||||||
"getSerial": "readonly",
|
|
||||||
"getTime": "readonly",
|
|
||||||
"global": "readonly",
|
|
||||||
"HIGH": "readonly",
|
|
||||||
"I2C1": "readonly",
|
|
||||||
"Infinity": "readonly",
|
|
||||||
"isFinite": "readonly",
|
|
||||||
"isNaN": "readonly",
|
|
||||||
"LED": "readonly",
|
|
||||||
"LED1": "readonly",
|
|
||||||
"LED2": "readonly",
|
|
||||||
"load": "readonly",
|
|
||||||
"LoopbackA": "readonly",
|
|
||||||
"LoopbackB": "readonly",
|
|
||||||
"LOW": "readonly",
|
|
||||||
"NaN": "readonly",
|
|
||||||
"parseFloat": "readonly",
|
|
||||||
"parseInt": "readonly",
|
|
||||||
"peek16": "readonly",
|
|
||||||
"peek32": "readonly",
|
|
||||||
"peek8": "readonly",
|
|
||||||
"pinMode": "readonly",
|
|
||||||
"poke16": "readonly",
|
|
||||||
"poke32": "readonly",
|
|
||||||
"poke8": "readonly",
|
|
||||||
"print": "readonly",
|
|
||||||
started "require": "readonly",
|
|
||||||
"reset": "readonly",
|
|
||||||
"save": "readonly",
|
|
||||||
"Serial1": "readonly",
|
|
||||||
"setBusyIndicator": "readonly",
|
|
||||||
"setInterval": "readonly",
|
|
||||||
"setSleepIndicator": "readonly",
|
|
||||||
"setTime": "readonly",
|
|
||||||
"setTimeout": "readonly",
|
|
||||||
"setWatch": "readonly",
|
|
||||||
"shiftOut": "readonly",
|
|
||||||
"SPI1": "readonly",
|
|
||||||
"Terminal": "readonly",
|
|
||||||
"trace": "readonly",
|
|
||||||
"VIBRATE": "readonly",
|
|
||||||
// Aliases and not defined at https://banglejs.com/reference
|
|
||||||
done "g": "readonly",
|
|
||||||
done "WIDGETS": "readonly"
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// ambient JS definitions
|
/* Note: The following don't have to be declared as they are
|
||||||
|
* already part of regular JavaScript:
|
||||||
|
* btoa
|
||||||
|
* clearInterval
|
||||||
|
* clearTimeout
|
||||||
|
* decodeURIComponent
|
||||||
|
* encodeURIComponent
|
||||||
|
* eval
|
||||||
|
* Infinity
|
||||||
|
* isFinite
|
||||||
|
* isNaN
|
||||||
|
* NaN
|
||||||
|
* parseFloat
|
||||||
|
* parseInt
|
||||||
|
* setInterval
|
||||||
|
* setTimeout
|
||||||
|
*/
|
||||||
|
|
||||||
declare const require: ((module: 'heatshrink') => {
|
// Pins
|
||||||
|
declare type Pin = number;
|
||||||
|
declare type PinMode =
|
||||||
|
| "analog"
|
||||||
|
| "input"
|
||||||
|
| "intupt_pullup"
|
||||||
|
| "intupt_pulldown"
|
||||||
|
| "output"
|
||||||
|
| "opendrain"
|
||||||
|
| "af_output"
|
||||||
|
| "af_opendrain";
|
||||||
|
|
||||||
|
declare const BTN: 24;
|
||||||
|
declare const BTN1: 24;
|
||||||
|
declare const BTN2: 22;
|
||||||
|
declare const BTN3: 23;
|
||||||
|
declare const BTN4: 11;
|
||||||
|
declare const BTN5: 16;
|
||||||
|
declare const VIBRATE: 13;
|
||||||
|
|
||||||
|
declare function getPinMode(pin: Pin): PinMode;
|
||||||
|
declare function pinMode(
|
||||||
|
pin: Pin,
|
||||||
|
mode?: PinMode | "auto",
|
||||||
|
automatic?: boolean
|
||||||
|
): void;
|
||||||
|
|
||||||
|
// Analog pins
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the analog value of the given pin.
|
||||||
|
* This is different to Arduino which only returns an integer between 0 and 1023.
|
||||||
|
* However only pins connected to an ADC will work (see the datasheet).
|
||||||
|
* **Note**: if you didn't call `pinMode` beforehand then this function will also reset pin's state to "analog".
|
||||||
|
* @param {number} pin - The pin to use.
|
||||||
|
* @returns {number} The analog Value of the Pin between 0 and 1.
|
||||||
|
* @url https://banglejs.com/reference#l__global_analogRead
|
||||||
|
*/
|
||||||
|
declare function analogRead(pin: Pin): number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the analog Value of a pin. It will be output using PWM.
|
||||||
|
* **Note**: if you didn't call pinMode beforehand then this function will also reset pin's state to "output".
|
||||||
|
* @param {number} pin - The pin to use.
|
||||||
|
* @param {number} value - A value between 0 and 1.
|
||||||
|
* @param {object} [options] - Additonal options.
|
||||||
|
* @param {number} [options.freq] - Pulse frequency in Hz, e.g. 10 - specifying a frequency will force PWM output, even if the pin has a DAC.
|
||||||
|
* @param {boolean} [options.soft] - If true software PWM is used if hardware is not available.
|
||||||
|
* @param {boolean} [options.forceSoft] - If true software PWM is used even if hardware PWM or a DAC is available.
|
||||||
|
*/
|
||||||
|
declare function analogWrite(
|
||||||
|
pin: Pin,
|
||||||
|
value: number,
|
||||||
|
options?: { freq?: number; soft?: boolean; forceSoft?: boolean }
|
||||||
|
): void;
|
||||||
|
|
||||||
|
// Digital pins
|
||||||
|
declare const HIGH: 1;
|
||||||
|
|
||||||
|
declare const LOW: 0;
|
||||||
|
|
||||||
|
declare function digitalPulse(pin: Pin, value: boolean, time: number): void;
|
||||||
|
|
||||||
|
declare function digitalRead(pin: Pin | Pin[]): number;
|
||||||
|
|
||||||
|
declare function digitalWrite(pin: Pin, value: boolean): void;
|
||||||
|
declare function digitalWrite(pin: Pin[], value: number): void;
|
||||||
|
declare function digitalWrite(
|
||||||
|
pin: {
|
||||||
|
write: (value: boolean) => void;
|
||||||
|
},
|
||||||
|
value: boolean
|
||||||
|
): void;
|
||||||
|
|
||||||
|
// Other globals
|
||||||
|
declare function atob(base64Data: string): string;
|
||||||
|
|
||||||
|
declare function btoa(binaryData: string): string;
|
||||||
|
|
||||||
|
declare function changeInterval(id: number, time: number): void;
|
||||||
|
|
||||||
|
declare function dump(): void;
|
||||||
|
|
||||||
|
declare function echo(echoOn: boolean): void;
|
||||||
|
|
||||||
|
declare function edit(funcName: string | Function): void;
|
||||||
|
|
||||||
|
declare function getSerial(): number;
|
||||||
|
|
||||||
|
declare function getTime(): number;
|
||||||
|
|
||||||
|
declare const global: any; //TODO define better
|
||||||
|
|
||||||
|
declare const I2C1: I2C;
|
||||||
|
|
||||||
|
declare function load(file?: string): void;
|
||||||
|
|
||||||
|
declare function peek8(address: number, count?: 1): number;
|
||||||
|
declare function peek8(address: number, count: number): Uint8Array;
|
||||||
|
|
||||||
|
declare function peek16(address: number, count?: 1): number;
|
||||||
|
declare function peek16(address: number, count: number): Uint16Array;
|
||||||
|
|
||||||
|
declare function peek32(address: number, count?: 1): number;
|
||||||
|
declare function peek32(address: number, count: number): Uint32Array;
|
||||||
|
|
||||||
|
declare function poke8(address: number, value: number): void;
|
||||||
|
|
||||||
|
declare function poke16(address: number, value: number): void;
|
||||||
|
|
||||||
|
declare function poke32(address: number, value: number): void;
|
||||||
|
|
||||||
|
declare function print(...args: any[]): void;
|
||||||
|
|
||||||
|
declare const Serial1: Serial;
|
||||||
|
|
||||||
|
declare const Bluetooth: Serial;
|
||||||
|
|
||||||
|
declare const LoopbackA: Serial;
|
||||||
|
|
||||||
|
declare const LoopbackB: Serial;
|
||||||
|
|
||||||
|
declare function require(module: "heatshrink"): {
|
||||||
decompress: (compressedString: string) => string;
|
decompress: (compressedString: string) => string;
|
||||||
}) & // TODO add more
|
|
||||||
((module: 'otherString') => {});
|
|
||||||
|
|
||||||
// ambient bangle.js definitions
|
|
||||||
|
|
||||||
declare const Bangle: {
|
|
||||||
// functions
|
|
||||||
buzz: (duration?: number, intensity?: number) => Promise<void>;
|
|
||||||
drawWidgets: () => void;
|
|
||||||
isCharging: () => boolean;
|
|
||||||
// events
|
|
||||||
on(event: 'charging', listener: (charging: boolean) => void): void;
|
|
||||||
// TODO add more
|
|
||||||
};
|
};
|
||||||
|
declare function require(module: "Storage"): Storage;
|
||||||
|
declare type Module = "heatshrink" | "Storage";
|
||||||
|
|
||||||
declare type Image = {
|
declare function reset(clearFlash?: true): void;
|
||||||
width: number;
|
|
||||||
height: number;
|
|
||||||
bpp?: number;
|
|
||||||
buffer: ArrayBuffer | string;
|
|
||||||
transparent?: number;
|
|
||||||
palette?: Uint16Array;
|
|
||||||
};
|
|
||||||
|
|
||||||
declare type GraphicsApi = {
|
declare function setInterval(id: any): void;
|
||||||
reset: () => GraphicsApi;
|
|
||||||
flip: () => void;
|
declare function setBusyIndicator(pin?: Pin): void;
|
||||||
setColor: (color: string) => GraphicsApi; // TODO we can most likely type color more usefully than this
|
|
||||||
drawImage: (
|
declare function setSleepIndicator(pin?: Pin): void;
|
||||||
image: string | Image | ArrayBuffer,
|
|
||||||
xOffset: number,
|
declare function setTime(time: number): void;
|
||||||
yOffset: number,
|
|
||||||
|
type Data =
|
||||||
|
| number
|
||||||
|
| string
|
||||||
|
| Array<Data>
|
||||||
|
| ArrayBuffer
|
||||||
|
| { data: Data; count: number }
|
||||||
|
| { callback: () => Data };
|
||||||
|
|
||||||
|
declare function shiftOut(
|
||||||
|
pins: Pin | Pin[],
|
||||||
|
options: { clk: Pin; repeat?: number },
|
||||||
|
data: Data
|
||||||
|
): void;
|
||||||
|
|
||||||
|
declare const SPI1: SPIInstance;
|
||||||
|
|
||||||
|
declare const Terminal: Serial;
|
||||||
|
|
||||||
|
declare function trace(root?: number): void;
|
||||||
|
|
||||||
|
// Watches
|
||||||
|
declare function clearWatch(id?: number): void;
|
||||||
|
declare const setWatch: ((
|
||||||
|
callback:
|
||||||
|
| ((obj: { state: boolean; time: number; lastTime: number }) => void)
|
||||||
|
| string,
|
||||||
|
pin: number,
|
||||||
|
options?:
|
||||||
|
| boolean
|
||||||
|
| number
|
||||||
|
| {
|
||||||
|
repeat?: boolean;
|
||||||
|
edge?: "rising" | "falling" | "both";
|
||||||
|
debounce?: number;
|
||||||
|
irq?: boolean;
|
||||||
|
}
|
||||||
|
) => number) &
|
||||||
|
// If a data option is specified, the callback will also have one.
|
||||||
|
((
|
||||||
|
callback:
|
||||||
|
| ((obj: {
|
||||||
|
state: boolean;
|
||||||
|
time: number;
|
||||||
|
lastTime: number;
|
||||||
|
data: any; // TODO: Specify data type
|
||||||
|
}) => void)
|
||||||
|
| string,
|
||||||
|
pin: number,
|
||||||
options?: {
|
options?: {
|
||||||
rotate?: number;
|
data: number;
|
||||||
scale?: number;
|
repeat?: boolean;
|
||||||
|
edge?: "rising" | "falling" | "both";
|
||||||
|
debounce?: number;
|
||||||
|
irq?: boolean;
|
||||||
}
|
}
|
||||||
) => GraphicsApi;
|
) => number);
|
||||||
// TODO add more
|
|
||||||
};
|
|
||||||
|
|
||||||
declare const Graphics: GraphicsApi;
|
|
||||||
declare const g: GraphicsApi;
|
|
||||||
|
|
||||||
type WidgetArea = 'tl' | 'tr' | 'bl' | 'br';
|
|
||||||
declare type Widget = {
|
|
||||||
area: WidgetArea;
|
|
||||||
width: number;
|
|
||||||
draw: (this: { x: number; y: number }) => void;
|
|
||||||
};
|
|
||||||
declare const WIDGETS: { [key: string]: Widget };
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,266 @@
|
||||||
|
/*~ This file declares the Graphics class.
|
||||||
|
*~ Reference: https://banglejs.com/reference#Graphics
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Image = {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
buffer: ArrayBuffer | string;
|
||||||
|
bpp?: number;
|
||||||
|
transparent?: number;
|
||||||
|
palette?: Uint16Array;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Theme = {
|
||||||
|
fg: number;
|
||||||
|
bg: number;
|
||||||
|
fg2: number;
|
||||||
|
bg2: number;
|
||||||
|
fgH: number;
|
||||||
|
bgH: number;
|
||||||
|
dark: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type Layer = {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
image: string | Image | ArrayBuffer;
|
||||||
|
scale?: number;
|
||||||
|
rotate?: number;
|
||||||
|
center?: boolean;
|
||||||
|
repeat?: boolean;
|
||||||
|
nobounds?: boolean;
|
||||||
|
};
|
||||||
|
|
||||||
|
type GraphicsApi = {
|
||||||
|
asBMP: () => string | undefined;
|
||||||
|
|
||||||
|
asImage: ((type: "object" | undefined) => object) &
|
||||||
|
((type: "string") => string);
|
||||||
|
|
||||||
|
asURL: () => string | undefined;
|
||||||
|
|
||||||
|
blit: (options: {
|
||||||
|
x1: number;
|
||||||
|
y1: number;
|
||||||
|
w: number;
|
||||||
|
h: number;
|
||||||
|
x2: number;
|
||||||
|
y2: number;
|
||||||
|
setModified?: boolean;
|
||||||
|
}) => GraphicsApi;
|
||||||
|
|
||||||
|
buffer: ArrayBuffer;
|
||||||
|
|
||||||
|
clear: (reset?: boolean) => GraphicsApi;
|
||||||
|
|
||||||
|
clearRect: ((x1: number, y1: number, x2: number, y2: number) => GraphicsApi) &
|
||||||
|
((options: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
x2: number;
|
||||||
|
y2: number;
|
||||||
|
}) => GraphicsApi) &
|
||||||
|
((options: { x: number; y: number; w: number; h: number }) => GraphicsApi);
|
||||||
|
|
||||||
|
createArrayBuffer: (
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
bpp: number,
|
||||||
|
options?: {
|
||||||
|
zigzag?: boolean;
|
||||||
|
vertical_byte?: boolean;
|
||||||
|
msb?: boolean;
|
||||||
|
interleavex?: boolean;
|
||||||
|
color_order?: "rgb" | "rbg" | "grb" | "gbr" | "brg" | "bgr";
|
||||||
|
}
|
||||||
|
) => GraphicsApi;
|
||||||
|
|
||||||
|
createCallback: (
|
||||||
|
width: number,
|
||||||
|
height: number,
|
||||||
|
bpp: number,
|
||||||
|
callback: ((x: number, y: number, colour: number) => void) & {
|
||||||
|
setPixel: (x: number, y: number, colour: number) => void;
|
||||||
|
fillRect: (
|
||||||
|
x1: number,
|
||||||
|
y1: number,
|
||||||
|
x2: number,
|
||||||
|
y2: number,
|
||||||
|
colour: number
|
||||||
|
) => void;
|
||||||
|
}
|
||||||
|
) => GraphicsApi;
|
||||||
|
|
||||||
|
createImage: (str: string) => Image;
|
||||||
|
|
||||||
|
drawCircle: (x: number, y: number, radius: number) => GraphicsApi;
|
||||||
|
|
||||||
|
drawCircleAA: (x: number, y: number, radius: number) => GraphicsApi;
|
||||||
|
|
||||||
|
drawEllipse: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi;
|
||||||
|
|
||||||
|
drawImage: (
|
||||||
|
image: string | Image | ArrayBuffer,
|
||||||
|
xOffset: number,
|
||||||
|
yOffset: number,
|
||||||
|
options?: {
|
||||||
|
rotate?: number;
|
||||||
|
scale?: number;
|
||||||
|
frame?: number;
|
||||||
|
}
|
||||||
|
) => GraphicsApi;
|
||||||
|
|
||||||
|
drawImages: (
|
||||||
|
layers: [Layer?, Layer?, Layer?],
|
||||||
|
options?: {
|
||||||
|
x: number;
|
||||||
|
y: number;
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
}
|
||||||
|
) => GraphicsApi;
|
||||||
|
|
||||||
|
drawLine: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi;
|
||||||
|
|
||||||
|
drawLineAA: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi;
|
||||||
|
|
||||||
|
// TODO: Somehow define that poly must have an even number of items
|
||||||
|
drawPoly: (poly: number[], closed?: boolean) => GraphicsApi;
|
||||||
|
|
||||||
|
drawPolyAA: (poly: number[], closed?: boolean) => GraphicsApi;
|
||||||
|
|
||||||
|
drawRect: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi;
|
||||||
|
|
||||||
|
drawString: (
|
||||||
|
str: string | number | boolean,
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
solid?: boolean
|
||||||
|
) => GraphicsApi;
|
||||||
|
|
||||||
|
dump: () => void;
|
||||||
|
|
||||||
|
fillCircle: (x: number, y: number, radius: number) => GraphicsApi;
|
||||||
|
|
||||||
|
fillEllipse: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi;
|
||||||
|
|
||||||
|
fillPoly: (poly: number[], closed?: boolean) => GraphicsApi;
|
||||||
|
|
||||||
|
fillPolyAA: (poly: number[], closed?: boolean) => GraphicsApi;
|
||||||
|
|
||||||
|
fillRect: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi;
|
||||||
|
|
||||||
|
flip: (all?: boolean) => GraphicsApi;
|
||||||
|
|
||||||
|
getBgColor: () => number;
|
||||||
|
|
||||||
|
getBPP: () => number;
|
||||||
|
|
||||||
|
getColor: () => number;
|
||||||
|
|
||||||
|
getFont: () => string;
|
||||||
|
|
||||||
|
getFontHeight: () => number;
|
||||||
|
|
||||||
|
getFonts: () => string[];
|
||||||
|
|
||||||
|
getHeight: () => number;
|
||||||
|
|
||||||
|
getInstance: () => GraphicsApi | undefined;
|
||||||
|
|
||||||
|
getModified: (
|
||||||
|
reset?: boolean
|
||||||
|
) => { x1: number; y1: number; x2: number; y2: number } | undefined;
|
||||||
|
|
||||||
|
getPixel: (x: number, y: number) => number;
|
||||||
|
|
||||||
|
getWidth: () => number;
|
||||||
|
|
||||||
|
imageMetrics: (image: string | GraphicsApi | Image | ArrayBuffer) =>
|
||||||
|
| {
|
||||||
|
width: number;
|
||||||
|
height: number;
|
||||||
|
bpp: number;
|
||||||
|
transparent: number;
|
||||||
|
}
|
||||||
|
| undefined;
|
||||||
|
|
||||||
|
lineTo: (x: number, y: number) => GraphicsApi;
|
||||||
|
|
||||||
|
moveTo: (x: number, y: number) => GraphicsApi;
|
||||||
|
|
||||||
|
quadraticBezier: (
|
||||||
|
vertices: [
|
||||||
|
x0: number,
|
||||||
|
y0: number,
|
||||||
|
x1: number,
|
||||||
|
y1: number,
|
||||||
|
x2: number,
|
||||||
|
y2: number
|
||||||
|
],
|
||||||
|
points?: number
|
||||||
|
) => number[];
|
||||||
|
|
||||||
|
reset: () => GraphicsApi;
|
||||||
|
|
||||||
|
scroll: (x: number, y: number) => GraphicsApi;
|
||||||
|
|
||||||
|
setBgColor: ((color: string) => GraphicsApi) &
|
||||||
|
((color: number) => GraphicsApi) &
|
||||||
|
((r: number, g: number, b: number) => GraphicsApi);
|
||||||
|
|
||||||
|
setClipRect: (x1: number, y1: number, x2: number, y2: number) => GraphicsApi;
|
||||||
|
|
||||||
|
setColor: ((color: string) => GraphicsApi) &
|
||||||
|
((color: number) => GraphicsApi) &
|
||||||
|
((r: number, g: number, b: number) => GraphicsApi);
|
||||||
|
|
||||||
|
setFont: (name?: string, size?: number) => GraphicsApi;
|
||||||
|
|
||||||
|
setFontAlign: (
|
||||||
|
x: -1 | 0 | 1,
|
||||||
|
y: -1 | 0 | 1,
|
||||||
|
rotation?: 0 | 1 | 2 | 3
|
||||||
|
) => GraphicsApi;
|
||||||
|
|
||||||
|
setFontBitmap: () => GraphicsApi;
|
||||||
|
|
||||||
|
setFontCustom: (
|
||||||
|
bitmap: ArrayBuffer,
|
||||||
|
firstChar: number,
|
||||||
|
width: number | string,
|
||||||
|
height: number
|
||||||
|
) => GraphicsApi;
|
||||||
|
|
||||||
|
setFontVector: (size: number) => GraphicsApi;
|
||||||
|
|
||||||
|
setPixel: (
|
||||||
|
x: number,
|
||||||
|
y: number,
|
||||||
|
colour: number | string | undefined
|
||||||
|
) => GraphicsApi;
|
||||||
|
|
||||||
|
setRotation: (rotation: 0 | 1 | 2 | 3, reflect?: boolean) => GraphicsApi;
|
||||||
|
|
||||||
|
setTheme: (theme: Theme) => GraphicsApi;
|
||||||
|
|
||||||
|
stringMetrics: (str: string) => { width: number; height: number };
|
||||||
|
|
||||||
|
stringWidth: (str: string) => number;
|
||||||
|
|
||||||
|
theme: Theme;
|
||||||
|
|
||||||
|
toColor: ((color: string) => number) &
|
||||||
|
((color: number) => number) &
|
||||||
|
((r: number, g: number, b: number) => number);
|
||||||
|
|
||||||
|
transformVertices: (
|
||||||
|
verts: number[],
|
||||||
|
transformation:
|
||||||
|
| { x?: number; y?: number; scale?: number; rotate?: number }
|
||||||
|
| [number, number, number, number, number, number] // 2D transformation matrix
|
||||||
|
) => number[];
|
||||||
|
|
||||||
|
wrapString: (str: string, maxWidth: number) => string[];
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*~ This file declares the I2c class.
|
||||||
|
*~ Reference: https://banglejs.com/reference#I2C
|
||||||
|
*/
|
||||||
|
|
||||||
|
declare class I2C {
|
||||||
|
constructor();
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*~ These are the type declarations for Espruino on the Bangle.JS.
|
||||||
|
*~ Reference: https://banglejs.com/reference
|
||||||
|
*/
|
||||||
|
|
||||||
|
/// <reference path="globals.d.ts" />
|
||||||
|
/// <reference path="bangle.d.ts" />
|
||||||
|
/// <reference path="espruino.d.ts" />
|
||||||
|
/// <reference path="graphics.d.ts" />
|
||||||
|
/// <reference path="i2c.d.ts" />
|
||||||
|
/// <reference path="serial.d.ts" />
|
||||||
|
/// <reference path="spi.d.ts" />
|
||||||
|
/// <reference path="storage.d.ts" />
|
||||||
|
|
||||||
|
declare const Graphics: GraphicsApi;
|
||||||
|
declare const g: GraphicsApi;
|
||||||
|
|
||||||
|
type WidgetArea = "tl" | "tr" | "bl" | "br";
|
||||||
|
type Widget = {
|
||||||
|
area: WidgetArea;
|
||||||
|
width: number;
|
||||||
|
draw: (this: { x: number; y: number }) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
declare const WIDGETS: { [key: string]: Widget };
|
||||||
|
|
||||||
|
declare let exports: any;
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name": "banglejs",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"typings": "main.d.ts"
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
declare type Serial = {};
|
||||||
|
|
@ -0,0 +1,24 @@
|
||||||
|
declare type SPI = {
|
||||||
|
find(pin: Pin): SPIInstance | undefined;
|
||||||
|
new (): SPIInstance;
|
||||||
|
};
|
||||||
|
|
||||||
|
type TOrArray<T> = T | TOrArray<T>[];
|
||||||
|
type TArrObj<T> = T | TArrObj<T>[] | { data: TArrObj<T>; count: number };
|
||||||
|
type NumStrArr = TOrArray<number | string>;
|
||||||
|
|
||||||
|
declare type SPIInstance = {
|
||||||
|
send(data: TArrObj<number | string>, nss_pin: number): any;
|
||||||
|
send4bit(data: NumStrArr, bit0: number, bit1: number, nss_pin: number): void;
|
||||||
|
send8bit(data: NumStrArr, bit0: number, bit1: number, nss_pin: number): void;
|
||||||
|
setup(options: {
|
||||||
|
sck?: Pin;
|
||||||
|
miso?: Pin;
|
||||||
|
mosi?: Pin;
|
||||||
|
baud?: number;
|
||||||
|
mode?: 0 | 1 | 2 | 3;
|
||||||
|
order?: "msb" | "lsb";
|
||||||
|
bits?: number;
|
||||||
|
}): void;
|
||||||
|
write(...data: Array<Data | Pin>): void;
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
type FileData = string | Array<any> | Object;
|
||||||
|
|
||||||
|
declare interface Storage {
|
||||||
|
compact: () => void;
|
||||||
|
erase: (name: string) => void;
|
||||||
|
eraseAll: () => void;
|
||||||
|
getFree: () => number;
|
||||||
|
hash: (regex?: RegExp) => number; // More specifically it returns Uint32
|
||||||
|
list: (regex?: RegExp, filter?: { sf: boolean }) => string[];
|
||||||
|
open: (name: string, mode: "r" | "w" | "a") => StorageFile;
|
||||||
|
read: (name: string, offset?: number, length?: number) => string | undefined;
|
||||||
|
readArrayBuffer: (name: string) => ArrayBuffer | undefined;
|
||||||
|
readJSON: (name: string, noExceptions?: boolean) => any;
|
||||||
|
write: (
|
||||||
|
name: string,
|
||||||
|
data: FileData,
|
||||||
|
offset?: number,
|
||||||
|
size?: number
|
||||||
|
) => boolean;
|
||||||
|
writeJSON: (name: string, data: any) => boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
declare interface StorageFile {
|
||||||
|
erase: () => void;
|
||||||
|
getLength: () => number;
|
||||||
|
read: (len: number) => string | undefined;
|
||||||
|
readLine: () => string | undefined;
|
||||||
|
write: (data: FileData) => string;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue