mirror of https://github.com/espruino/BangleApps
Merge branch 'espruino-master'
commit
94d5447122
40
apps.json
40
apps.json
|
@ -57,7 +57,7 @@
|
|||
{
|
||||
"id": "messages",
|
||||
"name": "Messages",
|
||||
"version": "0.09",
|
||||
"version": "0.10",
|
||||
"description": "App to display notifications from iOS and Gadgetbridge",
|
||||
"icon": "app.png",
|
||||
"type": "app",
|
||||
|
@ -146,7 +146,7 @@
|
|||
{
|
||||
"id": "setting",
|
||||
"name": "Settings",
|
||||
"version": "0.34",
|
||||
"version": "0.35",
|
||||
"description": "A menu for setting up Bangle.js",
|
||||
"icon": "settings.png",
|
||||
"tags": "tool,system",
|
||||
|
@ -263,16 +263,17 @@
|
|||
"id": "mywelcome",
|
||||
"name": "Customised Welcome",
|
||||
"shortName": "My Welcome",
|
||||
"version": "0.12",
|
||||
"version": "0.13",
|
||||
"description": "Appears at first boot and explains how to use Bangle.js. Like 'Welcome', but can be customised with a greeting",
|
||||
"icon": "app.png",
|
||||
"tags": "start,welcome",
|
||||
"supports": ["BANGLEJS"],
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"custom": "custom.html",
|
||||
"screenshots": [{"url":"bangle1-customized-welcome-screenshot.png"}],
|
||||
"storage": [
|
||||
{"name":"mywelcome.boot.js","url":"boot.js"},
|
||||
{"name":"mywelcome.app.js","url":"app.js"},
|
||||
{"name":"mywelcome.app.js","url":"app-bangle1.js","supports": ["BANGLEJS"]},
|
||||
{"name":"mywelcome.app.js","url":"app-bangle2.js","supports": ["BANGLEJS2"]},
|
||||
{"name":"mywelcome.settings.js","url":"settings.js"},
|
||||
{"name":"mywelcome.img","url":"app-icon.js","evaluate":true}
|
||||
],
|
||||
|
@ -1955,11 +1956,12 @@
|
|||
"id": "openstmap",
|
||||
"name": "OpenStreetMap",
|
||||
"shortName": "OpenStMap",
|
||||
"version": "0.10",
|
||||
"description": "[BETA] Loads map tiles from OpenStreetMap onto your Bangle.js and displays a map of where you are",
|
||||
"version": "0.11",
|
||||
"description": "Loads map tiles from OpenStreetMap onto your Bangle.js and displays a map of where you are. Once installed this also adds map functionality to `GPS Recorder` and `Recorder` apps",
|
||||
"icon": "app.png",
|
||||
"tags": "outdoors,gps",
|
||||
"tags": "outdoors,gps,osm",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"custom": "custom.html",
|
||||
"customConnect": true,
|
||||
"storage": [
|
||||
|
@ -1989,11 +1991,12 @@
|
|||
"id": "chronowid",
|
||||
"name": "Chrono Widget",
|
||||
"shortName": "Chrono Widget",
|
||||
"version": "0.03",
|
||||
"version": "0.04",
|
||||
"description": "Chronometer (timer) which runs as widget.",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,widget",
|
||||
"supports": ["BANGLEJS","BANGLEJS2"],
|
||||
"screenshots": [{"url":"screenshot.png"}],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"chronowid.wid.js","url":"widget.js"},
|
||||
|
@ -4643,23 +4646,6 @@
|
|||
{"name":"a_speech_timer.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "sensible",
|
||||
"name": "SensiBLE",
|
||||
"shortName": "SensiBLE",
|
||||
"version": "0.02",
|
||||
"description": "Collect, display and advertise real-time sensor data.",
|
||||
"icon": "sensible.png",
|
||||
"type": "app",
|
||||
"tags": "tool,sensors",
|
||||
"supports" : [ "BANGLEJS2" ],
|
||||
"allow_emulator": true,
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{ "name": "sensible.app.js", "url": "sensible.js" },
|
||||
{ "name": "sensible.img", "url": "sensible-icon.js", "evaluate": true }
|
||||
]
|
||||
},
|
||||
{ "id": "mylocation",
|
||||
"name": "My Location",
|
||||
"shortName":"My Location",
|
||||
|
@ -4735,7 +4721,7 @@
|
|||
{
|
||||
"id": "weatherClock",
|
||||
"name": "Weather Clock",
|
||||
"version": "0.01",
|
||||
"version": "0.02",
|
||||
"description": "A clock which displays current weather conditions (requires Gadgetbridge and Weather apps).",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"screens/screen1.png"}],
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
0.01: New widget and app!
|
||||
0.02: Setting to reset values, timer buzzes at 00:00 and not later (see readme)
|
||||
0.03: Display only minutes:seconds when less than 1 hour left
|
||||
0.03: Display only minutes:seconds when less than 1 hour left
|
||||
0.04: Change to 7 segment font, move to top widget bar
|
||||
Better auto-update behaviour, less RAM used
|
||||
|
|
|
@ -5,14 +5,13 @@ The advantage is, that you can still see your normal watchface and other widgets
|
|||
The widget is always active, but only shown when the timer is on.
|
||||
Hours, minutes, seconds and timer status can be set with an app.
|
||||
|
||||
When there is less than one seconds left on the timer it buzzes.
|
||||
When there is less than one second left on the timer it buzzes.
|
||||
|
||||
The widget has been tested on Bangle 1 and Bangle 2
|
||||
|
||||
## Screenshots
|
||||
|
||||

|
||||

|
||||

|
||||
|
||||
|
||||
## Features
|
||||
|
@ -28,15 +27,15 @@ There are no settings section in the settings app, timer can be set using an app
|
|||
* Hours: Set the hours for the timer
|
||||
* Minutes: Set the minutes for the timer
|
||||
* Seconds: Set the seconds for the timer
|
||||
* Timer on: Starts the timer and displays the widget when set to 'On'. You have to leave the app to load the widget which starts the timer. The widget is always there, but only visible when timer is on.
|
||||
* Timer on: Starts the timer and displays the widget when set to 'On'. You have to leave the app to load the widget which starts the timer. The widget is always there, but only visible when timer is on.
|
||||
|
||||
|
||||
## Releases
|
||||
|
||||
* Offifical app loader: https://github.com/espruino/BangleApps/tree/master/apps/chronowid (https://banglejs.com/apps/)
|
||||
* Official app loader: https://github.com/espruino/BangleApps/tree/master/apps/chronowid (https://banglejs.com/apps/)
|
||||
* Forked app loader: https://github.com/Purple-Tentacle/BangleApps/tree/master/apps/chronowid (https://purple-tentacle.github.io/BangleApps/index.html#)
|
||||
* Development: https://github.com/Purple-Tentacle/BangleAppsDev/tree/master/apps/chronowid
|
||||
|
||||
## Requests
|
||||
|
||||
If you have any feature requests, please write here: http://forum.espruino.com/conversations/345972/
|
||||
If you have any feature requests, please write here: http://forum.espruino.com/conversations/345972/
|
||||
|
|
|
@ -3,7 +3,6 @@ Bangle.loadWidgets();
|
|||
Bangle.drawWidgets();
|
||||
|
||||
const storage = require('Storage');
|
||||
const boolFormat = v => v ? "On" : "Off";
|
||||
let settingsChronowid;
|
||||
|
||||
function updateSettings() {
|
||||
|
@ -12,6 +11,7 @@ function updateSettings() {
|
|||
now.getHours() + settingsChronowid.hours, now.getMinutes() + settingsChronowid.minutes, now.getSeconds() + settingsChronowid.seconds);
|
||||
settingsChronowid.goal = goal.getTime();
|
||||
storage.writeJSON('chronowid.json', settingsChronowid);
|
||||
if (WIDGETS["chronowid"]) WIDGETS["chronowid"].reload();
|
||||
}
|
||||
|
||||
function resetSettings() {
|
||||
|
@ -44,6 +44,7 @@ function showMenu() {
|
|||
timerMenu.started.value = settingsChronowid.started;
|
||||
}
|
||||
},
|
||||
'< Back' : ()=>{load();},
|
||||
'Reset values': function() {
|
||||
settingsChronowid.hours = 0;
|
||||
settingsChronowid.minutes = 0;
|
||||
|
@ -84,15 +85,15 @@ function showMenu() {
|
|||
},
|
||||
'Timer on': {
|
||||
value: settingsChronowid.started,
|
||||
format: boolFormat,
|
||||
format: v => v ? "On" : "Off",
|
||||
onchange: v => {
|
||||
settingsChronowid.started = v;
|
||||
updateSettings();
|
||||
}
|
||||
},
|
||||
};
|
||||
timerMenu['-Exit-'] = ()=>{load();};
|
||||
|
||||
return E.showMenu(timerMenu);
|
||||
}
|
||||
|
||||
showMenu();
|
||||
showMenu();
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 29 KiB |
Binary file not shown.
Before Width: | Height: | Size: 60 KiB |
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
|
@ -1,93 +1,79 @@
|
|||
(() => {
|
||||
const storage = require('Storage');
|
||||
settingsChronowid = storage.readJSON("chronowid.json",1)||{}; //read settingsChronowid from file
|
||||
var height = 23;
|
||||
var width = 58;
|
||||
var settingsChronowid;
|
||||
var interval = 0; //used for the 1 second interval timer
|
||||
var now = new Date();
|
||||
var diff;
|
||||
|
||||
var time = 0;
|
||||
var diff = settingsChronowid.goal - now;
|
||||
|
||||
//Convert ms to time
|
||||
function getTime(t) {
|
||||
var milliseconds = parseInt((t % 1000) / 100),
|
||||
seconds = Math.floor((t / 1000) % 60),
|
||||
minutes = Math.floor((t / (1000 * 60)) % 60),
|
||||
hours = Math.floor((t / (1000 * 60 * 60)) % 24);
|
||||
|
||||
hours = (hours < 10) ? "0" + hours : hours;
|
||||
minutes = (minutes < 10) ? "0" + minutes : minutes;
|
||||
seconds = (seconds < 10) ? "0" + seconds : seconds;
|
||||
|
||||
return hours + ":" + minutes + ":" + seconds;
|
||||
return hours.toString().padStart(2,0) + ":" + minutes.toString().padStart(2,0) + ":" + seconds.toString().padStart(2,0);
|
||||
}
|
||||
|
||||
function printDebug() {
|
||||
print ("Nowtime: " + getTime(now));
|
||||
print ("Now: " + now);
|
||||
/*function printDebug() {
|
||||
print ("Goaltime: " + getTime(settingsChronowid.goal));
|
||||
print ("Goal: " + settingsChronowid.goal);
|
||||
print("Difftime: " + getTime(diff));
|
||||
print("Diff: " + diff);
|
||||
print ("Started: " + settingsChronowid.started);
|
||||
print ("----");
|
||||
}
|
||||
}*/
|
||||
|
||||
//counts down, calculates and displays
|
||||
function countDown() {
|
||||
now = new Date();
|
||||
var now = new Date();
|
||||
diff = settingsChronowid.goal - now; //calculate difference
|
||||
WIDGETS["chronowid"].draw();
|
||||
//time is up
|
||||
// time is up
|
||||
if (settingsChronowid.started && diff < 1000) {
|
||||
Bangle.buzz(1500);
|
||||
//write timer off to file
|
||||
settingsChronowid.started = false;
|
||||
storage.writeJSON('chronowid.json', settingsChronowid);
|
||||
require('Storage').writeJSON('chronowid.json', settingsChronowid);
|
||||
clearInterval(interval); //stop interval
|
||||
interval = undefined;
|
||||
}
|
||||
//printDebug();
|
||||
// calculates width and redraws accordingly
|
||||
WIDGETS["chronowid"].redraw();
|
||||
}
|
||||
|
||||
// draw your widget
|
||||
function draw() {
|
||||
if (!settingsChronowid.started) {
|
||||
width = 0;
|
||||
return; //do not draw anything if timer is not started
|
||||
}
|
||||
g.reset();
|
||||
if (diff >= 0) {
|
||||
if (diff < 3600000) { //less than 1 hour left
|
||||
width = 58;
|
||||
g.clearRect(this.x,this.y,this.x+width,this.y+height);
|
||||
g.setFont("6x8", 2);
|
||||
g.drawString(getTime(diff).substring(3), this.x+1, this.y+5); //remove hour part 00:00:00 -> 00:00
|
||||
}
|
||||
if (diff >= 3600000) { //one hour or more left
|
||||
width = 48;
|
||||
g.clearRect(this.x,this.y,this.x+width,this.y+height);
|
||||
g.setFont("6x8", 1);
|
||||
g.drawString(getTime(diff), this.x+1, this.y+((height/2)-4)); //display hour 00:00:00
|
||||
}
|
||||
}
|
||||
// not needed anymoe, because we check if diff < 1000 now, so 00:00 is displayed.
|
||||
// else {
|
||||
// width = 58;
|
||||
// g.clearRect(this.x,this.y,this.x+width,this.y+height);
|
||||
// g.setFont("6x8", 2);
|
||||
// g.drawString("END", this.x+15, this.y+5);
|
||||
// }
|
||||
}
|
||||
|
||||
if (settingsChronowid.started) interval = setInterval(countDown, 1000); //start countdown each second
|
||||
|
||||
// add the widget
|
||||
WIDGETS["chronowid"]={area:"bl",width:width,draw:draw,reload:function() {
|
||||
reload();
|
||||
Bangle.drawWidgets(); // relayout all widgets
|
||||
WIDGETS["chronowid"]={area:"tl",width:0,draw:function() {
|
||||
if (!this.width) return;
|
||||
g.reset().setFontAlign(0,0).clearRect(this.x,this.y,this.x+this.width,this.y+23);
|
||||
//g.drawRect(this.x,this.y,this.x+this.width-1, this.y+23);
|
||||
var scale;
|
||||
var timeStr;
|
||||
if (diff < 3600000) { //less than 1 hour left
|
||||
width = 58;
|
||||
scale = 2;
|
||||
timeStr = getTime(diff).substring(3); // remove hour part 00:00:00 -> 00:00
|
||||
} else { //one hour or more left
|
||||
width = 48;
|
||||
scale = 1;
|
||||
timeStr = getTime(diff); //display hour 00:00:00 but small
|
||||
}
|
||||
// Font5x9Numeric7Seg - just build this in as it's tiny
|
||||
g.setFontCustom(atob("AAAAAAAAAAIAAAQCAQAAAd0BgMBdwAAAAAAAdwAB0RiMRcAAAERiMRdwAcAQCAQdwAcERiMRBwAd0RiMRBwAAEAgEAdwAd0RiMRdwAcERiMRdwAFAAd0QiEQdwAdwRCIRBwAd0BgMBAAABwRCIRdwAd0RiMRAAAd0QiEQAAAAAAAAAA="), 32, atob("BgAAAAAAAAAAAAAAAAYCAAYGBgYGBgYGBgYCAAAAAAAABgYGBgYG"), 9 + (scale<<8));
|
||||
g.drawString(timeStr, this.x+this.width/2, this.y+12);
|
||||
}, redraw:function() {
|
||||
var last = this.width;
|
||||
if (!settingsChronowid.started) this.width = 0;
|
||||
else this.width = (diff < 3600000) ? 58 : 48;
|
||||
if (last != this.width) Bangle.drawWidgets();
|
||||
else this.draw();
|
||||
}, reload:function() {
|
||||
settingsChronowid = require('Storage').readJSON("chronowid.json",1)||{};
|
||||
if (interval) clearInterval(interval);
|
||||
interval = undefined;
|
||||
// start countdown each second
|
||||
if (settingsChronowid.started) interval = setInterval(countDown, 1000);
|
||||
// reset everything
|
||||
countDown();
|
||||
}};
|
||||
|
||||
//printDebug();
|
||||
countDown();
|
||||
})();
|
||||
// set width correctly, start countdown each second
|
||||
WIDGETS["chronowid"].reload();
|
||||
})();
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
Back now marks a message as read
|
||||
Clicking top-left opens a menu which allows you to delete a message or mark unread
|
||||
0.07: Added settings menu with option to choose vibrate pattern and frequency (fix #909)
|
||||
0.08: Fix rendering of long messages (fix #969)
|
||||
0.08: Fix rendering of long messages (fix #969)
|
||||
buzz on new message (fix #999)
|
||||
0.09: Respect the 'new' attribute if it was set from iOS integrations
|
||||
0.09: Message now disappears after 60s if no action taken and clock loads (fix 922)
|
||||
Fix phone icon (#1014)
|
||||
0.10: Respect the 'new' attribute if it was set from iOS integrations
|
|
@ -8,9 +8,17 @@ and responded to.
|
|||
|
||||
It is a replacement for the old `notify`/`gadgetbridge` apps.
|
||||
|
||||
## Usage
|
||||
## Settings
|
||||
|
||||
You can change settings by going to the global `Settings` app, then `App Settings`
|
||||
and `Messages`:
|
||||
|
||||
* `Vibrate` - This is the pattern of buzzes that should be made when a new message is received
|
||||
* `Repeat` - How often should buzzes repeat - the default of 4 means the Bangle will buzz every 4 seconds
|
||||
* `Unread Timer` - when a new message is received we go into the Messages app.
|
||||
If there is no user input for this amount of time then the app will exit and return
|
||||
to the clock where `MESSAGES` will be shown in the Widget bar.
|
||||
|
||||
...
|
||||
|
||||
## Requests
|
||||
|
||||
|
|
|
@ -42,7 +42,12 @@ try {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
/** this is a timeout if the app has started and is showing a single message
|
||||
but the user hasn't seen it (eg no user input) - in which case
|
||||
we should start a timeout for settings.unreadTimeout to return
|
||||
to the clock. */
|
||||
var unreadTimeout;
|
||||
/// List of all our messages
|
||||
var MESSAGES = require("Storage").readJSON("messages.json",1)||[];
|
||||
if (!Array.isArray(MESSAGES)) MESSAGES=[];
|
||||
var onMessagesModified = function(msg) {
|
||||
|
@ -171,8 +176,14 @@ function showMessageSettings(msg) {
|
|||
function showMessage(msgid) {
|
||||
var msg = MESSAGES.find(m=>m.id==msgid);
|
||||
if (!msg) return checkMessages(); // go home if no message found
|
||||
if (msg.src=="Maps") return showMapMessage(msg);
|
||||
if (msg.id=="music") return showMusicMessage(msg);
|
||||
if (msg.src=="Maps") {
|
||||
cancelReloadTimeout(); // don't auto-reload to clock now
|
||||
return showMapMessage(msg);
|
||||
}
|
||||
if (msg.id=="music") {
|
||||
cancelReloadTimeout(); // don't auto-reload to clock now
|
||||
return showMusicMessage(msg);
|
||||
}
|
||||
// Normal text message display
|
||||
var title=msg.title, titleFont = fontLarge, lines;
|
||||
if (title) {
|
||||
|
@ -186,14 +197,15 @@ function showMessage(msgid) {
|
|||
}
|
||||
var buttons = [
|
||||
{type:"btn", src:getBackImage(), cb:()=>{
|
||||
msg.new = false; // read mail
|
||||
saveMessages();
|
||||
msg.new = false; saveMessages(); // read mail
|
||||
cancelReloadTimeout(); // don't auto-reload to clock now
|
||||
checkMessages({clockIfNoMsg:1,clockIfAllRead:0,showMsgIfUnread:1});
|
||||
}} // back
|
||||
];
|
||||
if (msg.positive) {
|
||||
buttons.push({type:"btn", src:getPosImage(), cb:()=>{
|
||||
msg.new = false; saveMessages();
|
||||
cancelReloadTimeout(); // don't auto-reload to clock now
|
||||
Bangle.messageResponse(msg,true);
|
||||
checkMessages({clockIfNoMsg:1,clockIfAllRead:1,showMsgIfUnread:1});
|
||||
}});
|
||||
|
@ -202,6 +214,7 @@ function showMessage(msgid) {
|
|||
buttons.push({type:"btn", src:getNegImage(), cb:()=>{
|
||||
console.log("Response");
|
||||
msg.new = false; saveMessages();
|
||||
cancelReloadTimeout(); // don't auto-reload to clock now
|
||||
Bangle.messageResponse(msg,false);
|
||||
checkMessages({clockIfNoMsg:1,clockIfAllRead:1,showMsgIfUnread:1});
|
||||
}});
|
||||
|
@ -210,7 +223,10 @@ function showMessage(msgid) {
|
|||
var body = (lines.length>4) ? lines.slice(0,4).join("\n")+"..." : lines.join("\n");
|
||||
layout = new Layout({ type:"v", c: [
|
||||
{type:"h", fillx:1, bgCol:colBg, c: [
|
||||
{ type:"btn", src:getMessageImage(msg), cb:()=>showMessageSettings(msg) },
|
||||
{ type:"btn", src:getMessageImage(msg), cb:()=>{
|
||||
cancelReloadTimeout(); // don't auto-reload to clock now
|
||||
showMessageSettings(msg);
|
||||
}},
|
||||
{ type:"v", fillx:1, c: [
|
||||
{type:"txt", font:fontSmall, label:msg.src||"Message", bgCol:colBg, fillx:1, pad:2, halign:1 },
|
||||
title?{type:"txt", font:titleFont, label:title, bgCol:colBg, fillx:1, pad:2 }:{},
|
||||
|
@ -249,7 +265,8 @@ function checkMessages(options) {
|
|||
// no new messages - go to clock?
|
||||
if (options.clockIfAllRead && newMessages.length==0)
|
||||
return load();
|
||||
|
||||
// we don't have to time out of this screen...
|
||||
cancelReloadTimeout();
|
||||
// Otherwise show a menu
|
||||
E.showScroller({
|
||||
h : 48,
|
||||
|
@ -291,9 +308,23 @@ function checkMessages(options) {
|
|||
});
|
||||
}
|
||||
|
||||
function cancelReloadTimeout() {
|
||||
if (!unreadTimeout) return;
|
||||
clearTimeout(unreadTimeout);
|
||||
unreadTimeout = undefined;
|
||||
}
|
||||
|
||||
|
||||
g.clear();
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
setTimeout(() => {
|
||||
var unreadTimeoutSecs = (require('Storage').readJSON("messages.settings.json", true) || {}).unreadTimeout;
|
||||
if (unreadTimeoutSecs===undefined) unreadTimeoutSecs=60;
|
||||
if (unreadTimeoutSecs)
|
||||
unreadTimeout = setTimeout(function() {
|
||||
print("Message not seen - reloading");
|
||||
load();
|
||||
}, unreadTimeoutSecs*1000);
|
||||
checkMessages({clockIfNoMsg:0,clockIfAllRead:0,showMsgIfUnread:1});
|
||||
},10); // if checkMessages wants to 'load', do that
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
/* Push a new message onto messages queue, event is:
|
||||
{t:"add",id:int, src,title,subject,body,sender,tel, important:bool, new:bool}
|
||||
{t:"add",id:int, id:"music", state, artist, track, etc} // add new
|
||||
{t:"remove-",id:int} // remove
|
||||
{t:"modify",id:int, title:string} // modified
|
||||
*/
|
||||
exports.pushMessage = function(event) {
|
||||
/* event is:
|
||||
{t:"add",id:int, src,title,subject,body,sender,tel, important:bool, new:bool} // add new
|
||||
{t:"add",id:int, id:"music", state, artist, track, etc} // add new
|
||||
{t:"remove-",id:int} // remove
|
||||
{t:"modify",id:int, title:string} // modified
|
||||
*/
|
||||
var messages, inApp = "undefined"!=typeof MESSAGES;
|
||||
if (inApp)
|
||||
messages = MESSAGES; // we're in an app that has already loaded messages
|
||||
|
@ -51,6 +51,7 @@ exports.pushMessage = function(event) {
|
|||
WIDGETS.messages.show();
|
||||
}, 500);
|
||||
}
|
||||
/// Remove all messages
|
||||
exports.clearAll = function(event) {
|
||||
var messages, inApp = "undefined"!=typeof MESSAGES;
|
||||
if (inApp) {
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
let settings = require('Storage').readJSON("messages.settings.json", true) || {};
|
||||
if (settings.vibrate===undefined) settings.vibrate=".";
|
||||
if (settings.repeat===undefined) settings.repeat=4;
|
||||
if (settings.unreadTimeout===undefined) settings.unreadTimeout=60;
|
||||
return settings;
|
||||
}
|
||||
function updateSetting(setting, value) {
|
||||
|
@ -30,6 +31,12 @@
|
|||
format: v => v+"s",
|
||||
onchange: v => updateSetting("repeat", v)
|
||||
},
|
||||
'Unread timer': {
|
||||
value: settings().unreadTimeout,
|
||||
min: 0, max: 240, step : 10,
|
||||
format: v => v?v+"s":"Off",
|
||||
onchange: v => updateSetting("unreadTimeout", v)
|
||||
},
|
||||
};
|
||||
E.showMenu(mainmenu);
|
||||
})
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
WIDGETS["messages"]={area:"tl",width:0,draw:function() {
|
||||
if (!this.width) return;
|
||||
var c = (Date.now()-this.t)/1000;
|
||||
|
@ -13,9 +12,10 @@ WIDGETS["messages"]={area:"tl",width:0,draw:function() {
|
|||
WIDGETS["messages"].buzz(); // buzz every 4 seconds
|
||||
}
|
||||
setTimeout(()=>WIDGETS["messages"].draw(), 1000);
|
||||
},show:function() {
|
||||
},show:function(quiet) {
|
||||
WIDGETS["messages"].t=Date.now(); // first time
|
||||
WIDGETS["messages"].l=Date.now()-10000; // last buzz
|
||||
if (quiet) WIDGETS["messages"].t -= 500000; // if quiet, set last time in the past so there is no buzzing
|
||||
WIDGETS["messages"].width=64;
|
||||
Bangle.drawWidgets();
|
||||
Bangle.setLCDPower(1);// turns screen on
|
||||
|
@ -34,3 +34,10 @@ WIDGETS["messages"]={area:"tl",width:0,draw:function() {
|
|||
}
|
||||
b();
|
||||
}};
|
||||
/* We might have returned here if we were in the Messages app for a
|
||||
message but then the watch was never viewed. In that case we don't
|
||||
want to buzz but should still show that there are unread messages. */
|
||||
if (global.MESSAGES===undefined) (function() {
|
||||
var messages = require("Storage").readJSON("messages.json",1)||[];
|
||||
if (messages.some(m=>m.new)) WIDGETS["messages"].show(true);
|
||||
})();
|
||||
|
|
|
@ -14,3 +14,4 @@
|
|||
0.10: Add birthday style
|
||||
0.11: Skip double buffering, use 240x240 size
|
||||
0.12: Fix swipe direction (#800)
|
||||
0.13: Bangle.js 2 support
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
// exec each function from seq one after the other
|
||||
function animate(seq,period) {
|
||||
var c = g.getColor();
|
||||
var i = setInterval(function() {
|
||||
if (seq.length) {
|
||||
var f = seq.shift();
|
||||
g.setColor(c);
|
||||
if (f) f();
|
||||
} else clearInterval(i);
|
||||
},period);
|
||||
}
|
||||
|
||||
// Fade in to FG color with angled lines
|
||||
function fade(col, callback) {
|
||||
var n = 0;
|
||||
function f() {"ram"
|
||||
g.setColor(col);
|
||||
for (var i=n;i<240;i+=10) g.drawLine(i,0,0,i).drawLine(i,240,240,i);
|
||||
g.flip();
|
||||
n++;
|
||||
if (n<10) setTimeout(f,0);
|
||||
else callback();
|
||||
}
|
||||
f();
|
||||
}
|
||||
|
||||
|
||||
var SCENE_COUNT=11;
|
||||
function getScene(n) {
|
||||
if (n==0) return function() {
|
||||
console.log("Start app");
|
||||
g.clear(1);
|
||||
eval(require("Storage").read("mywelcome.custom.js"));
|
||||
}
|
||||
if (n==1) return function() {
|
||||
g.reset().setBgColor(0).clearRect(0,0,176,176);
|
||||
g.setFont("6x15");
|
||||
var n=0;
|
||||
var l = Bangle.getLogo();
|
||||
var im = g.imageMetrics(l);
|
||||
var i = setInterval(function() {
|
||||
n+=0.1;
|
||||
g.setColor(n,n,n);
|
||||
g.drawImage(l,(176-im.width)/2,(176-im.height)/2);
|
||||
if (n>=1) {
|
||||
clearInterval(i);
|
||||
setTimeout(()=>g.drawString("Open",44,104), 500);
|
||||
setTimeout(()=>g.drawString("Hackable",44,116), 1000);
|
||||
setTimeout(()=>g.drawString("Smart Watch",44,128), 1500);
|
||||
}
|
||||
},50);
|
||||
};
|
||||
if (n==2) return function() {
|
||||
var img = require("heatshrink").decompress(atob("ptR4n/j/4gH+8H5wl+jOukVVoHZ8dt/n//n37OtgH9sHhwHp4H5xmkGiH72MRje/LL/7iIAEE7sPEgoAC+AlagIlIiMQErPxDwUYxAABwIHCj8N7nOl3uEqa6BEggnFjfM5nCkUil3gEq5KDAAQmC6QmBE4JxSEhIABiQmB8QmSXoQlCYRMdEwIlCAAIlNhYlOiO85nNEyMPEoZwIAAcsYIYmPXoYlMiKaFExX/u9VEqLBBOYrCH+czmtVqJyDEpiaCOYsgSYszmc3qtTEqMR7hzG8AlGmd1OQglOOY6aEgYlCmmZoJMCTBrnD6SaIEoU/zOUuolSjbnBJgqaCEoU5zOXX4RyQYBBzCS4X5zNDqqZCJiERJg5zBEoVJEoM1JgYlQjhMHc4JLEmZMEEp6ZIJgPzS4WTmZMVTILmFYAK+BmglCmd1JgUYJiPNEorABEIOZygDBm5MCiJMQlhMH8ByBXwIlBJgUxJiMd5nOTIzlBTAK+BAANVq4jPAAS/HJgJyCTATAEACC/B4S/IJgIlCYAgAPiS/Kn5yEYANTEyPc5niOQxMB/LlCOapyJJgbpBYAZzROQK/Gl0ATIWfEoZzBc6IlB6SYGgBJBJgpzSlhyH8EAh5MBTIjnCuIlOjjlHTAJzC/LmDTSSYIEoTABOYIlETSKYHXwIABOYM0yYmETSCYHEobnDOYqaBExu8TAwlEc4U5EoiaCmK+NTAolFEwX0TQzBMXwXiEpTBCAAomNEoS+EEo4mIYIImKEoS+EEpDoBEyUbEo3gEo4mJdAImIJY4lJEycdEoPOOBYmPuIlE+HcJYhKKTZ1fhYkB2EAhnNcYMuEhomMr8A3YABEoJyB5gjOAAYmHm9VgELEoJMBEoXAEyXzE45YBJgXwEqx1I+ByDOYJyVJw5yCgEB3cQGgJMWJwQnCu6/CgFBigDB13S/glVAAf1qomCglEoADB1QDBADEPEoNVqEAolEgEKolKErJMDYAJMD0lE0AmaEoNaAgJMCFIYAahV/IgIiDOTgABNYJMEOToiCIoJMCOTzfCN4RMBOTxsDJIRyfIwZMBKQZzfJgRyfOYZMBOUBzCJgNKOT5zDJgLoCADxKBOAIABOT6aCAARyfOYRyjOYRyjOYlKEsBzEEsBzEOUJzDOUIABOUiaDOURzCOUZzCEscKCiY"));
|
||||
var im = g.imageMetrics(img);
|
||||
g.reset();
|
||||
g.setBgColor("#ff00ff");
|
||||
var y = 176, speed = 5;
|
||||
function balloon(callback) {
|
||||
y-=speed;
|
||||
var x = (176-im.width)/2;
|
||||
g.drawImage(img,x,y);
|
||||
g.clearRect(x,y+81,x+77,y+81+speed);
|
||||
if (y>30) setTimeout(balloon,0,callback);
|
||||
else callback();
|
||||
}
|
||||
fade("#ff00ff", function() {
|
||||
balloon(function() {
|
||||
g.setColor(-1).setFont("6x15:2").setFontAlign(0,0);
|
||||
g.drawString("Welcome.",88,130);
|
||||
});
|
||||
});
|
||||
setTimeout(function() {
|
||||
var n=0;
|
||||
var i = setInterval(function() {
|
||||
n+=4;
|
||||
g.scroll(0,-4);
|
||||
if (n>150)
|
||||
clearInterval(i);
|
||||
},20);
|
||||
},3500);
|
||||
|
||||
};
|
||||
if (n==3) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#ffff00").setColor(0).clear();
|
||||
g.setFont("12x20").setFontAlign(0,0);
|
||||
var x = 70, y = 25, h=25;
|
||||
animate([
|
||||
()=>g.drawString("Your",x,y+=h),
|
||||
()=>g.drawString("Bangle.js",x,y+=h),
|
||||
()=>g.drawString("has one",x,y+=h),
|
||||
()=>g.drawString("button",x,y+=h),
|
||||
()=>{g.setFont("12x20:2").setFontAlign(0,0,1).drawString("HERE!",150,88);}
|
||||
],200);
|
||||
};
|
||||
if (n==4) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#00ffff").setColor(0).clear();
|
||||
g.setFontAlign(0,0).setFont("6x15:2");
|
||||
g.drawString("Press",88,40).setFontAlign(0,-1);
|
||||
g.setFont("12x20");
|
||||
g.drawString("To wake the\nscreen up, or to\nselect", 88,60);
|
||||
};
|
||||
if (n==5) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#00ffff").setColor(0).clear();
|
||||
g.setFontAlign(0,0).setFont("6x15:2");
|
||||
g.drawString("Long Press",88,40).setFontAlign(0,-1);
|
||||
g.setFont("12x20");
|
||||
g.drawString("To go back to\nthe clock", 88,60);
|
||||
};
|
||||
if (n==6) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#ff0000").setColor(0).clear();
|
||||
g.setFontAlign(0,0).setFont("12x20");
|
||||
g.drawString("If Bangle.js ever\nstops, hold the\nbutton for\nten seconds.\n\nBangle.js will\nthen reboot.", 88,78);
|
||||
};
|
||||
if (n==7) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#0000ff").setColor(-1).clear();
|
||||
g.setFont("12x20").setFontAlign(0,0);
|
||||
var x = 88, y = -20, h=60;
|
||||
animate([
|
||||
()=>{g.drawString("Bangle.js has a\nfull touchscreen",x,y+=h);},
|
||||
0,0,
|
||||
()=>{g.drawString("Drag up and down\nto scroll and\ntap to select",x,y+=h);},
|
||||
],300);
|
||||
};
|
||||
if (n==8) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#00ff00").setColor(0).clear();
|
||||
g.setFont("12x20").setFontAlign(0,0);
|
||||
var x = 88, y = -35, h=80;
|
||||
animate([
|
||||
()=>{g.drawString("Bangle.js comes\nwith a few\napps installed",x,y+=h);},
|
||||
0,0,
|
||||
()=>{g.drawString("To add more, visit\nbanglejs.com/apps",x,y+=h);},
|
||||
],400);
|
||||
};
|
||||
if (n==9) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#ff0000").setColor(0).clear();
|
||||
g.setFont("12x20").setFontAlign(0,0);
|
||||
var x = 88;
|
||||
g.drawString("You can also make\nyour own apps!",x,30);
|
||||
g.drawString("Check out\nbanglejs.com",x,130);
|
||||
|
||||
var rx = 0, ry = 0;
|
||||
// draw a cube
|
||||
function draw() {
|
||||
// rotate
|
||||
rx += 0.1;
|
||||
ry += 0.11;
|
||||
var rcx=Math.cos(rx),
|
||||
rsx=Math.sin(rx),
|
||||
rcy=Math.cos(ry),
|
||||
rsy=Math.sin(ry);
|
||||
// Project 3D coordinates into 2D
|
||||
function p(x,y,z) {
|
||||
var t;
|
||||
t = x*rcy + z*rsy;
|
||||
z = z*rcy - x*rsy;
|
||||
x=t;
|
||||
t = y*rcx + z*rsx;
|
||||
z = z*rcx - y*rsx;
|
||||
y=t;
|
||||
z += 4;
|
||||
return [88 + 60*x/z, 78+ 60*y/z];
|
||||
}
|
||||
|
||||
var a;
|
||||
// draw a series of lines to make up our cube
|
||||
var s = 30;
|
||||
g.clearRect(88-s,78-s,88+s,78+s);
|
||||
a = p(-1,-1,-1); g.moveTo(a[0],a[1]);
|
||||
a = p(1,-1,-1); g.lineTo(a[0],a[1]);
|
||||
a = p(1,1,-1); g.lineTo(a[0],a[1]);
|
||||
a = p(-1,1,-1); g.lineTo(a[0],a[1]);
|
||||
a = p(-1,-1,-1); g.lineTo(a[0],a[1]);
|
||||
a = p(-1,-1,1); g.moveTo(a[0],a[1]);
|
||||
a = p(1,-1,1); g.lineTo(a[0],a[1]);
|
||||
a = p(1,1,1); g.lineTo(a[0],a[1]);
|
||||
a = p(-1,1,1); g.lineTo(a[0],a[1]);
|
||||
a = p(-1,-1,1); g.lineTo(a[0],a[1]);
|
||||
a = p(-1,-1,-1); g.moveTo(a[0],a[1]);
|
||||
a = p(-1,-1,1); g.lineTo(a[0],a[1]);
|
||||
a = p(1,-1,-1); g.moveTo(a[0],a[1]);
|
||||
a = p(1,-1,1); g.lineTo(a[0],a[1]);
|
||||
a = p(1,1,-1); g.moveTo(a[0],a[1]);
|
||||
a = p(1,1,1); g.lineTo(a[0],a[1]);
|
||||
a = p(-1,1,-1); g.moveTo(a[0],a[1]);
|
||||
a = p(-1,1,1); g.lineTo(a[0],a[1]);
|
||||
}
|
||||
|
||||
setInterval(draw,50);
|
||||
};
|
||||
if (n==10) return function() {
|
||||
g.reset();
|
||||
g.setBgColor("#ffffff");g.clear();
|
||||
g.setFontAlign(0,0);
|
||||
g.setFont("12x20");
|
||||
|
||||
var x = 88, y = 10, h=21;
|
||||
animate([
|
||||
()=>g.drawString("That's it!",x,y+=h),
|
||||
()=>{g.drawString("Press",x,y+=h*2);
|
||||
g.drawString("the button",x,y+=h);
|
||||
g.drawString("to start",x,y+=h);
|
||||
g.drawString("Bangle.js",x,y+=h);}
|
||||
],400);
|
||||
}
|
||||
}
|
||||
|
||||
var sceneNumber = 0;
|
||||
|
||||
function move(dir) {
|
||||
if (dir>0 && sceneNumber+1 == SCENE_COUNT) return; // at the end
|
||||
sceneNumber = (sceneNumber+dir)%SCENE_COUNT;
|
||||
if (sceneNumber<0) sceneNumber=0;
|
||||
clearInterval();
|
||||
getScene(sceneNumber)();
|
||||
if (sceneNumber>1) {
|
||||
var l = SCENE_COUNT;
|
||||
for (var i=0;i<l-2;i++) {
|
||||
var x = 88+(i-(l-2)/2)*12;
|
||||
if (i<sceneNumber-1) {
|
||||
g.setColor(-1).fillCircle(x,166,4);
|
||||
} else {
|
||||
g.setColor(0).fillCircle(x,166,4);
|
||||
g.setColor(-1).drawCircle(x,166,4);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (sceneNumber < SCENE_COUNT-1)
|
||||
setTimeout(function() {
|
||||
move(1);
|
||||
}, (sceneNumber==0) ? 20000 : 5000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Bangle.on('swipe', dir => move(dir));
|
||||
setWatch(()=>{
|
||||
if (sceneNumber == SCENE_COUNT-1)
|
||||
load();
|
||||
else
|
||||
move(1);
|
||||
}, BTN1, {repeat:true});
|
||||
|
||||
Bangle.setLCDTimeout(0);
|
||||
Bangle.setLocked(0);
|
||||
Bangle.setLCDPower(1);
|
||||
move(0);
|
|
@ -28,13 +28,15 @@ function getApp() {
|
|||
var line3 = document.getElementById("line3").value;
|
||||
var line4 = document.getElementById("line4").value;
|
||||
var style = document.getElementById("style").value;
|
||||
|
||||
// build the app's text using a templated String
|
||||
if (style=="Birthday") return `(function() {
|
||||
var ib = require("heatshrink").decompress(atob("jk0ggGDhOZAAWQCYwMEBxAMFAAIaHyc/+c5DgwMC/84Dg4aCBgwcDBoOf+Y4GBoQEBn4zCI44DBDQ4NEyf4BpgoIBoefxINMBhApEBrQAKBrrrGWpANZHBT7FBpYqIFAYcJBggNOFQwoFDgwMHBwoMIBwYMKBrkykANLmcwBu0zBrMDBv4AFN5gA/ADY"));
|
||||
var ir = require("heatshrink").decompress(atob("jk0ggGDhvdAAXQCYwMEBxAMFAAIaH6c/+c9DgwMC/8zDg4aC/4YCHIwNB7/zHAwNCAgM/DQwqDAYIaHBonT/oNMFBAND74NNBhApEBrQAKBrrrGWpANZHBT7FBpYqIFAYcJBgkA5oMF7gNFFQwoFDgwMHHIoMIAAPM5gMKBrk0oANLmcwBu0zBrMDBv4AFN5gA/ADYA="));
|
||||
var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/+c3DgwMC/8yDg4aC/4YCHIwNBv/zHAwNCAgM/DQwqDAYIaHBolz+4NMFBANDv8nBpgMIFIgNaABQNddYy1IBrI4KfYoNLFRAoDDhIMEgHnBgt+BooqGFAoqGBg4OFBhAODBhQNcmUgBpczmAN2mYNZgYN/AApvMAH4Ab"));
|
||||
var igift = require("heatshrink").decompress(atob("q1QxH+ADOi0QbZ5nMHDQAbKgIACKa4ACKnJWVKghW0KgxWTKgxWyKhBWRKhBWwKhRWPKhRWuKhhWNKhhWtKpxWKKhys8KxBU8Ky5U+KypU/KyhU/KyhU/KynGKn5WTKn5WUKmHCADpJJE7uYABZUfKuuYKv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/AAv+Kv5VT/wADyIAaKpIlbABZSEKv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/Kv5V/ADNtKv6rdKzZVwKhAABy5V/Khw"));
|
||||
var W=240,H=240;
|
||||
var W=g.getWidth(),H=g.getHeight();
|
||||
var titleFont = g.getFonts().includes("12x20") ? "12x20" : "6x8:2";
|
||||
var blns = [];
|
||||
function updateFlake(f) {
|
||||
f.im = [ir,ig,ib][Math.round(Math.random()*100)%3];
|
||||
|
@ -60,7 +62,7 @@ var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/
|
|||
});
|
||||
var x = W/2, y = H/2;
|
||||
g.drawImage(igift,x-43,y-80);
|
||||
g.setFont("6x8",2).setFontAlign(0,0);
|
||||
g.setFont(titleFont).setFontAlign(0,0);
|
||||
g.drawString(${JSON.stringify(line1)},x,y+=20);
|
||||
g.drawString(${JSON.stringify(line2)},x,y+=20);
|
||||
g.setFont("6x8");
|
||||
|
@ -68,7 +70,7 @@ var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/
|
|||
g.drawString(${JSON.stringify(line4)},x,y+=10);
|
||||
g.flip();
|
||||
}
|
||||
g.clear();
|
||||
g.clear(1).setBgColor(0).setColor(-1).clearRect(0,0,W,H);
|
||||
setInterval(draw,50);
|
||||
})()`;
|
||||
// if (style=="Christmas")
|
||||
|
@ -76,6 +78,7 @@ var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/
|
|||
var isnow = require("heatshrink").decompress(atob("jEagQWTgfAAocf+gFDh4FDiARBggVB3AFBl3Agf8jfkn/AgX/v/9/+Agfv/2//YrBgfwh4wCgfghYFJCIYdFFIw1EIIpNFL44FFOIoAP"));
|
||||
var itree = require("heatshrink").decompress(atob("mtWxH+ADHHDTI0aGuXH5vNGmhqvTYIzBGtoxF6fTG4g4oGgQyBAAZssGoI0Ga1g1FGdo01ZgIAEGmHHNoLSuAAN/rdb0YFBGlgCBGYIABA4YArGYY1CGn4znAAM6GeVd5PQ5Iyurc/vQ0oGZFAn+d4XC3d5GddiGYIEBy+7zoEBGlFhoEcsQ9GT08+oFk1mkGdaVBMgNArnJ6/KzswGs/J6GlrlbqtbvPC5PCy8wGohniMIPJvIpCqmX3e7vI0BqhqlMIY0DqhtBqoEBa0xgBMIIoEqoABGQwzfsIhBv4qHABM50vQGjg1CGaN66DoBGt1ioGd5LoBGjo1PGYNhvLoCa7wnBqgvGA4YzCAgN5GUAsCqoDBmAHCAYU/wPQ0oSDGcBiDqkwAYcxoFd5PX6GdGjrIIqtUAAc3jk5vPC4fCy5pef5I2BTQMcnAHBy+7y95T0oADnFk1ekBpI2aGRUin7NGAA9hsIzVsIgHTAKZBZoPJ5LNDGhBpXGolcwOsrtcA4TNB3bNDGb/+sVin9AoGe6HX5InEvN/TkP+5XQwM/sRsBzqWB4QuKGjvC6HQ4QdDvKWBZYMwmAuHmFUCYNbqibX3fD5O7qolEZQQ0FBwgKDqgJBGiphEDwNUEgJbBFIQqCAgYOCB4IzCnE6GyhYFGoQnDABYzGAAQ1UAAo2NBoQSBnOB0t/Gjo2EABIPCoGe6HX4QzTGRIAEqtVF4QEBBQc4oE4y/J5PCvIxeABk/oADBvO73eXTyAyZMwM/Awd5vIOFGslAr2Av4PLNcU/jmA6HX5I1KasFcn8dTIOd5PJ4SZGGiNhAAIyNn0ckU+ZYe7AAJpJEYJnNGZk+n9kw9cBAcwGoN5aZg1JJJQABm8/oEjoDKC5ALCrUwqh/NrvQ6HDGp04n9doEdoE/sQJBZQZhCqgABGZk6zw0K/1dnVAoNAFwOlCYL1FubJBy4GCGh1AnOX4XC3YzHFYOeCgdV5PQ5OdD4rKBqqYNGYlbv+X3edGY3CGgKMDAAO7JAJgDAClcr2BEYgADaIZ0DL4uXGbDuB6HX5I1GsP+sNhOgWXIhBmWd4Od5PK4TwFGIJoBAYI2BAD0/jlcQoO7AAJaEGQQADGr0/sjNEvOdAoZmDGgw2ZsVAkeAZpQACGZI2VsU/kVGn1bZoPJZogpGGhA4GfRYwBoGC1mlBQbNFFoo0JNxAGCEod/wM6oFAn9iv/J6/Kzo1Ey9/MZQAKCg4GCFgTDEvPCSwI0BC5I0RN4ocEYYPQ5OdHgeXSwTFKGaJyKFYPC3f+MIdbpzFLAD4zB/1OqtbqtOGgYArGAIADGl9UAAI0wGQN5GoQ0vvIABGoI0uGYQABqo0zNOg0uaQY0/GllOGn40//w="));
|
||||
var W=g.getWidth(),H=g.getHeight();
|
||||
var titleFont = g.getFonts().includes("12x20") ? "12x20" : "6x8:2";
|
||||
var flakes = [];
|
||||
for (var i=0;i<10;i++) {
|
||||
var f = {
|
||||
|
@ -97,7 +100,7 @@ var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/
|
|||
});
|
||||
var x = W/2, y = H/2;
|
||||
g.drawImage(itree,x-27,y-80);
|
||||
g.setFont("6x8",2).setFontAlign(0,0);
|
||||
g.setFont(titleFont).setFontAlign(0,0);
|
||||
g.drawString(${JSON.stringify(line1)},x,y+=20);
|
||||
g.drawString(${JSON.stringify(line2)},x,y+=20);
|
||||
g.setFont("6x8");
|
||||
|
@ -105,7 +108,7 @@ var ig = require("heatshrink").decompress(atob("jk0ggGDg93AAVwCYwMEBxAMFAAIaHuc/
|
|||
g.drawString(${JSON.stringify(line4)},x,y+=10);
|
||||
g.flip();
|
||||
}
|
||||
g.clear();
|
||||
g.clear(1).setBgColor(0).setColor(-1).clearRect(0,0,W,H);
|
||||
setInterval(draw,50);
|
||||
})();
|
||||
`;
|
||||
|
|
|
@ -8,3 +8,5 @@
|
|||
0.08: Update for drag event refactor
|
||||
0.09: Use current theme cols when drawing GPS info
|
||||
0.10: Improve scale factor calculation to fix scaling issues (#984)
|
||||
0.11: Add slight offset to OSM data to align it properly (fix #984)
|
||||
Fix alignment of satellite info text
|
||||
|
|
|
@ -25,11 +25,11 @@ function drawMarker() {
|
|||
var fix;
|
||||
Bangle.on('GPS',function(f) {
|
||||
fix=f;
|
||||
g.reset().clearRect(0,y1,240,y1+8).setFont("6x8").setFontAlign(0,0);
|
||||
g.reset().clearRect(0,y1,g.getWidth()-1,y1+8).setFont("6x8").setFontAlign(0,0);
|
||||
var txt = fix.satellites+" satellites";
|
||||
if (!fix.fix)
|
||||
txt += " - NO FIX";
|
||||
g.drawString(txt,120,y1 + 4);
|
||||
g.drawString(txt,g.getWidth()/2,y1 + 4);
|
||||
drawMarker();
|
||||
});
|
||||
Bangle.setGPSPower(1, "app");
|
||||
|
|
|
@ -132,8 +132,10 @@ TODO:
|
|||
var zoom = map.getZoom();
|
||||
var centerlatlon = map.getBounds().getCenter();
|
||||
var center = map.project(centerlatlon, zoom).divideBy(OSMTILESIZE);
|
||||
var ox = Math.round((center.x - Math.floor(center.x)) * OSMTILESIZE);
|
||||
var oy = Math.round((center.y - Math.floor(center.y)) * OSMTILESIZE);
|
||||
// Reason for 16px adjustment below not 100% known, but it seems to
|
||||
// align everything perfectly: https://github.com/espruino/BangleApps/issues/984
|
||||
var ox = Math.round((center.x - Math.floor(center.x)) * OSMTILESIZE) + 16;
|
||||
var oy = Math.round((center.y - Math.floor(center.y)) * OSMTILESIZE) + 16;
|
||||
center = center.floor(); // make sure we're in the middle of a tile
|
||||
// JS version of Bangle.js's projection
|
||||
function bproject(lat, lon) {
|
||||
|
@ -155,8 +157,15 @@ TODO:
|
|||
var bd = bproject(pd.lat, pd.lng)
|
||||
var scale = bc.distanceTo(bd);
|
||||
|
||||
var tileGetters = [];
|
||||
// test
|
||||
/*var p = bproject(centerlatlon.lat, centerlatlon.lng);
|
||||
var q = bproject(mylat, mylon);
|
||||
var testPt = {
|
||||
x : (q.x-p.x)/scale + (MAPSIZE/2),
|
||||
y : (MAPSIZE/2) - (q.y-p.y)/scale
|
||||
};*/
|
||||
|
||||
var tileGetters = [];
|
||||
// Render everything to a canvas...
|
||||
var canvas = document.getElementById("maptiles");
|
||||
canvas.style.display="";
|
||||
|
@ -173,6 +182,11 @@ TODO:
|
|||
tileGetters.push(new Promise(function(resolve,reject) {
|
||||
img.onload = function(){
|
||||
ctx.drawImage(img,i*OSMTILESIZE - ox, j*OSMTILESIZE - oy);
|
||||
/*if (testPt) {
|
||||
ctx.fillStyle="green";
|
||||
ctx.fillRect(testPt.x-1, testPt.y-5, 3,10);
|
||||
ctx.fillRect(testPt.x-5, testPt.y-1, 10,3);
|
||||
}*/
|
||||
resolve();
|
||||
};
|
||||
}));
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 5.6 KiB |
|
@ -37,3 +37,4 @@
|
|||
0.32: Fix 'beep' menu on Bangle.js 2
|
||||
0.33: Really fix 'beep' menu on Bangle.js 2 this time
|
||||
0.34: Remove Quiet Mode LCD settings: now handled by Quiet Mode Schedule app
|
||||
0.35: Change App/Widget settings to 'App Settings' so it fits on Bangle screen
|
||||
|
|
|
@ -96,7 +96,7 @@ function showMainMenu() {
|
|||
'': { 'title': 'Settings' },
|
||||
'< Back': ()=>load(),
|
||||
'Make Connectable': ()=>makeConnectable(),
|
||||
'App/Widget Settings': ()=>showAppSettingsMenu(),
|
||||
'App Settings': ()=>showAppSettingsMenu(),
|
||||
'BLE': ()=>showBLEMenu(),
|
||||
'Debug Info': {
|
||||
value: settings.log,
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
0.01: New App!
|
||||
0.01: New App!
|
||||
0.02: Minor layout format tweak so it uses less memory and draws ok on Bangle.js 1 (#1012)
|
||||
|
|
|
@ -69,22 +69,20 @@ var clockLayout = new Layout( {
|
|||
{type:"txt", font:"10%", label:"01/01/1970", id:"date" }
|
||||
]
|
||||
},
|
||||
{type: "v", fillx: 1, c: [
|
||||
{type: "h", valign : 1, fillx:1, c: [
|
||||
{type: "img", filly: 1, id: "weatherIcon", src: sunIcon},
|
||||
{type: "v", fillx:1, c: [
|
||||
{type: "h", c: [
|
||||
{type: "txt", font: "10%", id: "temp", label: "000"},
|
||||
{type: "txt", font: "10%", id: "tempUnit", label: "°C"},
|
||||
]},
|
||||
{type: "h", c: [
|
||||
{type: "txt", font: "10%", id: "wind", label: "00"},
|
||||
{type: "txt", font: "10%", id: "windUnit", label: "km/h"},
|
||||
]}
|
||||
]
|
||||
},
|
||||
]},
|
||||
]}]
|
||||
{type: "h", valign : 1, fillx:1, c: [
|
||||
{type: "img", filly: 1, id: "weatherIcon", src: sunIcon},
|
||||
{type: "v", fillx:1, c: [
|
||||
{type: "h", c: [
|
||||
{type: "txt", font: "10%", id: "temp", label: "000"},
|
||||
{type: "txt", font: "10%", id: "tempUnit", label: "°C"},
|
||||
]},
|
||||
{type: "h", c: [
|
||||
{type: "txt", font: "10%", id: "wind", label: "00"},
|
||||
{type: "txt", font: "10%", id: "windUnit", label: "km/h"},
|
||||
]}
|
||||
]
|
||||
},
|
||||
]}]
|
||||
});
|
||||
|
||||
// timeout used to update every minute
|
||||
|
@ -133,4 +131,4 @@ Bangle.setUI("clock"); // Show launcher when middle button pressed
|
|||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
clockLayout.render();
|
||||
draw();
|
||||
draw();
|
||||
|
|
|
@ -244,5 +244,6 @@ setWatch(()=>{
|
|||
}, BTN1, {repeat:true});
|
||||
|
||||
Bangle.setLCDTimeout(0);
|
||||
Bangle.setLocked(0);
|
||||
Bangle.setLCDPower(1);
|
||||
move(0);
|
||||
|
|
Loading…
Reference in New Issue