Merge branch 'master' of https://github.com/espruino/BangleApps into compass
# Conflicts: # apps/compass/compass.jsmaster
commit
3cdd0f7820
37
apps.json
37
apps.json
|
|
@ -137,7 +137,7 @@
|
|||
"name": "Default Alarm",
|
||||
"shortName":"Alarms",
|
||||
"icon": "app.png",
|
||||
"version":"0.07",
|
||||
"version":"0.08",
|
||||
"description": "Set and respond to alarms",
|
||||
"tags": "tool,alarm,widget",
|
||||
"storage": [
|
||||
|
|
@ -280,7 +280,7 @@
|
|||
{ "id": "gpstime",
|
||||
"name": "GPS Time",
|
||||
"icon": "gpstime.png",
|
||||
"version":"0.03",
|
||||
"version":"0.04",
|
||||
"description": "Update the Bangle.js's clock based on the time from the GPS receiver",
|
||||
"tags": "tool,gps",
|
||||
"storage": [
|
||||
|
|
@ -303,7 +303,7 @@
|
|||
{ "id": "speedo",
|
||||
"name": "Speedo",
|
||||
"icon": "speedo.png",
|
||||
"version":"0.03",
|
||||
"version":"0.04",
|
||||
"description": "Show the current speed according to the GPS",
|
||||
"tags": "tool,outdoors,gps",
|
||||
"storage": [
|
||||
|
|
@ -888,7 +888,7 @@
|
|||
{ "id": "berlinc",
|
||||
"name": "Berlin Clock",
|
||||
"icon": "berlin-clock.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "Berlin Clock (see https://en.wikipedia.org/wiki/Mengenlehreuhr)",
|
||||
"tags": "clock",
|
||||
"type":"clock",
|
||||
|
|
@ -1727,7 +1727,7 @@
|
|||
{ "id": "rndmclk",
|
||||
"name": "Random Clock Loader",
|
||||
"icon": "rndmclk.png",
|
||||
"version":"0.02",
|
||||
"version":"0.03",
|
||||
"description": "Load a different clock whenever the LCD is switched on.",
|
||||
"readme": "README.md",
|
||||
"tags": "widget,clock",
|
||||
|
|
@ -1774,5 +1774,32 @@
|
|||
"storage": [
|
||||
{"name":"widviz.wid.js","url":"widget.js"}
|
||||
]
|
||||
},
|
||||
{ "id": "binclock",
|
||||
"name": "Binary Clock",
|
||||
"shortName":"Binary Clock",
|
||||
"icon": "app.png",
|
||||
"version":"0.02",
|
||||
"description": "A binary clock with hours and minutes. BTN1 toggles a digital clock.",
|
||||
"tags": "clock,binary",
|
||||
"type": "clock",
|
||||
"storage": [
|
||||
{"name":"binclock.app.js","url":"app.js"},
|
||||
{"name":"binclock.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
} ,
|
||||
{
|
||||
"id": "pizzatimer",
|
||||
"name": "Pizza Timer",
|
||||
"shortName":"Pizza Timer",
|
||||
"icon": "pizza.png",
|
||||
"version":"0.01",
|
||||
"description": "A timer app for when you cook Pizza. Some say it can also time other things",
|
||||
"tags": "timer,tool,pizza",
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"pizzatimer.app.js","url":"app.js"},
|
||||
{"name":"pizzatimer.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
|||
|
|
@ -0,0 +1,159 @@
|
|||
{
|
||||
"env": {
|
||||
// TODO: "espruino": false
|
||||
// TODO: "banglejs": false
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
// Methods and Fields at https://banglejs.com/reference
|
||||
"Array": "readonly",
|
||||
"ArrayBuffer": "readonly",
|
||||
"ArrayBufferView": "readonly",
|
||||
"Bangle": "readonly",
|
||||
"BluetoothDevice": "readonly",
|
||||
"BluetoothRemoteGATTCharacteristic": "readonly",
|
||||
"BluetoothRemoteGATTServer": "readonly",
|
||||
"BluetoothRemoteGATTService": "readonly",
|
||||
"Boolean": "readonly",
|
||||
"console": "readonly",
|
||||
"DataView": "readonly",
|
||||
"Date": "readonly",
|
||||
"E": "readonly",
|
||||
"Error": "readonly",
|
||||
"Flash": "readonly",
|
||||
"Float32Array": "readonly",
|
||||
"Float64Array": "readonly",
|
||||
"fs": "readonly",
|
||||
"Function": "readonly",
|
||||
"Graphics": "readonly",
|
||||
"heatshrink": "readonly",
|
||||
"I2C": "readonly",
|
||||
"Int16Array": "readonly",
|
||||
"Int32Array": "readonly",
|
||||
"Int8Array": "readonly",
|
||||
"InternalError": "readonly",
|
||||
"JSON": "readonly",
|
||||
"Math": "readonly",
|
||||
"Modules": "readonly",
|
||||
"NRF": "readonly",
|
||||
"Number": "readonly",
|
||||
"Object": "readonly",
|
||||
"OneWire": "readonly",
|
||||
"Pin": "readonly",
|
||||
"process": "readonly",
|
||||
"Promise": "readonly",
|
||||
"ReferenceError": "readonly",
|
||||
"RegExp": "readonly",
|
||||
"Serial": "readonly",
|
||||
"SPI": "readonly",
|
||||
"Storage": "readonly",
|
||||
"StorageFile": "readonly",
|
||||
"String": "readonly",
|
||||
"SyntaxError": "readonly",
|
||||
"tensorflow": "readonly",
|
||||
"TFMicroInterpreter": "readonly",
|
||||
"TypeError": "readonly",
|
||||
"Uint16Array": "readonly",
|
||||
"Uint24Array": "readonly",
|
||||
"Uint32Array": "readonly",
|
||||
"Uint8Array": "readonly",
|
||||
"Uint8ClampedArray": "readonly",
|
||||
"Waveform": "readonly",
|
||||
// Methods and Fields at https://banglejs.com/reference
|
||||
"analogRead": "readonly",
|
||||
"analogWrite": "readonly",
|
||||
"arguments": "readonly",
|
||||
"atob": "readonly",
|
||||
"Bluetooth": "readonly",
|
||||
"BTN": "readonly",
|
||||
"BTN1": "readonly",
|
||||
"BTN2": "readonly",
|
||||
"BTN3": "readonly",
|
||||
"BTN4": "readonly",
|
||||
"BTN5": "readonly",
|
||||
"btoa": "readonly",
|
||||
"changeInterval": "readonly",
|
||||
"clearInterval": "readonly",
|
||||
"clearTimeout": "readonly",
|
||||
"clearWatch": "readonly",
|
||||
"decodeURIComponent": "readonly",
|
||||
"digitalPulse": "readonly",
|
||||
"digitalRead": "readonly",
|
||||
"digitalWrite": "readonly",
|
||||
"dump": "readonly",
|
||||
"echo": "readonly",
|
||||
"edit": "readonly",
|
||||
"encodeURIComponent": "readonly",
|
||||
"eval": "readonly",
|
||||
"getPinMode": "readonly",
|
||||
"getSerial": "readonly",
|
||||
"getTime": "readonly",
|
||||
"global": "readonly",
|
||||
"HIGH": "readonly",
|
||||
"I2C1": "readonly",
|
||||
"Infinity": "readonly",
|
||||
"isFinite": "readonly",
|
||||
"isNaN": "readonly",
|
||||
"LED": "readonly",
|
||||
"LED1": "readonly",
|
||||
"LED2": "readonly",
|
||||
"load": "readonly",
|
||||
"LoopbackA": "readonly",
|
||||
"LoopbackB": "readonly",
|
||||
"LOW": "readonly",
|
||||
"NaN": "readonly",
|
||||
"parseFloat": "readonly",
|
||||
"parseInt": "readonly",
|
||||
"peek16": "readonly",
|
||||
"peek32": "readonly",
|
||||
"peek8": "readonly",
|
||||
"pinMode": "readonly",
|
||||
"poke16": "readonly",
|
||||
"poke32": "readonly",
|
||||
"poke8": "readonly",
|
||||
"print": "readonly",
|
||||
"require": "readonly",
|
||||
"reset": "readonly",
|
||||
"save": "readonly",
|
||||
"Serial1": "readonly",
|
||||
"setBusyIndicator": "readonly",
|
||||
"setInterval": "readonly",
|
||||
"setSleepIndicator": "readonly",
|
||||
"setTime": "readonly",
|
||||
"setTimeout": "readonly",
|
||||
"setWatch": "readonly",
|
||||
"shiftOut": "readonly",
|
||||
"SPI1": "readonly",
|
||||
"Terminal": "readonly",
|
||||
"trace": "readonly",
|
||||
"VIBRATE": "readonly",
|
||||
// Aliases and not defined at https://banglejs.com/reference
|
||||
"g": "readonly",
|
||||
"WIDGETS": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 11
|
||||
},
|
||||
"rules": {
|
||||
"indent": [
|
||||
"warn",
|
||||
2,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
],
|
||||
"no-case-declarations": "off",
|
||||
"no-constant-condition": "off",
|
||||
"no-delete-var": "off",
|
||||
"no-empty": "off",
|
||||
"no-global-assign": "off",
|
||||
"no-inner-declarations": "off",
|
||||
"no-octal": "off",
|
||||
"no-prototype-builtins": "off",
|
||||
"no-redeclare": "off",
|
||||
// TODO: "no-undef": "warn",
|
||||
"no-undef": "off",
|
||||
"no-unused-vars": "off",
|
||||
"no-useless-escape": "off"
|
||||
}
|
||||
}
|
||||
|
|
@ -5,3 +5,4 @@
|
|||
0.05: Add alarm.boot.js and move code from the bootloader
|
||||
0.06: Change 'New Alarm' to 'Save', allow Deletion of Alarms
|
||||
0.07: Don't overwrite existing settings on app update
|
||||
0.08: Make alarm scheduling more reliable
|
||||
|
|
|
|||
|
|
@ -2,15 +2,16 @@
|
|||
(function() {
|
||||
var alarms = require('Storage').readJSON('alarm.json',1)||[];
|
||||
var time = new Date();
|
||||
var active = alarms.filter(a=>a.on&&(a.last!=time.getDate()));
|
||||
var active = alarms.filter(a=>a.on);
|
||||
if (active.length) {
|
||||
active = active.sort((a,b)=>a.hr-b.hr);
|
||||
active = active.sort((a,b)=>(a.hr-b.hr)+(a.last-b.last)*24);
|
||||
var hr = time.getHours()+(time.getMinutes()/60)+(time.getSeconds()/3600);
|
||||
if (!require('Storage').read("alarm.js")) {
|
||||
console.log("No alarm app!");
|
||||
require('Storage').write('alarm.json',"[]")
|
||||
require('Storage').write('alarm.json',"[]");
|
||||
} else {
|
||||
var t = 3600000*(active[0].hr-hr);
|
||||
if (active[0].last == time.getDate() || t < 0) t += 86400000;
|
||||
if (t<1000) t=1000;
|
||||
/* execute alarm at the correct time. We avoid execing immediately
|
||||
since this code will get called AGAIN when alarm.js is loaded. alarm.js
|
||||
|
|
@ -21,4 +22,4 @@
|
|||
},t);
|
||||
}
|
||||
}
|
||||
})()
|
||||
})();
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
0.02: Modified for use with new bootloader and firmware
|
||||
0.03: Shrinked size to avoid cut-off edges on the physical device. BTN3: show date. BTN1: show time in decimal.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,10 @@
|
|||
# Berlin Clock Watch Face
|
||||
|
||||
This is a clock-face analogous to the [Berlin Clock](https://en.wikipedia.org/wiki/Mengenlehreuhr).
|
||||
|
||||
## Usage
|
||||
|
||||
* BTN1: toggle displaying the time in decimal figures (24 hour format) in the minutes fields. The first two fields are used for the hour and the last two fields for the minute. This might be a help when you're still familarizig yourself with this new way to express the time.
|
||||
* BTN2: start the launcher
|
||||
* BTN3: toggle displaying the current date (in ISO 8601 format) below the actual clock-face.
|
||||
|
||||
|
|
@ -1,34 +1,58 @@
|
|||
// place your const, vars, functions or classes here
|
||||
fields = [ 4 , 4 , 11 , 4 ];
|
||||
width = g.getWidth();
|
||||
height = g.getHeight();
|
||||
rowHeight = height/4;
|
||||
// Berlin Clock see https://en.wikipedia.org/wiki/Mengenlehreuhr
|
||||
// https://github.com/eska-muc/BangleApps
|
||||
const fields = [4, 4, 11, 4];
|
||||
const offset = 20;
|
||||
const width = g.getWidth() - 2 * offset;
|
||||
const height = g.getHeight() - 2 * offset;
|
||||
const rowHeight = height / 4;
|
||||
|
||||
var show_date = false;
|
||||
var show_time = false;
|
||||
var yy = 0;
|
||||
|
||||
rowlights = [];
|
||||
time_digit = [];
|
||||
|
||||
function drawBerlinClock() {
|
||||
g.clear();
|
||||
var now = new Date();
|
||||
|
||||
// show date below the clock
|
||||
if (show_date) {
|
||||
var yr = now.getFullYear();
|
||||
var month = now.getMonth() + 1;
|
||||
var day = now.getDate();
|
||||
var dateString = `${yr}-${month < 10 ? '0' : ''}${month}-${day < 10 ? '0' : ''}${day}`;
|
||||
var strWidth = g.stringWidth(dateString);
|
||||
g.setColor(1, 1, 1);
|
||||
g.setFontAlign(-1,-1);
|
||||
g.drawString(dateString, ( g.getWidth() - strWidth ) / 2, height + offset + 4);
|
||||
}
|
||||
|
||||
rowlights[0] = Math.floor(now.getHours() / 5);
|
||||
rowlights[1] = now.getHours() % 5;
|
||||
rowlights[2] = Math.floor(now.getMinutes() / 5);
|
||||
rowlights[3] = now.getMinutes() % 5;
|
||||
|
||||
g.clear();
|
||||
time_digit[0] = Math.floor(now.getHours() / 10);
|
||||
time_digit[1] = now.getHours() % 10;
|
||||
time_digit[2] = Math.floor(now.getMinutes() / 10);
|
||||
time_digit[3] = now.getMinutes() % 10;
|
||||
|
||||
g.drawRect(0,0,width,height);
|
||||
g.drawRect(offset, offset, width + offset, height + offset);
|
||||
for (row = 0; row < 4; row++) {
|
||||
nfields = fields[row];
|
||||
boxWidth = width / nfields;
|
||||
|
||||
for (col = 0; col < nfields; col++) {
|
||||
x1 = col*boxWidth;
|
||||
y1 = row*rowHeight;
|
||||
x2 = (col+1)*boxWidth;
|
||||
y2 = (row+1)*rowHeight;
|
||||
x1 = col * boxWidth + offset;
|
||||
y1 = row * rowHeight + offset;
|
||||
x2 = (col + 1) * boxWidth + offset;
|
||||
y2 = (row + 1) * rowHeight + offset;
|
||||
|
||||
g.setColor(1, 1, 1);
|
||||
g.drawRect(x1, y1, x2, y2);
|
||||
if (col < rowlights[row]) {
|
||||
|
||||
if (row === 2) {
|
||||
if (((col + 1) % 3) === 0) {
|
||||
g.setColor(1, 0, 0);
|
||||
|
|
@ -38,12 +62,26 @@ function drawBerlinClock() {
|
|||
} else {
|
||||
g.setColor(1, 0, 0);
|
||||
}
|
||||
|
||||
g.fillRect(x1 + 2, y1 + 2, x2 - 2, y2 - 2);
|
||||
}
|
||||
if (row == 3 && show_time) {
|
||||
g.setColor(1,1,1);
|
||||
g.setFontAlign(0,0);
|
||||
g.drawString(time_digit[col],(x1+x2)/2,(y1+y2)/2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function toggleDate() {
|
||||
show_date = ! show_date;
|
||||
drawBerlinClock();
|
||||
}
|
||||
|
||||
function toggleTime() {
|
||||
show_time = ! show_time;
|
||||
drawBerlinClock();
|
||||
}
|
||||
|
||||
// special function to handle display switch on
|
||||
Bangle.on('lcdPower', (on) => {
|
||||
|
|
@ -52,7 +90,8 @@ Bangle.on('lcdPower', (on) => {
|
|||
Bangle.drawWidgets();
|
||||
// call your app function here
|
||||
drawBerlinClock();
|
||||
}});
|
||||
}
|
||||
});
|
||||
|
||||
// refesh every 15 sec
|
||||
setInterval(drawBerlinClock, 15E3);
|
||||
|
|
@ -61,5 +100,9 @@ g.clear();
|
|||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
drawBerlinClock();
|
||||
// Toggle date display, when BTN3 is pressed
|
||||
setWatch(toggleTime,BTN1, { repeat : true, edge: "falling"});
|
||||
// Toggle date display, when BTN3 is pressed
|
||||
setWatch(toggleDate,BTN3, { repeat : true, edge: "falling"});
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
||||
|
|
|
|||
|
|
@ -0,0 +1,2 @@
|
|||
0.01: New App!
|
||||
0.02: Fixed bug where screen didn't clear so incorrect time displayed.
|
||||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwwkEIf4A/AH8AgP/iAECiIJCj/xAgURBoUAn8gAYMP//wAgIMBBwX//4gCAIUAgf/EIUfC5QEBC5MCI4gNCEIPyAgRGDLQMwBIwEJEAYEFAH7v3dQTpDAZ6cDdIYDPdQbpDAZ8QYgTpDAZ5IEAaYAeM4cRTYSuQiABBiQCBbckjmQzFmcggUzGJkBBoMDQgcSkMAAIIXOgL8CC6gvRL4b2CL4MwTIotJAAJfJiIiCC5RfHF4LdHC4wvGAwIvHL5UDYQIuBF44A/AH4A/AH4AbA"))
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
// Load fonts
|
||||
require("Font7x11Numeric7Seg").add(Graphics);
|
||||
// position on screen
|
||||
const X = 160, Y = 180;
|
||||
var displayTime = 0;
|
||||
var minuteLED = [0,0,0,0,0,0];
|
||||
var hourLED = [0,0,0,0,0];
|
||||
var prevMinute = [0,0,0,0,0,0];
|
||||
var prevHour = [0,0,0,0,0];
|
||||
|
||||
|
||||
function drawTime(d) {
|
||||
// work out how to display the current time
|
||||
var h = d.getHours(), m = d.getMinutes();
|
||||
var time = (" "+h).substr(-2) + ":" + ("0"+m).substr(-2);
|
||||
// draw the current time (4x size 7 segment)
|
||||
g.setFont("7x11Numeric7Seg",4);
|
||||
g.setFontAlign(1,1); // align right bottom
|
||||
g.drawString(time, X, Y, true /*clear background*/);
|
||||
// draw the seconds (2x size 7 segment)
|
||||
g.setFont("7x11Numeric7Seg",2);
|
||||
g.drawString(("0"+d.getSeconds()).substr(-2), X+30, Y, true /*clear background*/);
|
||||
}
|
||||
|
||||
function updateHourArray(hours){
|
||||
|
||||
var j;
|
||||
for(j=0;j<hourLED.length;j++){
|
||||
prevHour[j] = hourLED[j];
|
||||
}
|
||||
|
||||
var i;
|
||||
for(i = 0;i < hourLED.length;i++){
|
||||
hourLED[i]=0;
|
||||
}
|
||||
|
||||
if(hours > 15){
|
||||
hourLED[0] = 1;
|
||||
hours = hours - 16;
|
||||
}
|
||||
if(hours > 7){
|
||||
hourLED[1] = 1;
|
||||
hours = hours - 8;
|
||||
}
|
||||
if(hours > 3){
|
||||
hourLED[2] = 1;
|
||||
hours = hours - 4;
|
||||
}
|
||||
if(hours > 1){
|
||||
hourLED[3] = 1;
|
||||
hours = hours - 2;
|
||||
}
|
||||
if(hours > 0){
|
||||
hourLED[4] = 1;
|
||||
}
|
||||
|
||||
return hourLED;
|
||||
|
||||
}
|
||||
|
||||
function updateMinuteArray(minutes){
|
||||
var j;
|
||||
for(j=0;j<minuteLED.length;j++){
|
||||
prevMinute[j] = minuteLED[j];
|
||||
}
|
||||
|
||||
var i;
|
||||
for(i = 0;i < minuteLED.length;i++){
|
||||
minuteLED[i]=0;
|
||||
}
|
||||
|
||||
if(minutes > 31){
|
||||
minuteLED[0] = 1;
|
||||
minutes = minutes - 32;
|
||||
}
|
||||
if(minutes > 15){
|
||||
minuteLED[1] = 1;
|
||||
minutes = minutes - 16;
|
||||
}
|
||||
if(minutes > 7){
|
||||
minuteLED[2] = 1;
|
||||
minutes = minutes - 8;
|
||||
}
|
||||
if(minutes > 3){
|
||||
minuteLED[3] = 1;
|
||||
minutes = minutes - 4;
|
||||
}
|
||||
if(minutes > 1){
|
||||
minuteLED[4] = 1;
|
||||
minutes = minutes - 2;
|
||||
}
|
||||
if(minutes > 0){
|
||||
minuteLED[5] = 1;
|
||||
}
|
||||
|
||||
return minuteLED;
|
||||
|
||||
}
|
||||
|
||||
function draw(){
|
||||
|
||||
// work out how to display the current time
|
||||
var d = new Date();
|
||||
var h = d.getHours(), m = d.getMinutes();
|
||||
|
||||
updateHourArray(h);
|
||||
updateMinuteArray(m);
|
||||
|
||||
var i;
|
||||
//Draw hour circles
|
||||
for(i=0; i<hourLED.length; i++){
|
||||
if(prevHour[i] == hourLED[i]){
|
||||
if(hourLED[i] == 1){
|
||||
g.fillCircle(24+i*48,50,10);
|
||||
} else {
|
||||
var colour = g.getColor();
|
||||
g.setColor(0,0,0);
|
||||
g.fillCircle(24+i*48,50,10);
|
||||
g.setColor(colour);
|
||||
g.drawCircle(24+i*48,50,10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(i=0; i<minuteLED.length; i++){
|
||||
if(prevMinute[i] == minuteLED[i]){
|
||||
if(minuteLED[i] == 1){
|
||||
g.fillCircle(20+i*40,100,10);
|
||||
} else {
|
||||
var colour = g.getColor();
|
||||
g.setColor(0,0,0);
|
||||
g.fillCircle(20+i*40,100,10);
|
||||
g.setColor(colour);
|
||||
g.drawCircle(20+i*40,100,10);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// draw the date, in a normal font
|
||||
g.setFont("6x8");
|
||||
g.setFontAlign(0,1); // align center bottom
|
||||
// pad the date - this clears the background if the date were to change length
|
||||
var dateStr = " "+require("locale").date(d)+" ";
|
||||
g.drawString(dateStr, g.getWidth()/2, 130, true /*clear background*/);
|
||||
|
||||
if(displayTime){
|
||||
drawTime(d);
|
||||
}else{
|
||||
g.clearRect(0,240,240,130);
|
||||
}
|
||||
}
|
||||
|
||||
// Clear the screen once, at startup
|
||||
g.clear();
|
||||
// draw immediately at first
|
||||
draw();
|
||||
var secondInterval = setInterval(draw, 1000);
|
||||
// Stop updates when LCD is off, restart when on
|
||||
Bangle.on('lcdPower',on=>{
|
||||
if (secondInterval) clearInterval(secondInterval);
|
||||
secondInterval = undefined;
|
||||
if (on) {
|
||||
setInterval(draw, 1000);
|
||||
draw(); // draw immediately
|
||||
}
|
||||
});
|
||||
// Load widgets
|
||||
Bangle.loadWidgets();
|
||||
Bangle.drawWidgets();
|
||||
// Show launcher when middle button pressed
|
||||
setWatch(Bangle.showLauncher, BTN2, { repeat: false, edge: "falling" });
|
||||
setWatch(function() {
|
||||
if(displayTime == 0){
|
||||
displayTime = 1;
|
||||
} else{
|
||||
displayTime = 0;
|
||||
}
|
||||
}, BTN, {edge:"rising", debounce:50, repeat:true});
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 709 B |
|
|
@ -15,7 +15,8 @@
|
|||
"rules": {
|
||||
"indent": [
|
||||
"error",
|
||||
2
|
||||
2,
|
||||
{ "SwitchCase": 1 }
|
||||
],
|
||||
"linebreak-style": [
|
||||
"error",
|
||||
|
|
@ -24,10 +25,11 @@
|
|||
"quotes": [
|
||||
"error",
|
||||
"double"
|
||||
],
|
||||
]
|
||||
/*,
|
||||
"semi": [
|
||||
"error",
|
||||
"always"
|
||||
]
|
||||
]*/
|
||||
}
|
||||
}
|
||||
|
|
@ -150,4 +150,4 @@ exports = class Exercise {
|
|||
|
||||
workout.emit("redraw");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -25,4 +25,4 @@ exports = class Set {
|
|||
if (this.reps <= this.minReps) return;
|
||||
this.reps--;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -3,7 +3,7 @@ exports = class Workout {
|
|||
this.title = params.title;
|
||||
this.exercises = [];
|
||||
this.completed = false;
|
||||
this.on("redraw", redraw.bind(null, this));
|
||||
this.on("redraw", params.redraw.bind(null, this));
|
||||
}
|
||||
|
||||
addExercises(exercises) {
|
||||
|
|
@ -27,11 +27,12 @@ exports = class Workout {
|
|||
return !!this.completed;
|
||||
}
|
||||
|
||||
static fromJSON(workoutJSON) {
|
||||
static fromJSON(workoutJSON, redraw) {
|
||||
const Set = require("buffgym-set.js");
|
||||
const Exercise = require("buffgym-exercise.js");
|
||||
const workout = new this({
|
||||
title: workoutJSON.title,
|
||||
redraw: redraw,
|
||||
});
|
||||
const exercises = workoutJSON.exercises.map(exerciseJSON => {
|
||||
const exercise = new Exercise({
|
||||
|
|
@ -80,4 +81,4 @@ exports = class Workout {
|
|||
// Call current exercise state machine
|
||||
this.currentExercise().next(this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -248,7 +248,7 @@ function getWorkoutIndex() {
|
|||
function buildWorkout(fName) {
|
||||
const Workout = require("buffgym-workout.js");
|
||||
const workoutJSON = require("Storage").readJSON(fName);
|
||||
const workout = Workout.fromJSON(workoutJSON);
|
||||
const workout = Workout.fromJSON(workoutJSON, redraw);
|
||||
|
||||
return workout;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ function setButtons(){
|
|||
setWatch(nextwp.bind(null,-1), BTN1, {repeat:true,edge:"falling"});
|
||||
setWatch(doselect, BTN2, {repeat:true,edge:"falling"});
|
||||
setWatch(nextwp.bind(null,1), BTN3, {repeat:true,edge:"falling"});
|
||||
};
|
||||
}
|
||||
|
||||
var SCREENACCESS = {
|
||||
withApp:true,
|
||||
|
|
|
|||
|
|
@ -1 +1,2 @@
|
|||
0.03: Fix time output on new firmwares when no GPS time set (fix #104)
|
||||
0.04: Fix shown UTC time zone sign
|
||||
|
|
@ -47,7 +47,7 @@ Bangle.on('GPS',function(f) {
|
|||
g.drawString(t[4],120,185); // time
|
||||
if (fix.time) {
|
||||
// timezone
|
||||
var tz = (new Date()).getTimezoneOffset()/60;
|
||||
var tz = (new Date()).getTimezoneOffset()/-60;
|
||||
if (tz==0) tz="UTC";
|
||||
else if (tz>0) tz="UTC+"+tz;
|
||||
else tz="UTC"+tz;
|
||||
|
|
|
|||
|
|
@ -95,7 +95,7 @@ function startKeyboardHID() {
|
|||
getCharacter().then(ch => {
|
||||
return sendHID(KEY[ch]);
|
||||
}).then(startKeyboardHID);
|
||||
};
|
||||
}
|
||||
|
||||
if (settings.HID=="kb" || settings.HID=="kbmedia") {
|
||||
if (settings.HID=="kbmedia") {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ function draw() {
|
|||
cg.setFontAlign(1,-1);
|
||||
cg.drawString(hours, x, 0);
|
||||
x+=2;
|
||||
if (t.getSeconds() & 1)
|
||||
cg.fillRect(x, 10, x+2, 10+2).fillRect(x, 20, x+2, 20+2);
|
||||
x+=6;
|
||||
cg.setFontAlign(-1,-1);
|
||||
|
|
|
|||
|
|
@ -446,5 +446,23 @@ var locales = {
|
|||
abday: "ne,po,út,st,čt,pá,so",
|
||||
day: "neděle,pondělí,úterý,středa,čtvrtek,pátek,sobota",
|
||||
trans: { yes: "tak", Yes: "Tak", no: "nie", No: "Nie", ok: "ok", on: "na", off: "poza" }
|
||||
},
|
||||
"sl_SI": {
|
||||
lang: "sl_SI",
|
||||
decimal_point: ",",
|
||||
thousands_sep: ".",
|
||||
currency_symbol: "\x80",
|
||||
int_curr_symbol: "EUR",
|
||||
speed: "km/h",
|
||||
distance: { 0: "m", 1: "km" },
|
||||
temperature: "°C",
|
||||
ampm: { 0: "dop.", 1: "pop." },
|
||||
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
||||
datePattern: { 0: "%d. %b %Y", 1: "%d.%m.%Y" }, // "30. jan. 2020" // "30.01.2020"(short)
|
||||
abmonth: "jan.,feb.,mar.,apr.,maj,jun.,jul.,avg.,sep.,okt.,nov.,dec.",
|
||||
month: "januar,februar,marec,april,maj,junij,julij,avgust,september,oktober,november,december",
|
||||
abday: "ned.,pon.,tor.,sre.,čet.,pet.,sob.",
|
||||
day: "nedelja,ponedeljek,torek,sreda,četrtek,petek,sobota",
|
||||
trans: { yes: "da", Yes: "Da", no: "ne", No: "Ne", ok: "ok", on: "On", off: "Off" }
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
(function(back) {
|
||||
function updateSettings() {
|
||||
storage.write('numerals.json', numeralsSettings);
|
||||
};
|
||||
}
|
||||
function resetSettings() {
|
||||
numeralsSettings = {
|
||||
color:0,
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.01: You can now time cooking a Pizza!
|
||||
|
|
@ -0,0 +1 @@
|
|||
# Pizza Timer
|
||||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwwkBiIA/AH4AwgCzUgEFqtVDIcQDpkQgtO9wACqAfCoAYKCwIVD93kCQMQgAcDAA8F73tqEAAAQXC6Fe8owIiFO9peBpvdAAIRBgvdHQIwIggKBhsNCoPUF4UEgtAp3gFxHlhsFgvQptAFAMQGoPUhpmCLoouB7tArvV7tVC4QEBAIPuC40O8hECAAVVIwXQKIPQC4xGB8FNotEgBBBXIMQhtAIwPQpx4FiBGCotFgFd7vQBQIUBF4NAhwIBLwpGC6ovCEwMAhvUqvVgsOSAsNRoJcCCwKlCgsNPoIXBCAJ2FLwJ2EgpeBGgKOBD4MEVAkQr3QaAIxCqgvBiFUNAMES4SQERwNA6tdBoPVhpeBCYVQQYKXBC4veNQMECIR2CAoUFoB/CC4vugoJBUgIABBgMQgtNoEFbQMA91RC4wAEgALCYoVQ6HQ7wvFOoYAB6DaBBoSMBBAMApxHGgC9BBgPUprbBB4RLBO4NNC4tVgqMBoHQYgQcBDAcAoFUR4tQhvQKoQuBroDBDAZLBKAYXCCoKzCJYKtBb4QHBGQYXEp3gC4XUVIYFBAQVQGYgACr3gCYVFAQJgCAwIKB6kEqAYFh3lU4JBCAQLDDUwNAH4IvFgnuhtF6FdCAJFDggGBgvuoAXFVANQC4NVhoxBqAUBPAVe9xfGPAKfBIgNNgsNhtVGAPVFwPlC40RhvkIgQqCLgQFBpw9BCwzHBKIKRFAANQIoIuIJAIwBgFUCodFgFd93tdggwGpwYBAAhEBIoIuIDAnu6lEolNCoIWNDAVUCYQAB6sACxoYCgEFqtQAgIVOAH4AC"))
|
||||
|
|
@ -0,0 +1,270 @@
|
|||
/* UI GLOBALS */
|
||||
|
||||
const HOUR_SCENE = 0;
|
||||
const MIN_SCENE = 1;
|
||||
const SEC_SCENE = 2;
|
||||
const COUNTDOWN_SCENE = 3;
|
||||
|
||||
var currentScene = 0;
|
||||
|
||||
var btn1Watch;
|
||||
var btn2Watch;
|
||||
var btn3Watch;
|
||||
|
||||
var drawInterval;
|
||||
|
||||
/* STATE GLOBALS */
|
||||
|
||||
var menuTime = new Uint8Array([0,0,0]);
|
||||
var countdownTime = menuTime.slice(0);
|
||||
var show = [true, true, true];
|
||||
|
||||
/* COUNTDOWN CONSTANTS */
|
||||
|
||||
const HOUR_INDEX = 0;
|
||||
const MIN_INDEX = 1;
|
||||
const SEC_INDEX = 2;
|
||||
|
||||
var flashIndex = HOUR_INDEX;
|
||||
|
||||
/* logic */
|
||||
|
||||
function setCountdownTime() {
|
||||
countdownTime = menuTime.slice(0);
|
||||
}
|
||||
|
||||
function countDownFinished() {
|
||||
return countdownTime[HOUR_INDEX] <= 0 &&
|
||||
countdownTime[MIN_INDEX] <= 0 &&
|
||||
countdownTime[SEC_INDEX] <= 0;
|
||||
}
|
||||
|
||||
function alertCountdownFinished() {
|
||||
if (drawInterval) return;
|
||||
Bangle.buzz()
|
||||
.then(() => new Promise(resolve => setTimeout(resolve, 200)))
|
||||
.then(() => Bangle.buzz());
|
||||
setTimeout(alertCountdownFinished, 2000);
|
||||
}
|
||||
|
||||
function unsetDrawInterval() {
|
||||
clearInterval(drawInterval);
|
||||
drawInterval = undefined;
|
||||
}
|
||||
|
||||
function decrementCountdownTime() {
|
||||
const allZero = countDownFinished();
|
||||
|
||||
if(allZero) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (countdownTime[SEC_INDEX] !== 0) {
|
||||
countdownTime[SEC_INDEX] = countdownTime[SEC_INDEX] - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
countdownTime[SEC_INDEX] = 59;
|
||||
|
||||
if (countdownTime[MIN_INDEX] !== 0) {
|
||||
countdownTime[MIN_INDEX] = countdownTime[MIN_INDEX] - 1;
|
||||
return;
|
||||
}
|
||||
|
||||
countdownTime[MIN_INDEX] = 59;
|
||||
|
||||
if (countdownTime[HOUR_INDEX] !== 0) {
|
||||
countdownTime[HOUR_INDEX] = countdownTime[HOUR_INDEX] - 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
function toggleShow(timeIndex) {
|
||||
show[timeIndex] = !show[timeIndex];
|
||||
}
|
||||
|
||||
function twoPadded(i) {
|
||||
return i.length < 2 ? "0" + i : i;
|
||||
}
|
||||
|
||||
function getTimeString(t) {
|
||||
let hour = t[HOUR_INDEX].toString();
|
||||
let min = t[MIN_INDEX].toString();
|
||||
let sec = t[SEC_INDEX].toString();
|
||||
|
||||
hour = show[HOUR_INDEX] ? twoPadded(hour) : " ";
|
||||
min = show[MIN_INDEX] ? twoPadded(min) : " ";
|
||||
sec = show[SEC_INDEX] ? twoPadded(sec) : " ";
|
||||
|
||||
return hour + ":" + min + ":" + sec;
|
||||
}
|
||||
|
||||
/* drawing */
|
||||
|
||||
/*
|
||||
shamelessly stollen from Bluetooth Music Controls
|
||||
https://github.com/espruino/BangleApps/blob/6b09377414e02d575b8335bb051c831ecc9da9d9/apps/hidmsic/hid-music.js#L42
|
||||
*/
|
||||
function drawArrows() {
|
||||
function c(a) {
|
||||
return {
|
||||
width: 8,
|
||||
height: a.length,
|
||||
bpp: 1,
|
||||
buffer: (new Uint8Array(a)).buffer
|
||||
};
|
||||
}
|
||||
const d = g.getWidth() - 18;
|
||||
g.drawImage(c([16,56,124,254,16,16,16,16]),d,40);
|
||||
g.drawImage(c([16,16,16,16,254,124,56,16]),d,194);
|
||||
g.drawImage(c([0,8,12,14,255,14,12,8]),d,116);
|
||||
}
|
||||
|
||||
function drawTime(input) {
|
||||
g.clear();
|
||||
g.setFontAlign(0,0);
|
||||
g.setFont("4x6",5);
|
||||
g.drawString(input, g.getWidth() / 2, g.getHeight() / 2);
|
||||
}
|
||||
|
||||
function drawMenu() {
|
||||
const timeString = getTimeString(menuTime);
|
||||
drawTime(timeString);
|
||||
drawArrows();
|
||||
}
|
||||
|
||||
function drawCountdown() {
|
||||
const timeString = getTimeString(countdownTime);
|
||||
drawTime(timeString);
|
||||
}
|
||||
|
||||
/* button callbacks */
|
||||
|
||||
function getMaxSelectableTime() {
|
||||
return flashIndex === HOUR_INDEX ? 23 : 59;
|
||||
}
|
||||
|
||||
/* btn1 */
|
||||
|
||||
function incrementMenuTime() {
|
||||
const maxTime = getMaxSelectableTime();
|
||||
const currentTime = menuTime[flashIndex];
|
||||
const newTime = currentTime < maxTime ? currentTime + 1 : 0;
|
||||
menuTime[flashIndex] = newTime;
|
||||
}
|
||||
|
||||
/* btn2 */
|
||||
|
||||
function incrementScene() {
|
||||
currentScene++;
|
||||
}
|
||||
|
||||
function incrementFlashIndex() {
|
||||
flashIndex++;
|
||||
}
|
||||
|
||||
function showAll() {
|
||||
for(var i = 0; i < show.length; i++) {
|
||||
show[i] = true;
|
||||
}
|
||||
}
|
||||
|
||||
function showFlashIndex() {
|
||||
show[flashIndex] = true;
|
||||
}
|
||||
|
||||
function hideFlashIndex() {
|
||||
show[flashIndex] = false;
|
||||
}
|
||||
|
||||
function next() {
|
||||
incrementScene();
|
||||
|
||||
if (currentScene === COUNTDOWN_SCENE) {
|
||||
showAll();
|
||||
startCountdownScene();
|
||||
} else {
|
||||
showFlashIndex();
|
||||
incrementFlashIndex();
|
||||
hideFlashIndex();
|
||||
}
|
||||
}
|
||||
|
||||
/* btn3 */
|
||||
|
||||
function decrementMenuTime() {
|
||||
const maxTime = getMaxSelectableTime();
|
||||
const currentTime = menuTime[flashIndex];
|
||||
const newTime = currentTime > 0 ? currentTime - 1 : maxTime;
|
||||
menuTime[flashIndex] = newTime;
|
||||
}
|
||||
|
||||
/* watches */
|
||||
|
||||
function setupMenuWatches() {
|
||||
clearWatch();
|
||||
btn1Watch = setWatch(incrementMenuTime, BTN1, {repeat: true});
|
||||
btn2Watch = setWatch(next, BTN2, {repeat: true});
|
||||
btn3Watch = setWatch(decrementMenuTime, BTN3, {repeat: true});
|
||||
}
|
||||
|
||||
function setupCountdownWatches() {
|
||||
clearWatch();
|
||||
btn2Watch = setWatch(main, BTN2, {repeat: true});
|
||||
}
|
||||
|
||||
/* scenes */
|
||||
|
||||
function menu() {
|
||||
drawMenu();
|
||||
toggleShow(flashIndex);
|
||||
}
|
||||
|
||||
function countdown() {
|
||||
decrementCountdownTime();
|
||||
drawCountdown();
|
||||
|
||||
if (countDownFinished()) {
|
||||
unsetDrawInterval();
|
||||
alertCountdownFinished();
|
||||
}
|
||||
}
|
||||
|
||||
/* init */
|
||||
|
||||
function unsetDrawInterval() {
|
||||
if (!drawInterval) return;
|
||||
clearInterval(drawInterval);
|
||||
drawInterval = undefined;
|
||||
}
|
||||
|
||||
function startMenuScene() {
|
||||
setupMenuWatches();
|
||||
unsetDrawInterval();
|
||||
menu();
|
||||
drawInterval = setInterval(menu, 500);
|
||||
}
|
||||
|
||||
function startCountdownScene() {
|
||||
setupCountdownWatches();
|
||||
unsetDrawInterval();
|
||||
setCountdownTime();
|
||||
showAll();
|
||||
drawCountdown();
|
||||
drawInterval = setInterval(countdown, 1000);
|
||||
}
|
||||
|
||||
/* main */
|
||||
|
||||
function reset() {
|
||||
currentScene = 0;
|
||||
flashIndex = HOUR_INDEX;
|
||||
hideFlashIndex();
|
||||
}
|
||||
|
||||
function main() {
|
||||
reset();
|
||||
startMenuScene();
|
||||
}
|
||||
|
||||
main();
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 4.1 KiB |
|
|
@ -1,2 +1,3 @@
|
|||
0.01: New widget
|
||||
0.02: Less invasive, change default clock setting instead of directly loading the new clock (no longer breaks Gadgetbridge notifications)
|
||||
0.03: Only changes when the widget id reloaded (no longer uses LCD turning off)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
# Summary
|
||||
Random Clock is a widget that will randomly show one of the installed watch faces each time the LCD is turned on.
|
||||
Random Clock is a widget that will randomly show one of the installed watch faces each time after the widget is (re-)loaded.
|
||||
|
||||
# How it works
|
||||
Everytime the LCD is turned off, the widget randomly changes the clock. When you long press BTN 3 the next time,
|
||||
Everytime the widget is reloaded, it randomly changes the clock. When you long press BTN 3 the next time,
|
||||
you might (or might not, it's random after all) see another watch face.
|
||||
|
|
@ -16,20 +16,18 @@
|
|||
if (clockApps && clockApps.length > 0) {
|
||||
var clockIndex = getRandomInt(clockApps.length);
|
||||
|
||||
// Only update the file if the clock really change to be nice to the FLASH mem
|
||||
// Only update the file if the clock really changed to be nice to the FLASH mem
|
||||
if (clockApps[clockIndex].src != currentClock) {
|
||||
currentClock = clockApps[clockIndex].src;
|
||||
settings = require("Storage").readJSON('setting.json', 1);
|
||||
settings.clock = clockApps[clockIndex].src;
|
||||
require("Storage").write('setting.json', settings);
|
||||
|
||||
console.log("RandomClockWidget set the clock to '" + clockApps[clockIndex].name + "'");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Bangle.on('lcdPower', (on) => {
|
||||
if (!on) {
|
||||
loadRandomClock();
|
||||
}
|
||||
});
|
||||
|
||||
})();
|
||||
|
|
@ -2,3 +2,4 @@
|
|||
0.02: Add widgets to app
|
||||
0.03: Use offscreen buffer (not doublebuffer)
|
||||
Use 'locale' to get internationalised speed
|
||||
0.04: Start GPS after loading app, just in case widgets affect it (#449)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,3 @@
|
|||
Bangle.setGPSPower(1);
|
||||
var buf = Graphics.createArrayBuffer(240,120,1,{msb:true});
|
||||
var lastFix = {fix:0,satellites:0};
|
||||
function onGPS(fix) {
|
||||
|
|
@ -31,3 +30,4 @@ Bangle.loadWidgets();
|
|||
Bangle.drawWidgets();
|
||||
|
||||
Bangle.on('GPS', onGPS);
|
||||
Bangle.setGPSPower(1);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ var SETTINGS = {
|
|||
};
|
||||
var Utils = require("../js/utils.js");
|
||||
var AppInfo = require("../js/appinfo.js");
|
||||
var noble = require('@abandonware/noble');
|
||||
var apps;
|
||||
|
||||
function ERROR(msg) {
|
||||
|
|
@ -62,7 +63,6 @@ function cmdInstallApp(appId) {
|
|||
}
|
||||
|
||||
function bangleSend(command) {
|
||||
var noble = require('noble');
|
||||
var log = function() {
|
||||
var args = [].slice.call(arguments);
|
||||
console.log("UART: "+args.join(" "));
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
espruinotools.js
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
{
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 6,
|
||||
"sourceType": "script"
|
||||
},
|
||||
"rules": {
|
||||
"indent": [
|
||||
"warn",
|
||||
2,
|
||||
{
|
||||
"SwitchCase": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"env": {
|
||||
"browser": true,
|
||||
"node": true
|
||||
}
|
||||
}
|
||||
|
|
@ -2,7 +2,7 @@ if (typeof btoa==="undefined") {
|
|||
// Don't define btoa as a function here because Apple's
|
||||
// iOS browser defines the function even though it's in
|
||||
// an IF statement that is never executed!
|
||||
btoa = function(d) { return BufferA.from(d).toString('base64'); }
|
||||
btoa = function(d) { return Buffer.from(d).toString('base64'); }
|
||||
}
|
||||
|
||||
// Converts a string into most efficient way to send to Espruino (either json, base64, or compressed base64)
|
||||
|
|
|
|||
|
|
@ -460,6 +460,10 @@ function refreshMyApps() {
|
|||
panelbody.innerHTML = appsInstalled.map(appInstalled => {
|
||||
var app = appNameToApp(appInstalled.id);
|
||||
var version = getVersionInfo(app, appInstalled);
|
||||
var username = "espruino";
|
||||
var githubMatch = window.location.href.match(/\/(\w+)\.github\.io/);
|
||||
if(githubMatch) username = githubMatch[1];
|
||||
var url = `https://github.com/${username}/BangleApps/tree/master/apps/${app.id}`;
|
||||
return `<div class="tile column col-6 col-sm-12 col-xs-12">
|
||||
<div class="tile-icon">
|
||||
<figure class="avatar"><img src="apps/${app.icon?`${app.id}/${app.icon}`:"unknown.png"}" alt="${escapeHtml(app.name)}"></figure>
|
||||
|
|
@ -467,6 +471,7 @@ return `<div class="tile column col-6 col-sm-12 col-xs-12">
|
|||
<div class="tile-content">
|
||||
<p class="tile-title text-bold">${escapeHtml(app.name)} <small>(${version.text})</small></p>
|
||||
<p class="tile-subtitle">${escapeHtml(app.description)}</p>
|
||||
<a href="${url}" target="_blank" class="link-github"><img src="img/github-icon-sml.png" alt="See the code on GitHub"/></a>
|
||||
</div>
|
||||
<div class="tile-action">
|
||||
<button class="btn btn-link btn-action btn-lg ${(appInstalled&&app.interface)?"":"d-hide"}" appid="${app.id}" title="Download data from app"><i class="icon icon-download"></i></button>
|
||||
|
|
|
|||
|
|
@ -4,10 +4,12 @@
|
|||
"author": "Gordon Williams <gw@pur3.co.uk> (http://espruino.com)",
|
||||
"version": "0.0.1",
|
||||
"devDependencies": {
|
||||
"acorn": ""
|
||||
"acorn": "",
|
||||
"eslint": "7.1.0"
|
||||
},
|
||||
"scripts": {
|
||||
"test": "node bin/sanitycheck.js",
|
||||
"lint-apps": "eslint ./apps --ext .js",
|
||||
"test": "node bin/sanitycheck.js && eslint ./apps --ext .js && eslint ./js",
|
||||
"start": "npx http-server"
|
||||
},
|
||||
"dependencies": {
|
||||
|
|
|
|||
Loading…
Reference in New Issue