mirror of https://github.com/espruino/BangleApps
Merge branch 'master' into stopw-ms-format
Conflicts: apps/clkinfostopw/settings.tspull/2697/head
commit
0eaa35cfe4
|
@ -31,3 +31,4 @@ clkinfo.addInteractive that would cause ReferenceError.
|
|||
0.29: use setItem of clockInfoMenu to change the active item
|
||||
0.30: Use widget_utils
|
||||
0.31: Use clock_info module as an app
|
||||
0.32: Make the border of the clock_info box extend all the way to the right of the screen.
|
||||
|
|
|
@ -135,7 +135,7 @@ let clockInfoMenu = clock_info.addInteractive(clockInfoItems, {
|
|||
app: "bwclk",
|
||||
x : 0,
|
||||
y: 135,
|
||||
w: W,
|
||||
w: W+1,
|
||||
h: H-135,
|
||||
draw : (itm, info, options) => {
|
||||
var hideClkInfo = info.text == null;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "bwclk",
|
||||
"name": "BW Clock",
|
||||
"version": "0.31",
|
||||
"version": "0.32",
|
||||
"description": "A very minimalistic clock.",
|
||||
"readme": "README.md",
|
||||
"icon": "app.png",
|
||||
|
|
|
@ -34,3 +34,4 @@ clkinfo.addInteractive that would cause ReferenceError.
|
|||
0.32: Diverge from BW Clock. Change out the custom font for a standard bitmap one to speed up loading times.
|
||||
Remove invertion of theme as this doesn'twork very well with fastloading.
|
||||
Do an quick inital fillRect on theclock info area.
|
||||
0.33: Make the border of the clock_info box extend all the way to the right of the screen.
|
||||
|
|
|
@ -95,7 +95,7 @@ let clockInfoMenu = clock_info.addInteractive(clockInfoItems, {
|
|||
app: "bwclklite",
|
||||
x : 0,
|
||||
y: 135,
|
||||
w: W,
|
||||
w: W+1,
|
||||
h: H-135,
|
||||
draw : (itm, info, options) => {
|
||||
let hideClkInfo = info.text == null;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "bwclklite",
|
||||
"name": "BW Clock Lite",
|
||||
"version": "0.32",
|
||||
"version": "0.33",
|
||||
"description": "A very minimalistic clock. This version of BW Clock is quicker at the cost of the custom font.",
|
||||
"readme": "README.md",
|
||||
"icon": "app.png",
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
((): ClockInfo.Menu => {
|
||||
(() => {
|
||||
let durationOnPause = "---";
|
||||
let redrawInterval: number | undefined;
|
||||
let startTime: number | undefined;
|
||||
|
@ -80,4 +80,4 @@
|
|||
}
|
||||
]
|
||||
};
|
||||
})
|
||||
}) satisfies ClockInfoFunc
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
const enum StopWatchFormat {
|
||||
HMS,
|
||||
Colon,
|
||||
}
|
||||
type StopWatchSettings = {
|
||||
format: StopWatchFormat,
|
||||
};
|
||||
|
||||
(back => {
|
||||
const SETTINGS_FILE = "clkinfostopw.setting.json";
|
||||
|
||||
const storage = require("Storage");
|
||||
const settings: StopWatchSettings = storage.readJSON(SETTINGS_FILE, true) || {};
|
||||
settings.format ??= StopWatchFormat.HMS;
|
||||
|
||||
const save = () => {
|
||||
storage.writeJSON(SETTINGS_FILE, settings)
|
||||
};
|
||||
|
||||
E.showMenu({
|
||||
"": { "title": "stopwatch" },
|
||||
"< Back": back,
|
||||
"Format": {
|
||||
value: settings.format,
|
||||
min: StopWatchFormat.HMS,
|
||||
max: StopWatchFormat.Colon,
|
||||
format: v => v === StopWatchFormat.HMS ? "12m34s" : "12:34",
|
||||
onchange: v => {
|
||||
settings.format = v;
|
||||
save();
|
||||
},
|
||||
},
|
||||
});
|
||||
}) satisfies SettingsFunc
|
|
@ -0,0 +1 @@
|
|||
0.01: New app!
|
|
@ -0,0 +1,33 @@
|
|||
# Drained
|
||||
|
||||
With this app installed, your Bangle will automatically switch into low power mode when the battery reaches 5% battery (or a preconfigured percentage), displaying a simple clock. When the battery is then charged above 20% (also configurable), normal operation is restored.
|
||||
|
||||
Low power mode can also be exited manually, by tapping the primary watch button (an initial tap may be required to unlock the watch).
|
||||
|
||||
# Features
|
||||
|
||||
## Persistence
|
||||
- [x] Restore normal operation with sufficient charge
|
||||
- [x] Reactivate on watch startup
|
||||
|
||||
## Time
|
||||
- [x] Show simple date/time
|
||||
- [ ] Disable alarms - with a setting?
|
||||
- [ ] Smarter/backoff interval for checking battery percentage
|
||||
|
||||
## No backlight (#2502)
|
||||
- [x] LCD brightness
|
||||
- [ ] LCD timeout?
|
||||
|
||||
## Peripherals
|
||||
- [x] Disable auto heart rate measurement in health app (#2502)
|
||||
- [x] Overwrite setGPSPower() function (#2502)
|
||||
- [x] Turn off already-running GPS / HRM
|
||||
|
||||
## Features
|
||||
- [x] Wake on twist -> off (#2502)
|
||||
- [x] Emit `"drained"` event
|
||||
|
||||
# Creator
|
||||
|
||||
- [bobrippling](https://github.com/bobrippling/)
|
|
@ -0,0 +1,102 @@
|
|||
var app = "drained";
|
||||
if (typeof drainedInterval !== "undefined")
|
||||
drainedInterval = clearInterval(drainedInterval);
|
||||
Bangle.setLCDBrightness(0);
|
||||
var powerNoop = function () { return false; };
|
||||
var forceOff = function (name) {
|
||||
var _a;
|
||||
if ((_a = Bangle._PWR) === null || _a === void 0 ? void 0 : _a[name])
|
||||
Bangle._PWR[name] = [];
|
||||
Bangle["set".concat(name, "Power")](0, app);
|
||||
Bangle["set".concat(name, "Power")] = powerNoop;
|
||||
};
|
||||
forceOff("GPS");
|
||||
forceOff("HRM");
|
||||
try {
|
||||
NRF.disconnect();
|
||||
NRF.sleep();
|
||||
}
|
||||
catch (e) {
|
||||
console.log("couldn't disable ble: ".concat(e));
|
||||
}
|
||||
Bangle.removeAllListeners();
|
||||
clearWatch();
|
||||
Bangle.setOptions({
|
||||
wakeOnFaceUp: 0,
|
||||
wakeOnTouch: 0,
|
||||
wakeOnTwist: 0,
|
||||
});
|
||||
var nextDraw;
|
||||
var draw = function () {
|
||||
var x = g.getWidth() / 2;
|
||||
var y = g.getHeight() / 2 - 48;
|
||||
var date = new Date();
|
||||
var timeStr = require("locale").time(date, 1);
|
||||
var dateStr = require("locale").date(date, 0).toUpperCase() +
|
||||
"\n" +
|
||||
require("locale").dow(date, 0).toUpperCase();
|
||||
g.reset()
|
||||
.clearRect(Bangle.appRect)
|
||||
.setFont("Vector", 55)
|
||||
.setFontAlign(0, 0)
|
||||
.drawString(timeStr, x, y)
|
||||
.setFont("Vector", 24)
|
||||
.drawString(dateStr, x, y + 56)
|
||||
.drawString("".concat(E.getBattery(), "%"), x, y + 104);
|
||||
if (nextDraw)
|
||||
clearTimeout(nextDraw);
|
||||
nextDraw = setTimeout(function () {
|
||||
nextDraw = undefined;
|
||||
draw();
|
||||
}, 60000 - (date.getTime() % 60000));
|
||||
};
|
||||
var reload = function () {
|
||||
Bangle.setUI({
|
||||
mode: "custom",
|
||||
remove: function () {
|
||||
if (nextDraw)
|
||||
clearTimeout(nextDraw);
|
||||
nextDraw = undefined;
|
||||
},
|
||||
btn: function () {
|
||||
E.showPrompt("Restore watch to full power?").then(function (v) {
|
||||
if (v) {
|
||||
drainedRestore();
|
||||
}
|
||||
else {
|
||||
reload();
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
Bangle.CLOCK = 1;
|
||||
g.clear();
|
||||
draw();
|
||||
};
|
||||
reload();
|
||||
Bangle.emit("drained", E.getBattery());
|
||||
var _a = require("Storage").readJSON("".concat(app, ".setting.json"), true) || {}, _b = _a.disableBoot, disableBoot = _b === void 0 ? false : _b, _c = _a.restore, restore = _c === void 0 ? 20 : _c;
|
||||
function drainedRestore() {
|
||||
if (disableBoot) {
|
||||
try {
|
||||
eval(require('Storage').read('bootupdate.js'));
|
||||
}
|
||||
catch (e) {
|
||||
console.log("error restoring bootupdate:" + e);
|
||||
}
|
||||
}
|
||||
load();
|
||||
}
|
||||
if (disableBoot) {
|
||||
var checkCharge_1 = function () {
|
||||
if (E.getBattery() < restore)
|
||||
return;
|
||||
drainedRestore();
|
||||
};
|
||||
if (Bangle.isCharging())
|
||||
checkCharge_1();
|
||||
Bangle.on("charging", function (charging) {
|
||||
if (charging)
|
||||
checkCharge_1();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,127 @@
|
|||
const app = "drained";
|
||||
|
||||
// from boot.js
|
||||
declare var drainedInterval: number | undefined;
|
||||
if(typeof drainedInterval !== "undefined")
|
||||
drainedInterval = clearInterval(drainedInterval) as undefined;
|
||||
|
||||
// backlight
|
||||
Bangle.setLCDBrightness(0);
|
||||
|
||||
// peripherals
|
||||
const powerNoop = () => false;
|
||||
|
||||
const forceOff = (name: "GPS" | "HRM" | "Compass" /*| "Barom"*/) => {
|
||||
if ((Bangle as any)._PWR?.[name])
|
||||
(Bangle as any)._PWR[name] = [];
|
||||
|
||||
// if(name === "Barom"){ setBarometerPower(...) }
|
||||
// ^^^^
|
||||
Bangle[`set${name}Power`](0, app);
|
||||
Bangle[`set${name}Power`] = powerNoop;
|
||||
};
|
||||
forceOff("GPS");
|
||||
forceOff("HRM");
|
||||
try{
|
||||
NRF.disconnect();
|
||||
NRF.sleep();
|
||||
}catch(e){
|
||||
console.log(`couldn't disable ble: ${e}`);
|
||||
}
|
||||
|
||||
// events
|
||||
Bangle.removeAllListeners();
|
||||
clearWatch();
|
||||
|
||||
// UI
|
||||
Bangle.setOptions({
|
||||
wakeOnFaceUp: 0,
|
||||
wakeOnTouch: 0,
|
||||
wakeOnTwist: 0,
|
||||
});
|
||||
|
||||
// clock
|
||||
let nextDraw: number | undefined;
|
||||
const draw = () => {
|
||||
const x = g.getWidth() / 2;
|
||||
const y = g.getHeight() / 2 - 48;
|
||||
|
||||
const date = new Date();
|
||||
|
||||
const timeStr = require("locale").time(date, 1);
|
||||
const dateStr = require("locale").date(date, 0).toUpperCase() +
|
||||
"\n" +
|
||||
require("locale").dow(date, 0).toUpperCase();
|
||||
|
||||
g.reset()
|
||||
.clearRect(Bangle.appRect)
|
||||
.setFont("Vector", 55)
|
||||
.setFontAlign(0, 0)
|
||||
.drawString(timeStr, x, y)
|
||||
.setFont("Vector", 24)
|
||||
.drawString(dateStr, x, y + 56)
|
||||
.drawString(`${E.getBattery()}%`, x, y + 104);
|
||||
|
||||
if(nextDraw) clearTimeout(nextDraw);
|
||||
nextDraw = setTimeout(() => {
|
||||
nextDraw = undefined;
|
||||
draw();
|
||||
}, 60000 - (date.getTime() % 60000));
|
||||
};
|
||||
|
||||
const reload = () => {
|
||||
Bangle.setUI({
|
||||
mode: "custom",
|
||||
remove: () => {
|
||||
if (nextDraw) clearTimeout(nextDraw);
|
||||
nextDraw = undefined;
|
||||
},
|
||||
btn: () => {
|
||||
E.showPrompt("Restore watch to full power?").then(v => {
|
||||
if(v){
|
||||
drainedRestore();
|
||||
}else{
|
||||
reload();
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
Bangle.CLOCK=1;
|
||||
|
||||
g.clear();
|
||||
draw();
|
||||
};
|
||||
reload();
|
||||
|
||||
// permit other apps to put themselves into low-power mode
|
||||
Bangle.emit("drained", E.getBattery());
|
||||
|
||||
// restore normal boot on charge
|
||||
const { disableBoot = false, restore = 20 }: DrainedSettings
|
||||
= require("Storage").readJSON(`${app}.setting.json`, true) || {};
|
||||
|
||||
// re-enable normal boot code when we're above a threshold:
|
||||
function drainedRestore() { // "public", to allow users to call
|
||||
if(disableBoot){
|
||||
try{
|
||||
eval(require('Storage').read('bootupdate.js'));
|
||||
}catch(e){
|
||||
console.log("error restoring bootupdate:" + e);
|
||||
}
|
||||
}
|
||||
load(); // necessary after updating boot.0
|
||||
}
|
||||
|
||||
if(disableBoot){
|
||||
const checkCharge = () => {
|
||||
if(E.getBattery() < restore) return;
|
||||
drainedRestore();
|
||||
};
|
||||
|
||||
if (Bangle.isCharging())
|
||||
checkCharge();
|
||||
|
||||
Bangle.on("charging", charging => {
|
||||
if(charging) checkCharge();
|
||||
});
|
||||
}
|
|
@ -0,0 +1,13 @@
|
|||
{
|
||||
var _a = require("Storage").readJSON("drained.setting.json", true) || {}, _b = _a.battery, threshold_1 = _b === void 0 ? 5 : _b, _c = _a.interval, interval = _c === void 0 ? 10 : _c, _d = _a.disableBoot, disableBoot_1 = _d === void 0 ? false : _d;
|
||||
drainedInterval = setInterval(function () {
|
||||
if (Bangle.isCharging())
|
||||
return;
|
||||
if (E.getBattery() > threshold_1)
|
||||
return;
|
||||
var app = "drained.app.js";
|
||||
if (disableBoot_1)
|
||||
require("Storage").write(".boot0", "if(typeof __FILE__ === \"undefined\" || __FILE__ !== \"".concat(app, "\") setTimeout(load, 100, \"").concat(app, "\");"));
|
||||
load(app);
|
||||
}, interval * 60 * 1000);
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
const { battery: threshold = 5, interval = 10, disableBoot = false }: DrainedSettings
|
||||
= require("Storage").readJSON(`drained.setting.json`, true) || {};
|
||||
|
||||
drainedInterval = setInterval(() => {
|
||||
if(Bangle.isCharging())
|
||||
return;
|
||||
if(E.getBattery() > threshold)
|
||||
return;
|
||||
|
||||
const app = "drained.app.js";
|
||||
|
||||
if(disableBoot)
|
||||
require("Storage").write(
|
||||
".boot0",
|
||||
`if(typeof __FILE__ === "undefined" || __FILE__ !== "${app}") setTimeout(load, 100, "${app}");`
|
||||
);
|
||||
|
||||
load(app);
|
||||
}, interval * 60 * 1000);
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 469 B |
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"id": "drained",
|
||||
"name": "Drained",
|
||||
"version": "0.01",
|
||||
"description": "Switches to displaying a simple clock when the battery percentage is low, and disables some peripherals",
|
||||
"readme": "README.md",
|
||||
"icon": "icon.png",
|
||||
"type": "clock",
|
||||
"tags": "clock",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"drained.boot.js","url":"boot.js"},
|
||||
{"name":"drained.app.js","url":"app.js"},
|
||||
{"name":"drained.settings.js","url":"settings.js"}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
(function (back) {
|
||||
var _a, _b, _c, _d;
|
||||
var SETTINGS_FILE = "drained.setting.json";
|
||||
var storage = require("Storage");
|
||||
var settings = storage.readJSON(SETTINGS_FILE, true) || {};
|
||||
(_a = settings.battery) !== null && _a !== void 0 ? _a : (settings.battery = 5);
|
||||
(_b = settings.restore) !== null && _b !== void 0 ? _b : (settings.restore = 20);
|
||||
(_c = settings.interval) !== null && _c !== void 0 ? _c : (settings.interval = 10);
|
||||
(_d = settings.disableBoot) !== null && _d !== void 0 ? _d : (settings.disableBoot = false);
|
||||
var save = function () {
|
||||
storage.writeJSON(SETTINGS_FILE, settings);
|
||||
};
|
||||
E.showMenu({
|
||||
"": { "title": "Drained" },
|
||||
"< Back": back,
|
||||
"Keep startup code": {
|
||||
value: settings.disableBoot,
|
||||
format: function () { return settings.disableBoot ? "No" : "Yes"; },
|
||||
onchange: function () {
|
||||
settings.disableBoot = !settings.disableBoot;
|
||||
save();
|
||||
},
|
||||
},
|
||||
"Trigger at batt%": {
|
||||
value: settings.battery,
|
||||
min: 0,
|
||||
max: 95,
|
||||
step: 5,
|
||||
format: function (v) { return "".concat(v, "%"); },
|
||||
onchange: function (v) {
|
||||
settings.battery = v;
|
||||
save();
|
||||
},
|
||||
},
|
||||
"Poll interval": {
|
||||
value: settings.interval,
|
||||
min: 1,
|
||||
max: 60 * 2,
|
||||
step: 5,
|
||||
format: function (v) { return "".concat(v, " mins"); },
|
||||
onchange: function (v) {
|
||||
settings.interval = v;
|
||||
save();
|
||||
},
|
||||
},
|
||||
"Restore watch at %": {
|
||||
value: settings.restore,
|
||||
min: 0,
|
||||
max: 95,
|
||||
step: 5,
|
||||
format: function (v) { return "".concat(v, "%"); },
|
||||
onchange: function (v) {
|
||||
settings.restore = v;
|
||||
save();
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
|
@ -0,0 +1,67 @@
|
|||
type DrainedSettings = {
|
||||
battery?: number,
|
||||
restore?: number,
|
||||
interval?: number,
|
||||
disableBoot?: ShortBoolean,
|
||||
};
|
||||
|
||||
(back => {
|
||||
const SETTINGS_FILE = "drained.setting.json";
|
||||
|
||||
const storage = require("Storage")
|
||||
const settings: DrainedSettings = storage.readJSON(SETTINGS_FILE, true) || {};
|
||||
settings.battery ??= 5;
|
||||
settings.restore ??= 20;
|
||||
settings.interval ??= 10;
|
||||
settings.disableBoot ??= false;
|
||||
|
||||
const save = () => {
|
||||
storage.writeJSON(SETTINGS_FILE, settings)
|
||||
};
|
||||
|
||||
E.showMenu({
|
||||
"": { "title": "Drained" },
|
||||
"< Back": back,
|
||||
"Keep startup code": {
|
||||
value: settings.disableBoot,
|
||||
format: () => settings.disableBoot ? "No" : "Yes",
|
||||
onchange: () => {
|
||||
settings.disableBoot = !settings.disableBoot;
|
||||
save();
|
||||
},
|
||||
},
|
||||
"Trigger at batt%": {
|
||||
value: settings.battery,
|
||||
min: 0,
|
||||
max: 95,
|
||||
step: 5,
|
||||
format: (v: number) => `${v}%`,
|
||||
onchange: (v: number) => {
|
||||
settings.battery = v;
|
||||
save();
|
||||
},
|
||||
},
|
||||
"Poll interval": {
|
||||
value: settings.interval,
|
||||
min: 1,
|
||||
max: 60 * 2,
|
||||
step: 5,
|
||||
format: (v: number) => `${v} mins`,
|
||||
onchange: (v: number) => {
|
||||
settings.interval = v;
|
||||
save();
|
||||
},
|
||||
},
|
||||
"Restore watch at %": {
|
||||
value: settings.restore,
|
||||
min: 0,
|
||||
max: 95,
|
||||
step: 5,
|
||||
format: (v: number) => `${v}%`,
|
||||
onchange: (v: number) => {
|
||||
settings.restore = v;
|
||||
save();
|
||||
},
|
||||
},
|
||||
});
|
||||
}) satisfies SettingsFunc
|
|
@ -1,3 +1,3 @@
|
|||
0.20: New App!
|
||||
0.21: Tell clock widgets to hide.
|
||||
|
||||
0.22: Changed font so 5 and 6 are not similar
|
||||
|
|
|
@ -1,13 +1,36 @@
|
|||
Graphics.prototype.setFontLECO1976Regular42 = function (scale) {
|
||||
|
||||
Graphics.prototype.setFontLECO1976Regular5fix42 = function(scale) {
|
||||
// Actual height 42 (41 - 0)
|
||||
g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAAAAAAA/AAAAAAAAH/AAAAAAAA//AAAAAAAP//AAAAAAB///AAAAAAP///AAAAAB////AAAAAf////AAAAD////4AAAAf////AAAAH////4AAAA////+AAAAA////wAAAAA///+AAAAAA///gAAAAAA//8AAAAAAA//gAAAAAAA/4AAAAAAAA/AAAAAAAAA4AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAH/AAAAAAAAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA//h////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////gD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4AAAH/AAA/4B/gH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAA////wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAAAAB/wAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA////x//AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/4B////AAA/wB////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA//gAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA/4AAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA////wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA/4B/wH/AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAA///////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAP+AAH/AAAAH+AAD/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"), 46, atob("ERkmHyYmJiYmJCYmEQ=="), 60 + (scale << 8) + (1 << 16));
|
||||
this.setFontCustom(
|
||||
E.toString(require('heatshrink').decompress(atob('ADMD/gHFv/AAwkHB3QAtngGFj47Fh5KFh//BwkH/4OEgf/BwgGCBwcBAwIOEAwQODAwX/wB7CCos/Awo/BAAPgDgvwJwgGEBwX4LoplFAw0P/yCF/4GFh6YGKgQAhNAZGDAwZ4CB3ibCg4ODZoYO/BwyV/BxIA7YX7C/YRRZCAAZZDB2AAgNAMHO4v4O42PB3P4AIL+EwABBQwQO/BwgABBwgGBB34A0h/wAYMDSogDBSogGBUgoOOd/4O2AAbgEAAIO+AGY7C/AHDIIWAB3wQCBwjiDB34OGf1gOdAGbgDgZKFwF/JQn4g4O3/ABBBwmAB34OLcAgOBd4oO6AGY5CJQoADd4gO5f2wOdf1IOdAEgqBA4v//AOGwAO5AwqGCB34OJAAbRCAwbgDB3QAzO/4OL/ABBg4ODwABBv4O/BwyV/BxIAzHYX4gZKFSogOCSowOxf2gOdf1YOdAGkH/EAgY7DSgMASoSWCCIIO3ADg='))),
|
||||
46,
|
||||
atob("ERkmICYmJiYmJCYmEQ=="),
|
||||
60+(scale<<8)+(1<<16)
|
||||
);
|
||||
return this;
|
||||
};
|
||||
|
||||
Graphics.prototype.setFontLECO1976Regular22 = function (scale) {
|
||||
Graphics.prototype.setFontLECO1976Regular5fix22 = function(scale) {
|
||||
// Actual height 22 (21 - 0)
|
||||
g.setFontCustom(atob("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAP/nA/+cD/5wP/nAAAAAAAAPwAA/gAD+AAPwAAAAAD+AAP4AA/gAAAAAAAAAAAAAcOAP//A//8D//wP//AHDgAcOAP//A//8D//wP//AHDgAAAAAAAAH/jgf+OB/44H/jj8OP/w4//Dj/8OPxw/4HD/gcP+Bw/4AAAAAAAP+AA/8AD/wQOHHA4c8D//wP/8A//gAD4AAfAAH/8A//wP//A84cDjhwIP/AA/8AB/wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8ABwAAAAAAAAD8AAP4AA/gAD8AAAAAAAAAAAEAAD+AB//A///v/D//gB/wABwAAAAAADgAA/wAf/4P8///wf/4AP8AAOAAAAAAAAAyAAHcAAPwAD/gAP/AA/8AA/AAH8AAMwAAAAAAAAAAAAADgAAOAAA4AAf8AD/wAP/AA/8AAOAAA4AADgAAAAAAAAAAD8AAfwAB/AAD8AAAAAAAADgAAOAAA4AADgAAOAAA4AADgAAAAAAAAAADgAAOAAA4AADgAAAAAAAAABwAB/AA/8A//gP/gA/wADwAAIAAAAAAD//wP//A//8D//wOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA4AcDgBwOAHA//8D//wP//A//8AABwAAHAAAcAAAAAAAA+f8D5/wPn/A+f8DhxwOHHA4ccDhxwP/HA/8cD/xwP/HAAAAAAAAOAHA4AcDhxwOHHA4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/wAP/AA/8AD/wAAHAAAcAABwAAHAA//8D//wP//A//8AAAAAAAA/98D/3wP/fA/98DhxwOHHA4ccDhxwOH/A4f8Dh/wOH/AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccDh/wOH/A4f8Dh/wAAAAAAAD4AAPgAA+AADgAAOAAA4AADgAAP//A//8D//wP//AAAAAAAAP//A//8D//wP//A4ccDhxwOHHA4ccD//wP//A//8D//wAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA//8D//wP//A//8AAAAAAAAOA4A4DgDgOAOA4AAAAAAAAOA/A4H8DgfwOA/AAAAAAAAB4AAPwAA/AAD8AAf4ABzgAPPAA8cAHh4AAAAAAAAAAAAHHAAccABxwAHHAAccABxwAHHAAccABxwAHHAAAAAAAAAOHAA4cADzwAPPAAf4AB/gAD8AAPwAAeAAB4AAAAAAAAA+AAD4AAPgAA+ecDh9wOH3A4fcDhwAP/AA/8AD/wAP/AAAAAAAAAP//4///j//+P//44ADjn/OOf845/zjnHOP8c4//zj//OP/84AAAAAAAP//A//8D//wP//A4cADhwAOHAA4cAD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA//8D//wP9/A/j8AAAAAAAA//8D//wP//A//8DgBwOAHA4AcDgBwOAHA4AcDgBwOAHAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA8A8D//wH/+AP/wAf+AAAAAAAAD//wP//A//8D//wOHHA4ccDhxwOHHA4ccDhxwOAHA4AcAAAAAAAA//8D//wP//A//8DhwAOHAA4cADhwAOHAA4cADgAAOAAAAAAD//wP//A//8D//wOAHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA//8D//wP//A//8ABwAAHAAAcAABwAP//A//8D//wP//AAAAAAAAP//A//8D//wP//AAAAAAAAOAHA4AcDgBwOAHA4AcDgBwOAHA//8D//wP//A//8AAAAAAAA//8D//wP//A//8AHwAA/AAP8AB/wAPn/A8f8DB/wIH/AAAAAAAAP//A//8D//wP//AAAcAABwAAHAAAcAABwAAHAAAAAAAAP//A//8D//wP//Af8AAP+AAH/AAD8AAHwAD/AB/wAf8AP+AA//8D//wP//AAAAAAAAP//A//8D//wP//AfwAAfwAAfwAAfwAAfwP//A//8D//wAAAAAAAAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//wP//A//8D//wAAAAAAAD//wP//A//8D//wOHAA4cADhwAOHAA/8AD/wAP/AA/8AAAAAP//A//8D//wP//A4AcDgBwOAHA4AcD//+P//4///j//+AAA4AADgAAAP//A//8D//wP//A4eADh+AOH8A4f4D/3wP/HA/8MD/wQAAAAAAAD/xwP/HA/8cD/xwOHHA4ccDhxwOHHA4f8Dh/wOH/A4f8AAAAAAAA4AADgAAOAAA//8D//wP//A//8DgAAOAAA4AADgAAAAAA//8D//wP//A//8AABwAAHAAAcAABwP//A//8D//wP//AAAADAAAPgAA/wAD/4AB/8AA/8AAfwAB/AA/8Af+AP/AA/wAD4AAMAAA4AAD+AAP/gA//8AH/wAB/AAf8Af/wP/4A/4AD/gAP/4AH/8AB/wAB/AB/8D//wP/gA/gADgAAIABA4AcDwDwPw/Afn4Af+AA/wAD/AA//AH5+A/D8DwDwOAHAgAEAAAAP/AA/8AD/wAP/AAAf8AB/wAH/AAf8D/wAP/AA/8AD/wAAAAAAAADh/wOH/A4f8Dh/wOHHA4ccDhxwOHHA/8cD/xwP/HA/8cAAAAAAAAf//9///3///f//9wAA3AADcAAMAAAOAAA/gAD/wAH/8AB/8AA/wAAPAAAEAAAAHAADcAANwAB3///f//9///wAA"), 32, atob("BwYLDg4UDwYJCQwMBgkGCQ4MDg4ODg4NDg4GBgwMDA4PDg4ODg4NDg4GDQ4MEg8ODQ8ODgwODhQODg4ICQg="), 22 + (scale << 8) + (1 << 16));
|
||||
this.setFontCustom(
|
||||
E.toString(require('heatshrink').decompress(atob('AAs8AYV8AaQjOgP8AYMPAYV/AYMH/4DBn///EA///4ADB/wSB//gAYQlCCIIABCIIAFDYIjBAaYjBLYIDTF64AH+CDCGdLLV/i7C/wfCAZ/4/BPCAaTiBAaaHBABaPIIaxPMcbxbBAapgCAahPhVYLDTUbA7CAZ/wv5PKN6xPzAof+AaTuXdcCbuJ8H4ngDCE4QDOJ+8PgBPBh+AE4IDPAA4'))),
|
||||
46,
|
||||
atob("CQ0UERQUFBQUExQUCQ=="),
|
||||
32+(scale<<8)+(1<<16)
|
||||
);
|
||||
return this;
|
||||
};
|
||||
|
||||
Graphics.prototype.setFontLECO1976Regular5fix11 = function(scale) {
|
||||
// Actual height 11 (10 - 0)
|
||||
this.setFontCustom(
|
||||
E.toString(require('heatshrink').decompress(atob('AAMBwEDgEGgECgF8g/4v/w/+B+ARBg//h/+j/8mEYsEw//h//D/+AgEMg0Yhk/DofggHAFwMAh9+j38nv4scw41h/nD/OH+YdC5kxzAODxgsBw47CIIM/wF/gAGBhkAjBKFCAN/mH+FgUZw0zhl+jH8mP4CAJZEBwVmBwdj+HwgPggfAQoIxBFgJoDSwUDJQhZDO4QsB4CVB+cP80fNAiVGgaWDmAA=='))),
|
||||
46,
|
||||
atob("BAYJCAkJCQkJCQkJBA=="),
|
||||
15+(scale<<8)+(1<<16)
|
||||
);
|
||||
return this;
|
||||
};
|
||||
|
||||
require("Font7x11Numeric7Seg").add(Graphics);
|
||||
|
||||
|
@ -60,7 +83,7 @@ function drawCal() {
|
|||
const CAL_Y = g.getHeight() - 44; // Bangle.appRect.y+this.DATE_FONT_SIZE()+10+this.TIME_FONT_SIZE()+3;
|
||||
const CAL_AREA_H = 44; // g.getHeight()-CAL_Y+24; //+24: top widgtes only
|
||||
const CELL_W = g.getWidth() / 7; //cell width
|
||||
const CELL_H = (CAL_AREA_H - DAY_NAME_FONT_SIZE) / 3; //cell heigth
|
||||
const CELL_H = 1+parseInt((CAL_AREA_H - DAY_NAME_FONT_SIZE) / 3); //cell heigth
|
||||
const DAY_NUM_FONT_SIZE = Math.min(CELL_H + 3, 15); //size down, max 15
|
||||
|
||||
const wdStrt = 1;
|
||||
|
@ -73,11 +96,14 @@ function drawCal() {
|
|||
const tdyNumClr = 0; // today fg
|
||||
|
||||
g.setFont("Vector", DAY_NAME_FONT_SIZE + 3);
|
||||
|
||||
|
||||
|
||||
g.setColor(nrgb[1]);
|
||||
g.setFontAlign(-1, -1);
|
||||
// g.clearRect(Bangle.appRect.x, CAL_Y, Bangle.appRect.x2, CAL_Y+CAL_AREA_H);
|
||||
|
||||
//draw grid & Headline
|
||||
// == draw grid & Headline ==
|
||||
const dNames = ABR_DAY.map((a) => a.length <= 2 ? a : a.substr(0, 2)); //force shrt 2
|
||||
for (var dNo = 0; dNo < dNames.length; dNo++) {
|
||||
const dIdx = wdStrt >= 0 ? ((wdStrt + dNo) % 7) : ((dNo + d.getDay() + 4) % 7);
|
||||
|
@ -103,9 +129,10 @@ function drawCal() {
|
|||
// horizontal lines
|
||||
// for(i=0; i<3; i++){ const y=nextY+i*CELL_H; g.drawLine(Bangle.appRect.x, y, Bangle.appRect.x2, y); }
|
||||
|
||||
g.setFont("Vector", DAY_NUM_FONT_SIZE);
|
||||
// g.setFont("Vector", DAY_NUM_FONT_SIZE);
|
||||
|
||||
g.setFont("7x11Numeric7Seg", 1);
|
||||
// g.setFont("7x11Numeric7Seg", 1);
|
||||
g.setFontLECO1976Regular5fix11();
|
||||
|
||||
//write days
|
||||
const tdyDate = d.getDate();
|
||||
|
@ -113,16 +140,38 @@ function drawCal() {
|
|||
var rD = new Date(d.getTime());
|
||||
rD.setDate(rD.getDate() - days);
|
||||
var rDate = rD.getDate();
|
||||
|
||||
// == today background rectangle ==
|
||||
for (var y = 0; y < 3; y++) {
|
||||
for (var x = 0; x < dNames.length; x++) {
|
||||
if (rDate === tdyDate) { //today
|
||||
g.setColor(nrgb[tdyMrkClr]); //today marker color or fg color
|
||||
|
||||
// rectangle
|
||||
g.fillRect(x * CELL_W, nextY + CELL_H - 1, x * CELL_W + CELL_W, nextY + CELL_H + CELL_H - 1);
|
||||
g.setColor(nrgb[tdyNumClr]); //today color or fg color
|
||||
var frm=3; // fame pixels
|
||||
g.drawRect(x * CELL_W-frm, nextY + CELL_H - 1-frm, x * CELL_W + CELL_W+frm, nextY + CELL_H + CELL_H - 1+frm);
|
||||
}
|
||||
rD.setDate(rDate + 1);
|
||||
rDate = rD.getDate();
|
||||
}
|
||||
}
|
||||
|
||||
// == individual days ==
|
||||
rD = new Date(d.getTime());
|
||||
rD.setDate(rD.getDate() - days);
|
||||
rDate = rD.getDate();
|
||||
for (var y = 0; y < 3; y++) {
|
||||
for (var x = 0; x < dNames.length; x++) {
|
||||
if (rDate === tdyDate) { //today
|
||||
g.setColor(nrgb[tdyMrkClr]); //today marker color or fg color
|
||||
|
||||
// rectangle
|
||||
// g.fillRect(x * CELL_W, nextY + CELL_H - 1, x * CELL_W + CELL_W, nextY + CELL_H + CELL_H - 1);
|
||||
// g.setColor(nrgb[tdyNumClr]); //today color or fg color
|
||||
// g.drawRect(x * CELL_W, nextY + CELL_H - 1, x * CELL_W + CELL_W, nextY + CELL_H + CELL_H - 1);
|
||||
|
||||
// simulate "bold"
|
||||
// g.setColor(nrgb[tdyNumClr]); //today color or fg color
|
||||
g.drawString(rDate, 1 + x * CELL_W + ((CELL_W - g.stringWidth(rDate)) / 2) + 2, nextY + ((CELL_H - DAY_NUM_FONT_SIZE + 2) / 2) + (CELL_H * y));
|
||||
|
||||
} else if (IS_SUNDAY[rD.getDay()]) { //sundays
|
||||
|
@ -153,7 +202,7 @@ function draw() {
|
|||
|
||||
// g.setFont('Vector', 30);
|
||||
// g.setFont("7x11Numeric7Seg", 5);
|
||||
g.setFontLECO1976Regular42();
|
||||
g.setFontLECO1976Regular5fix42();
|
||||
g.setFontAlign(0, -1);
|
||||
g.drawString(timeString(h, m), g.getWidth() / 2, 28);
|
||||
g.drawString(dayString(d), g.getWidth() * 3 / 4, 88);
|
||||
|
@ -162,7 +211,7 @@ function draw() {
|
|||
g.reset();
|
||||
|
||||
// Steps
|
||||
g.setFontLECO1976Regular22();
|
||||
g.setFontLECO1976Regular5fix22();
|
||||
g.setFontAlign(-1, -1);
|
||||
g.drawString(getSteps(), 8, 88);
|
||||
|
||||
|
@ -200,4 +249,4 @@ Bangle.on('lcdPower', on => {
|
|||
});
|
||||
|
||||
|
||||
Bangle.drawWidgets();
|
||||
Bangle.drawWidgets();
|
|
@ -2,7 +2,7 @@
|
|||
"id": "glbasic",
|
||||
"name": "GLBasic Clock",
|
||||
"shortName": "GLBasic",
|
||||
"version": "0.21",
|
||||
"version": "0.22",
|
||||
"description": "A clock with large numbers",
|
||||
"dependencies": {"widpedom":"app"},
|
||||
"icon": "icon48.png",
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
0.01: New App!
|
||||
0.02: Display icon of the message origin's app
|
|
@ -0,0 +1,13 @@
|
|||
# XXL Message app
|
||||
This app displays an incomming message with a very large
|
||||
font and scrolls the text. For people who can't read the
|
||||
menu font without glasses, this might be an alternative
|
||||
to the default messages UI app.
|
||||
|
||||
When arrived, new messages are displayed instantly on the screen.
|
||||
When the message fully scrolled two times or
|
||||
if you touch the screen or press the button,
|
||||
the default clock is loaded.
|
||||
|
||||
Nothing more, nothing less.
|
||||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwwcA/4A/AH4A/AH2SpMkAQ1/CI3+CI+fB4v5AQQRFk4JB84REBAXkCIgLFEAYsCIgo+BCIwLEC4oRHF4w7CCJAIRGQaDECLQIRLKB9QUKDFRdKB3GQYwAFBwpKFAAhEFAQokHAH4A/AH4A/ABA"))
|
|
@ -0,0 +1,42 @@
|
|||
|
||||
|
||||
if (require("Storage").read("messagegui")){ // "messagegui" module is installed
|
||||
require("messages").openGUI();
|
||||
console.log("Opened Messages UI");
|
||||
Bangle.load("messagegui");
|
||||
}
|
||||
|
||||
|
||||
function stop() {
|
||||
g.setBgColor(0, 1, 1);
|
||||
g.clear();
|
||||
g.reset();
|
||||
load();
|
||||
}
|
||||
var txt = 'No Messages';
|
||||
try{
|
||||
console.log("try delete messages");
|
||||
var MESSAGES = require("messages").getMessages();
|
||||
MESSAGES = [];
|
||||
txt = 'Deleted all messages';
|
||||
console.log("worked");
|
||||
}catch(e){}
|
||||
g.setBgColor('#ffff00');
|
||||
g.setColor('#000000');
|
||||
g.clear();
|
||||
|
||||
g.setFont('6x8:3');
|
||||
g.setFontAlign(0, 0);
|
||||
g.setColor('#000000');
|
||||
g.drawString(g.wrapString(txt, g.getWidth()).join("\n"), g.getWidth()/2, g.getHeight()/2);
|
||||
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
|
||||
//E.showMessage(txt,{
|
||||
// title:"XXL Messages",
|
||||
// img:atob("FBQBAfgAf+Af/4P//D+fx/n+f5/v+f//n//5//+f//n////3//5/n+P//D//wf/4B/4AH4A=") // (i)
|
||||
//})
|
||||
|
||||
setTimeout(stop, 4000);
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 315 B |
|
@ -0,0 +1 @@
|
|||
Bangle.on("message", (type, msg) => require("xxlmessage.lib.js").listener(type, msg));
|
|
@ -0,0 +1,133 @@
|
|||
// GB({"t":"notify","id":1575479849,"src":"Hangouts","title":"A Name","body":"message contents"})
|
||||
var xxl = {
|
||||
// private:
|
||||
msg: [],
|
||||
drawTimeout: undefined,
|
||||
xpos : 0,
|
||||
loopCount : 0,
|
||||
txt:'',
|
||||
wtot:0,
|
||||
img:undefined,
|
||||
imgcol:'#ffffff',
|
||||
|
||||
setFont: function(){
|
||||
g.setFont('6x8:5x9'); // TODO this is a bottleneck. How to prepare the font once?
|
||||
},
|
||||
|
||||
//public:
|
||||
show: function(theMessage){
|
||||
console.log("theMessage is:");
|
||||
console.log(theMessage);
|
||||
xxl.msg = theMessage;
|
||||
// prepare string and metrics
|
||||
xxl.txt = xxl.msg.src + ": " + xxl.msg.body;
|
||||
xxl.setFont();
|
||||
xxl.wtot = g.stringMetrics(xxl.txt).width;
|
||||
xxl.xpos = 2 * g.getWidth();
|
||||
|
||||
// get icon
|
||||
xxl.img = require("messageicons").getImage(xxl.msg);
|
||||
xxl.imgcol = require("messageicons").getColor(xxl.msg, '#ffffff');
|
||||
|
||||
Bangle.loadWidgets();
|
||||
|
||||
Bangle.on('touch', function (b, xy) {
|
||||
xxl.stop();
|
||||
});
|
||||
setWatch(xxl.stop, BTN1);
|
||||
Bangle.buzz(500,1);
|
||||
|
||||
xxl.draw();
|
||||
},
|
||||
|
||||
//private:
|
||||
// schedule a draw for 30 FPS
|
||||
queueDraw: function() {
|
||||
if (xxl.drawTimeout) { return; } // clearTimeout(xxl.drawTimeout); }
|
||||
xxl.drawTimeout = setTimeout(function () {
|
||||
xxl.drawTimeout = undefined;
|
||||
xxl.draw();
|
||||
}, 33 - (Date.now() % 33));
|
||||
},
|
||||
|
||||
|
||||
stop:function() {
|
||||
console.log("stop");
|
||||
if (xxl.drawTimeout) { clearTimeout(xxl.drawTimeout); }
|
||||
xxl.drawTimeout = undefined;
|
||||
g.reset();
|
||||
g.setBgColor('#ffff00');
|
||||
g.clear();
|
||||
|
||||
// Bangle.setLCDPower(0); // light off
|
||||
// Bangle.setLocked(true); // disable touch
|
||||
|
||||
setTimeout(load, 100);
|
||||
},
|
||||
|
||||
draw: function() {
|
||||
wh = 24; // widgets height
|
||||
var gw = g.getWidth();
|
||||
var h = (g.getHeight() - wh)/2; // height of drawing area per stripe
|
||||
|
||||
Bangle.setLCDPower(1); // light on
|
||||
Bangle.setLocked(false); // keep the touch input active
|
||||
g.setBgColor('#000000');
|
||||
g.clear();
|
||||
|
||||
if (xxl.img) { // 24x24
|
||||
g.setColor(xxl.imgcol);
|
||||
g.drawImage(xxl.img
|
||||
, gw/2, wh+h // center point
|
||||
,{rotate:0,scale:2}
|
||||
);
|
||||
}
|
||||
|
||||
xxl.setFont();
|
||||
g.setFontAlign(-1, -1);
|
||||
|
||||
// draw both lines
|
||||
g.setBgColor('#000000');
|
||||
g.setColor('#ffffff');
|
||||
g.drawString(xxl.txt, xxl.xpos, wh);
|
||||
g.drawString(xxl.txt, xxl.xpos - gw - 32, h + wh);
|
||||
|
||||
g.reset();
|
||||
// widget redraw
|
||||
Bangle.drawWidgets();
|
||||
|
||||
// scroll
|
||||
xxl.xpos -= 25;
|
||||
if (xxl.xpos < -xxl.wtot - gw * 2) {
|
||||
++xxl.loopCount;
|
||||
if (xxl.loopCount > 2) {
|
||||
xxl.stop();
|
||||
return;
|
||||
}
|
||||
xxl.xpos = 3 * gw;
|
||||
}
|
||||
// loop drawing
|
||||
xxl.queueDraw();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// for IDE
|
||||
// var exports={};
|
||||
|
||||
exports.listener = function (type, msg) {
|
||||
// msg = {t:"add",id:int, src,title,subject,body,sender,tel, important:bool, new:bool}
|
||||
if (!msg) return;
|
||||
if (type === 'text' && msg.t !== 'remove') {
|
||||
msg.handled = true; // don't do anything else with the message
|
||||
xxl.show(msg);
|
||||
}
|
||||
};
|
||||
|
||||
// debug
|
||||
// Bangle.on("message", (type, msg) => exports.listener(type, msg));
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
// GB({t:"notify",id:1680248072,src:"SMS Messenger",title:"Fabia",body:"Nein"})
|
||||
// msg = {"t":"add","id":1680248072,"src":"SMS Messenger","title":"Fabia","body":"Nein","new":true,"handled":true}
|
||||
var xxl = {
|
||||
// private:
|
||||
msg: [],
|
||||
drawTimeout: undefined,
|
||||
xpos : 0,
|
||||
loopCount : 0,
|
||||
txt:'',
|
||||
wtot:0,
|
||||
img:undefined,
|
||||
imgcol:'#ffffff',
|
||||
|
||||
// gfx buffer
|
||||
bufimg:undefined,
|
||||
bufpal4color:undefined,
|
||||
buffnt:'6x15', // font to use. Built-in: 4x6, 6x8,12x20,6x15,Vector
|
||||
bufw:0, // width of buffer for all lines
|
||||
bufh:0, // height of buffer
|
||||
buflin:0, // number of lines to print
|
||||
bufscale:0, // scale factor for buffer to screen
|
||||
|
||||
// public:
|
||||
show: function(theMessage){
|
||||
// console.log("theMessage is:");
|
||||
// console.log(theMessage);
|
||||
xxl.msg = theMessage;
|
||||
|
||||
// get icon
|
||||
try{
|
||||
xxl.img = require("messageicons").getImage(xxl.msg);
|
||||
xxl.imgcol = (require("messageicons").getColor(xxl.msg, '#ffffff')||'#00ffff');
|
||||
}catch(e){}
|
||||
|
||||
Bangle.loadWidgets();
|
||||
|
||||
Bangle.on('touch', function (b, xy) {
|
||||
xxl.stop();
|
||||
});
|
||||
setWatch(xxl.stop, BTN1);
|
||||
Bangle.buzz(500,1);
|
||||
|
||||
|
||||
// offscreen gfx buffer
|
||||
// screen is 176x176
|
||||
// font should be scaled 5x9=30x72px
|
||||
// built in fonts are 4x6, 6x8,12x20,6x15,Vector
|
||||
xxl.bufpal4color = new Uint16Array([0x0000,0xFFFF,0x7BEF,0xAFE5],0,2); // b,w,grey,greenyellow
|
||||
g.setFont(xxl.buffnt);
|
||||
var hfont = g.getFontHeight();
|
||||
xxl.bufscale=parseInt((g.getHeight() - 24/*widgets*/)/2) / hfont;
|
||||
xxl.buflin=2; // number of lines
|
||||
xxl.bufw=(g.getWidth() * xxl.buflin) / xxl.bufscale; // 6x15 font scaled by 5 on 176 screen width
|
||||
xxl.bufh=hfont;
|
||||
|
||||
xxl.bufimg = Graphics.createArrayBuffer(xxl.bufw,xxl.bufh,2,{msb:true});
|
||||
|
||||
// prepare string and metrics
|
||||
xxl.txt = (xxl.msg.title||(xxl.msg.src||"MSG")) + ": " + (xxl.msg.body||"-x-");
|
||||
g.setFont(xxl.buffnt);
|
||||
xxl.wtot = g.stringMetrics(xxl.txt).width;
|
||||
xxl.xpos = xxl.bufw; // g.getWidth();
|
||||
|
||||
xxl.draw();
|
||||
},
|
||||
|
||||
//private:
|
||||
// schedule a draw for 60 FPS
|
||||
queueDraw: function() {
|
||||
if (xxl.drawTimeout) { return; } // clearTimeout(xxl.drawTimeout); }
|
||||
xxl.drawTimeout = setTimeout(function () {
|
||||
xxl.drawTimeout = undefined;
|
||||
xxl.draw();
|
||||
}, 16 - (Date.now() % 16));
|
||||
},
|
||||
|
||||
|
||||
stop:function() {
|
||||
// console.log("stop");
|
||||
if (xxl.drawTimeout) { clearTimeout(xxl.drawTimeout); }
|
||||
xxl.drawTimeout = undefined;
|
||||
g.reset();
|
||||
g.setBgColor('#ffff00');
|
||||
g.clear();
|
||||
|
||||
// Bangle.setLCDPower(0); // light off
|
||||
// Bangle.setLocked(true); // disable touch
|
||||
|
||||
setTimeout(function(){Bangle.showClock();}, 100);
|
||||
},
|
||||
|
||||
// this is even slower than the scaled printing :(
|
||||
// megaPrintBufferd: function(txt, x, y){
|
||||
// xxl.bufimg.setFont(xxl.buffnt);
|
||||
// xxl.bufimg.setFontAlign(-1, -1);
|
||||
// xxl.bufimg.setColor(1); // index in palette
|
||||
// xxl.bufimg.clear();
|
||||
// xxl.bufimg.drawString(txt, x, 0);
|
||||
// for(var i = 0; i<xxl.buflin; ++i){
|
||||
// g.drawImage({
|
||||
// width:xxl.bufw, height:xxl.bufh, bpp:2
|
||||
// , buffer: xxl.bufimg.buffer
|
||||
// , palette: xxl.bufpal4color
|
||||
// }
|
||||
// , -i*g.getWidth(), y
|
||||
// ,{scale:xxl.bufscale}
|
||||
// );
|
||||
// y+=xxl.bufscale*xxl.bufh;
|
||||
// }
|
||||
// },
|
||||
|
||||
// x: pixels in buffer. Must scale this.
|
||||
// y: screen position
|
||||
megaPrint: function(txt, x, y){
|
||||
g.setFont(xxl.buffnt+':'+xxl.bufscale);
|
||||
g.setColor('#ffffff');
|
||||
g.setFontAlign(-1, -1);
|
||||
for(var i = 0; i<xxl.buflin; ++i){
|
||||
g.drawString(txt
|
||||
, x*xxl.bufscale-i*g.getWidth()
|
||||
, y
|
||||
);
|
||||
y+=xxl.bufscale*xxl.bufh;
|
||||
}
|
||||
},
|
||||
|
||||
draw: function() {
|
||||
var wh = 24; // widgets height
|
||||
var gw = g.getWidth();
|
||||
var h = (g.getHeight() - wh)/2; // height of drawing area per stripe
|
||||
|
||||
Bangle.setLCDPower(1); // light on
|
||||
Bangle.setLocked(false); // keep the touch input active
|
||||
g.setBgColor('#000000');
|
||||
g.clear();
|
||||
|
||||
// center line
|
||||
g.setColor(xxl.imgcol);
|
||||
g.fillRect( 0,wh+h-3,gw/2-26,wh+h-1);
|
||||
g.fillRect(gw/2+26,wh+h-3, gw-1,wh+h-1);
|
||||
|
||||
// image
|
||||
if (xxl.img) { // 24x24
|
||||
g.setColor(xxl.imgcol);
|
||||
g.drawImage(xxl.img
|
||||
, gw/2, wh+h-2 // center point
|
||||
,{rotate:0,scale:2}
|
||||
);
|
||||
}
|
||||
// scroll message
|
||||
xxl.megaPrint(xxl.txt, xxl.xpos, wh);
|
||||
|
||||
g.reset();
|
||||
// widget redraw
|
||||
Bangle.drawWidgets();
|
||||
|
||||
// scroll
|
||||
xxl.xpos -= 3; // buffer pixels
|
||||
if (xxl.xpos < -xxl.wtot - xxl.bufw/xxl.buflin - 4) {
|
||||
++xxl.loopCount;
|
||||
if (xxl.loopCount > 2) {
|
||||
xxl.stop();
|
||||
return;
|
||||
}
|
||||
xxl.xpos = (3*xxl.bufw)/2;
|
||||
}
|
||||
// loop drawing
|
||||
xxl.queueDraw();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// for IDE
|
||||
// var exports={};
|
||||
|
||||
exports.listener = function (type, msg) {
|
||||
// msg = {t:"add",id:int, src,title,subject,body,sender,tel, important:bool, new:bool}
|
||||
if (!msg) return;
|
||||
if (type === 'text' && msg.t !== 'remove') {
|
||||
msg.handled = true; // don't do anything else with the message
|
||||
xxl.show(msg);
|
||||
}
|
||||
};
|
||||
|
||||
// debug
|
||||
// var msg = {t:"add",id:12341, src:"SMS",title:undefined,subject:undefined,body:"yes",sender:"phoo",tel:undefined, important:false, new:true};
|
||||
// exports.listener('text', msg);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
{
|
||||
"id": "xxlmessage",
|
||||
"name": "XXL Message",
|
||||
"version": "0.02",
|
||||
"shortName": "XXL Msg",
|
||||
"description": "App to display large notifications from iOS and Gadgetbridge/Android",
|
||||
"icon": "app.png",
|
||||
"type": "app",
|
||||
"tags": "tool,system",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"dependencies" : {"messages":"module", "messageicons":"module" },
|
||||
"readme": "README.md",
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"xxlmessage.app.js","url":"app.js"},
|
||||
{"name":"xxlmessage.lib.js","url":"lib.js"},
|
||||
{"name":"xxlmessage.boot.js","url":"boot.js"},
|
||||
{"name":"xxlmessage.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 2.0 KiB |
|
@ -16,7 +16,7 @@ if (window.location.host=="banglejs.com") {
|
|||
'This is not the official Bangle.js App Loader - you can try the <a href="https://banglejs.com/apps/">Official Version</a> here.';
|
||||
}
|
||||
|
||||
var RECOMMENDED_VERSION = "2v16";
|
||||
var RECOMMENDED_VERSION = "2v17";
|
||||
// could check http://www.espruino.com/json/BANGLEJS.json for this
|
||||
|
||||
// We're only interested in Bangles
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
type SettingsFunc = (back: () => void) => void;
|
||||
type ClockInfoFunc = () => ClockInfo.Menu;
|
|
@ -90,6 +90,8 @@ type Widget = {
|
|||
};
|
||||
declare const WIDGETS: { [key: string]: Widget };
|
||||
|
||||
type ShortBoolean = boolean | 0 | 1;
|
||||
|
||||
type AccelData = {
|
||||
x: number;
|
||||
y: number;
|
||||
|
@ -153,13 +155,13 @@ type LCDMode =
|
|||
| "120x120"
|
||||
| "80x80"
|
||||
|
||||
type BangleOptions = {
|
||||
wakeOnBTN1: boolean;
|
||||
wakeOnBTN2: boolean;
|
||||
wakeOnBTN3: boolean;
|
||||
wakeOnFaceUp: boolean;
|
||||
wakeOnTouch: boolean;
|
||||
wakeOnTwist: boolean;
|
||||
type BangleOptions<Boolean = boolean> = {
|
||||
wakeOnBTN1: Boolean;
|
||||
wakeOnBTN2: Boolean;
|
||||
wakeOnBTN3: Boolean;
|
||||
wakeOnFaceUp: Boolean;
|
||||
wakeOnTouch: Boolean;
|
||||
wakeOnTwist: Boolean;
|
||||
twistThreshold: number;
|
||||
twistMaxY: number;
|
||||
twistTimeout: number;
|
||||
|
@ -174,6 +176,12 @@ type BangleOptions = {
|
|||
btnLoadTimeout: number;
|
||||
};
|
||||
|
||||
type SetUIArg<Mode> = Mode | {
|
||||
mode: Mode,
|
||||
back?: () => void,
|
||||
remove?: () => void,
|
||||
};
|
||||
|
||||
type NRFFilters = {
|
||||
services?: string[];
|
||||
name?: string;
|
||||
|
@ -296,6 +304,12 @@ type VariableSizeInformation = {
|
|||
more?: VariableSizeInformation;
|
||||
};
|
||||
|
||||
type PipeOptions = {
|
||||
chunkSize?: number,
|
||||
end?: boolean,
|
||||
complete?: () => void,
|
||||
};
|
||||
|
||||
|
||||
// CLASSES
|
||||
|
||||
|
@ -794,6 +808,29 @@ declare class NRF {
|
|||
*/
|
||||
static on(event: "security", callback: (status: any) => void): void;
|
||||
|
||||
/**
|
||||
* Called when Bluetooth advertising starts or stops on Espruino
|
||||
* @param {string} event - The event to listen to.
|
||||
* @param {(isAdvertising: boolean) => void} callback - A function that is executed when the event occurs. Its arguments are:
|
||||
* * `isAdvertising` Whether we are advertising or not
|
||||
* @url http://www.espruino.com/Reference#l_NRF_advertising
|
||||
*/
|
||||
static on(event: "advertising", callback: (isAdvertising: boolean) => void): void;
|
||||
|
||||
/**
|
||||
* Called during the bonding process to update on status
|
||||
* `status` is one of:
|
||||
* * `"request"` - Bonding has been requested in code via `NRF.startBonding`
|
||||
* * `"start"` - The bonding procedure has started
|
||||
* * `"success"` - The bonding procedure has succeeded (`NRF.startBonding`'s promise resolves)
|
||||
* * `"fail"` - The bonding procedure has failed (`NRF.startBonding`'s promise rejects)
|
||||
* @param {string} event - The event to listen to.
|
||||
* @param {(status: any) => void} callback - A function that is executed when the event occurs. Its arguments are:
|
||||
* * `status` One of `'request'/'start'/'success'/'fail'`
|
||||
* @url http://www.espruino.com/Reference#l_NRF_bond
|
||||
*/
|
||||
static on(event: "bond", callback: (status: any) => void): void;
|
||||
|
||||
/**
|
||||
* Called with a single byte value when Espruino is set up as a HID device and the
|
||||
* computer it is connected to sends a HID report back to Espruino. This is usually
|
||||
|
@ -985,15 +1022,17 @@ declare class NRF {
|
|||
* `options` is an object, which can contain:
|
||||
* ```
|
||||
* {
|
||||
* name: "Hello" // The name of the device
|
||||
* showName: true/false // include full name, or nothing
|
||||
* discoverable: true/false // general discoverable, or limited - default is limited
|
||||
* connectable: true/false // whether device is connectable - default is true
|
||||
* scannable : true/false // whether device can be scanned for scan response packets - default is true
|
||||
* interval: 600 // Advertising interval in msec, between 20 and 10000 (default is 375ms)
|
||||
* manufacturer: 0x0590 // IF sending manufacturer data, this is the manufacturer ID
|
||||
* manufacturerData: [...] // IF sending manufacturer data, this is an array of data
|
||||
* phy: "1mbps/2mbps/coded" // (NRF52840 only) use the long-range coded phy for transmission (1mbps default)
|
||||
* name: "Hello" // The name of the device
|
||||
* showName: true/false // include full name, or nothing
|
||||
* discoverable: true/false // general discoverable, or limited - default is limited
|
||||
* connectable: true/false // whether device is connectable - default is true
|
||||
* scannable : true/false // whether device can be scanned for scan response packets - default is true
|
||||
* whenConnected : true/false // keep advertising when connected (nRF52 only)
|
||||
* // switches to advertising as non-connectable when it is connected
|
||||
* interval: 600 // Advertising interval in msec, between 20 and 10000 (default is 375ms)
|
||||
* manufacturer: 0x0590 // IF sending manufacturer data, this is the manufacturer ID
|
||||
* manufacturerData: [...] // IF sending manufacturer data, this is an array of data
|
||||
* phy: "1mbps/2mbps/coded" // (NRF52840 only) use the long-range coded phy for transmission (1mbps default)
|
||||
* }
|
||||
* ```
|
||||
* Setting `connectable` and `scannable` to false gives the lowest power
|
||||
|
@ -2274,7 +2313,7 @@ declare class Socket {
|
|||
* end : call the 'end' function on the destination when the source is finished
|
||||
* @url http://www.espruino.com/Reference#l_Socket_pipe
|
||||
*/
|
||||
pipe(destination: any, options?: any): void;
|
||||
pipe(destination: any, options?: PipeOptions): void
|
||||
|
||||
/**
|
||||
* This function writes the `data` argument as a string. Data that is passed in
|
||||
|
@ -2469,7 +2508,7 @@ declare class httpSRq {
|
|||
* end : call the 'end' function on the destination when the source is finished
|
||||
* @url http://www.espruino.com/Reference#l_httpSRq_pipe
|
||||
*/
|
||||
pipe(destination: any, options?: any): void;
|
||||
pipe(dest: any, options?: PipeOptions): void
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2692,7 +2731,7 @@ declare class httpCRs {
|
|||
* end : call the 'end' function on the destination when the source is finished
|
||||
* @url http://www.espruino.com/Reference#l_httpCRs_pipe
|
||||
*/
|
||||
pipe(destination: any, options?: any): void;
|
||||
pipe(destination: any, options?: PipeOptions): void
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -2906,20 +2945,11 @@ declare class Microbit {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the File object - it allows you to stream data to and from files (As
|
||||
* opposed to the `require('fs').readFile(..)` style functions that read an entire
|
||||
* file).
|
||||
* To create a File object, you must type ```var fd =
|
||||
* E.openFile('filepath','mode')``` - see [E.openFile](#l_E_openFile) for more
|
||||
* information.
|
||||
* **Note:** If you want to remove an SD card after you have started using it, you
|
||||
* *must* call `E.unmountSD()` or you may cause damage to the card.
|
||||
* @url http://www.espruino.com/Reference#File
|
||||
*/
|
||||
declare class File {
|
||||
interface FileConstructor {
|
||||
|
||||
}
|
||||
|
||||
interface File {
|
||||
/**
|
||||
* Close an open file.
|
||||
* @url http://www.espruino.com/Reference#l_File_close
|
||||
|
@ -2976,9 +3006,22 @@ declare class File {
|
|||
* end : call the 'end' function on the destination when the source is finished
|
||||
* @url http://www.espruino.com/Reference#l_File_pipe
|
||||
*/
|
||||
pipe(destination: any, options?: any): void;
|
||||
pipe(destination: any, options?: PipeOptions): void
|
||||
}
|
||||
|
||||
/**
|
||||
* This is the File object - it allows you to stream data to and from files (As
|
||||
* opposed to the `require('fs').readFile(..)` style functions that read an entire
|
||||
* file).
|
||||
* To create a File object, you must type ```var fd =
|
||||
* E.openFile('filepath','mode')``` - see [E.openFile](#l_E_openFile) for more
|
||||
* information.
|
||||
* **Note:** If you want to remove an SD card after you have started using it, you
|
||||
* *must* call `E.unmountSD()` or you may cause damage to the card.
|
||||
* @url http://www.espruino.com/Reference#File
|
||||
*/
|
||||
declare const File: FileConstructor
|
||||
|
||||
/**
|
||||
* Class containing [Puck.js's](http://www.puck-js.com) utility functions.
|
||||
* @url http://www.espruino.com/Reference#Puck
|
||||
|
@ -3519,7 +3562,7 @@ declare class Bangle {
|
|||
* @param {string} event - The event to listen to.
|
||||
* @param {(button: number, xy: any) => void} callback - A function that is executed when the event occurs. Its arguments are:
|
||||
* * `button` `1` for left, `2` for right
|
||||
* * `xy` Object of form `{x,y}` containing touch coordinates (if the device supports full touch). Clipped to 0..175 (LCD pixel coordinates) on firmware 2v13 and later.
|
||||
* * `xy` Object of form `{x,y,type}` containing touch coordinates (if the device supports full touch). Clipped to 0..175 (LCD pixel coordinates) on firmware 2v13 and later.`type` is only available on Bangle.js 2 and is an integer, either 0 for swift touches or 2 for longer ones.
|
||||
* @url http://www.espruino.com/Reference#l_Bangle_touch
|
||||
*/
|
||||
static on(event: "touch", callback: TouchCallback): void;
|
||||
|
@ -3783,7 +3826,7 @@ declare class Bangle {
|
|||
* @param {any} options
|
||||
* @url http://www.espruino.com/Reference#l_Bangle_setOptions
|
||||
*/
|
||||
static setOptions(options: { [key in keyof BangleOptions]?: BangleOptions[key] }): void;
|
||||
static setOptions(options: { [key in keyof BangleOptions]?: BangleOptions<ShortBoolean>[key] }): void;
|
||||
|
||||
/**
|
||||
* Return the current state of options as set by `Bangle.setOptions`
|
||||
|
@ -3844,7 +3887,7 @@ declare class Bangle {
|
|||
* @returns {boolean} Is HRM on?
|
||||
* @url http://www.espruino.com/Reference#l_Bangle_setHRMPower
|
||||
*/
|
||||
static setHRMPower(isOn: boolean, appID: string): boolean;
|
||||
static setHRMPower(isOn: ShortBoolean, appID: string): boolean;
|
||||
|
||||
/**
|
||||
* Is the Heart rate monitor powered?
|
||||
|
@ -3868,7 +3911,7 @@ declare class Bangle {
|
|||
* @returns {boolean} Is the GPS on?
|
||||
* @url http://www.espruino.com/Reference#l_Bangle_setGPSPower
|
||||
*/
|
||||
static setGPSPower(isOn: boolean, appID: string): boolean;
|
||||
static setGPSPower(isOn: ShortBoolean, appID: string): boolean;
|
||||
|
||||
/**
|
||||
* Is the GPS powered?
|
||||
|
@ -3900,7 +3943,7 @@ declare class Bangle {
|
|||
* @returns {boolean} Is the Compass on?
|
||||
* @url http://www.espruino.com/Reference#l_Bangle_setCompassPower
|
||||
*/
|
||||
static setCompassPower(isOn: boolean, appID: string): boolean;
|
||||
static setCompassPower(isOn: ShortBoolean, appID: string): boolean;
|
||||
|
||||
/**
|
||||
* Is the compass powered?
|
||||
|
@ -3928,7 +3971,7 @@ declare class Bangle {
|
|||
* @returns {boolean} Is the Barometer on?
|
||||
* @url http://www.espruino.com/Reference#l_Bangle_setBarometerPower
|
||||
*/
|
||||
static setBarometerPower(isOn: boolean, appID: string): boolean;
|
||||
static setBarometerPower(isOn: ShortBoolean, appID: string): boolean;
|
||||
|
||||
/**
|
||||
* Is the Barometer powered?
|
||||
|
@ -4294,7 +4337,11 @@ declare class Bangle {
|
|||
* @param {any} callback - A function with one argument which is the direction
|
||||
* @url http://www.espruino.com/Reference#l_Bangle_setUI
|
||||
*/
|
||||
static setUI(type?: "updown" | "leftright" | "clock" | "clockupdown" | { mode: "custom"; back?: () => void; touch?: TouchCallback; swipe?: SwipeCallback; drag?: DragCallback; btn?: (n: number) => void, remove?: () => void, clock?: boolean }, callback?: (direction?: -1 | 1) => void): void;
|
||||
static setUI(type?: undefined): void;
|
||||
static setUI(type: SetUIArg<"updown" | "leftright">, callback: (direction?: -1 | 1) => void): void;
|
||||
static setUI(type: SetUIArg<"clock">): void;
|
||||
static setUI(type: SetUIArg<"clockupdown">, callback?: (direction: -1 | 1) => void): void;
|
||||
static setUI(type: SetUIArg<"custom"> & { touch?: TouchCallback; swipe?: SwipeCallback; drag?: DragCallback; btn?: (n: 1 | 2 | 3) => void; clock?: boolean | 0 | 1 }): void;
|
||||
|
||||
/**
|
||||
* @url http://www.espruino.com/Reference#l_Bangle_setUI
|
||||
|
@ -4316,7 +4363,7 @@ declare class Bangle {
|
|||
*/
|
||||
static appRect: { x: number, y: number, w: number, h: number, x2: number, y2: number };
|
||||
|
||||
static CLOCK: boolean;
|
||||
static CLOCK: ShortBoolean;
|
||||
static strokes: undefined | { [key: string]: Unistroke };
|
||||
}
|
||||
|
||||
|
@ -7972,7 +8019,7 @@ declare class E {
|
|||
* end : call the 'end' function on the destination when the source is finished
|
||||
* @url http://www.espruino.com/Reference#l_E_pipe
|
||||
*/
|
||||
static pipe(source: any, destination: any, options?: { chunkSize?: number, end?: boolean, complete?: () => void }): void
|
||||
static pipe(source: any, destination: any, options?: PipeOptions): void
|
||||
|
||||
/**
|
||||
* Create an ArrayBuffer from the given string. This is done via a reference, not a
|
||||
|
@ -8609,6 +8656,12 @@ declare class E {
|
|||
/**
|
||||
* This class provides a software-defined OneWire master. It is designed to be
|
||||
* similar to Arduino's OneWire library.
|
||||
* **Note:** OneWire commands are very timing-sensitive, and on nRF52 devices
|
||||
* (Bluetooth LE Espruino boards) the bluetooth stack can get in the way. Before
|
||||
* version 2v18 of Espruino OneWire could be unreliable, but as of firmware 2v18
|
||||
* Espruino now schedules OneWire accesses with the bluetooth stack to ensure it doesn't interfere.
|
||||
* OneWire is now reliable but some functions such as `OneWire.search` can now take
|
||||
* a while to execute (around 1 second).
|
||||
* @url http://www.espruino.com/Reference#OneWire
|
||||
*/
|
||||
declare class OneWire {
|
||||
|
@ -8946,10 +8999,10 @@ interface Object {
|
|||
* ```
|
||||
* For more information see `Object.on`
|
||||
*
|
||||
* @param {any} event - The name of the event, for instance `'data'`. If not specified *all* listeners are removed.
|
||||
* @param {any} [event] - [optional] The name of the event, for instance `'data'`. If not specified *all* listeners are removed.
|
||||
* @url http://www.espruino.com/Reference#l_Object_removeAllListeners
|
||||
*/
|
||||
removeAllListeners(event: any): void;
|
||||
removeAllListeners(event?: any): void;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9668,6 +9721,19 @@ declare class StorageFile {
|
|||
* @url http://www.espruino.com/Reference#l_StorageFile_erase
|
||||
*/
|
||||
erase(): void;
|
||||
|
||||
/**
|
||||
* Pipe this file to a stream (an object with a 'write' method)
|
||||
*
|
||||
* @param {any} destination - The destination file/stream that will receive content from the source.
|
||||
* @param {any} [options]
|
||||
* [optional] An object `{ chunkSize : int=32, end : bool=true, complete : function }`
|
||||
* chunkSize : The amount of data to pipe from source to destination at a time
|
||||
* complete : a function to call when the pipe activity is complete
|
||||
* end : call the 'end' function on the destination when the source is finished
|
||||
* @url http://www.espruino.com/Reference#l_StorageFile_pipe
|
||||
*/
|
||||
pipe(destination: any, options?: PipeOptions): void
|
||||
}
|
||||
|
||||
interface processConstructor {
|
||||
|
@ -10002,7 +10068,7 @@ declare class Serial {
|
|||
* end : call the 'end' function on the destination when the source is finished
|
||||
* @url http://www.espruino.com/Reference#l_Serial_pipe
|
||||
*/
|
||||
pipe(destination: any, options?: any): void;
|
||||
pipe(destination: any, options?: PipeOptions): void
|
||||
}
|
||||
|
||||
interface StringConstructor {
|
||||
|
@ -11437,10 +11503,11 @@ declare function setWatch(func: ((arg: { state: boolean, time: number, lastTime:
|
|||
* Clear the Watch that was created with setWatch. If no parameter is supplied, all watches will be removed.
|
||||
* To avoid accidentally deleting all Watches, if a parameter is supplied but is `undefined` then an Exception will be thrown.
|
||||
*
|
||||
* @param {any} id - The id returned by a previous call to setWatch. **Only one argument is allowed.**
|
||||
* @param {any} id - The id returned by a previous call to setWatch. **Only one argument is allowed.** (or pass nothing to clear all watches)
|
||||
* @url http://www.espruino.com/Reference#l__global_clearWatch
|
||||
*/
|
||||
declare function clearWatch(id: number): void;
|
||||
declare function clearWatch(): void;
|
||||
|
||||
/**
|
||||
* A variable containing the arguments given to the function:
|
||||
|
@ -11991,6 +12058,10 @@ declare module "neopixel" {
|
|||
* white). These are still supported but the array of data supplied must still be a
|
||||
* multiple of 3 bytes long. Just round the size up - it won't cause any problems.
|
||||
* * On some platforms like STM32, pins capable of hardware SPI MOSI are required.
|
||||
* * On STM32, `neopixel.write` chooses a hardware SPI device to output the signal on
|
||||
* and uses that. However in order to avoid spikes in the output, if that hardware device is *already
|
||||
* initialised* it will not be re-initialised. This means that if the SPI device was already in use,
|
||||
* you may have to use `SPIx.setup({baud:3200000, mosi:the_pin})` to force it to be re-setup on the pin.
|
||||
* * Espruino devices tend to have 3.3v IO, while WS2812/etc run off of 5v. Many
|
||||
* WS2812 will only register a logic '1' at 70% of their input voltage - so if
|
||||
* powering them off 5v you will not be able to send them data reliably. You can
|
||||
|
@ -12915,7 +12986,7 @@ declare module "fs" {
|
|||
* end : call the 'end' function on the destination when the source is finished
|
||||
* @url http://www.espruino.com/Reference#l_fs_pipe
|
||||
*/
|
||||
function pipe(source: any, destination: any, options?: any): void;
|
||||
function pipe(destination: any, options?: PipeOptions): void
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -13272,7 +13343,7 @@ declare module "Storage" {
|
|||
|
||||
/**
|
||||
* The Flash Storage system is journaling. To make the most of the limited write
|
||||
* cycles of Flash memory, Espruino marks deleted/replaced files as garbage and
|
||||
* cycles of Flash memory, Espruino marks deleted/replaced files as garbage/trash files and
|
||||
* moves on to a fresh part of flash memory. Espruino only fully erases those files
|
||||
* when it is running low on flash, or when `compact` is called.
|
||||
* `compact` may fail if there isn't enough RAM free on the stack to use as swap
|
||||
|
@ -13311,7 +13382,7 @@ declare module "Storage" {
|
|||
* fileBytes // How many bytes of allocated files do we have?
|
||||
* fileCount // How many allocated files do we have?
|
||||
* trashBytes // How many bytes of trash files do we have?
|
||||
* trashCount // How many trash files do we have?
|
||||
* trashCount // How many trash files do we have? (can be cleared with .compact)
|
||||
* }
|
||||
* ```
|
||||
* @returns {any} An object containing info about the current Storage system
|
||||
|
|
Loading…
Reference in New Issue