Merge branch 'espruino:master' into grandfather-clock
|
|
@ -270,7 +270,8 @@ and which gives information about the app for the Launcher.
|
|||
// 'notify' - provides 'notify' library for showing notifications
|
||||
// 'locale' - provides 'locale' library for language-specific date/distance/etc
|
||||
// (a version of 'locale' is included in the firmware)
|
||||
"tags": "", // comma separated tag list for searching
|
||||
// 'defaultconfig' - a set of apps that will can be installed and will wipe out all previously installed apps
|
||||
"tags": "", // comma separated tag list for searching (don't include uppercase or spaces)
|
||||
// common types are:
|
||||
// 'clock' - it's a clock
|
||||
// 'widget' - it is (or provides) a widget
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"version": "0.02",
|
||||
"description": "A UI/UX for espruino smartwatches, displays dinamically calc. x,y coordinates.",
|
||||
"icon": "app.png",
|
||||
"tags": "Color,input,buttons,touch,UI",
|
||||
"tags": "color,input,buttons,touch,ui",
|
||||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"screenshots": [{"url":"UI4swatch_icon.png"},{"url":"UI4swatch_s1.png"}],
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"version": "0.01",
|
||||
"description": "Aerobic fitness test created by Léger & Lambert",
|
||||
"icon": "beeptest.png",
|
||||
"tags": "Health",
|
||||
"tags": "health",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
|
|
|
|||
|
|
@ -33,3 +33,4 @@ clkinfo.addInteractive that would cause ReferenceError.
|
|||
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.
|
||||
0.33: Fix issue rendering ClockInfos with for fg+bg color set to the same (#2749)
|
||||
0.34: Support 12-hour time format
|
||||
|
|
|
|||
|
|
@ -239,11 +239,9 @@ let drawTime = function() {
|
|||
var y = y1;
|
||||
var date = new Date();
|
||||
|
||||
var hours = String(date.getHours());
|
||||
var minutes = date.getMinutes();
|
||||
minutes = minutes < 10 ? String("0") + minutes : minutes;
|
||||
var colon = settings.hideColon ? "" : ":";
|
||||
var timeStr = hours + colon + minutes;
|
||||
var timeStr = locale.time(date, 1);
|
||||
if (settings.hideColon)
|
||||
timeStr = timeStr.replace(":", "");
|
||||
|
||||
// Set y coordinates correctly
|
||||
y += parseInt((H - y)/2) + 5;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "bwclk",
|
||||
"name": "BW Clock",
|
||||
"version": "0.33",
|
||||
"version": "0.34",
|
||||
"description": "A very minimalistic clock.",
|
||||
"readme": "README.md",
|
||||
"icon": "app.png",
|
||||
|
|
|
|||
|
|
@ -36,3 +36,4 @@ clkinfo.addInteractive that would cause ReferenceError.
|
|||
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.
|
||||
0.34: Fix issue rendering ClockInfos with for fg+bg color set to the same (#2749)
|
||||
0.35: Support 12-hour time format
|
||||
|
|
|
|||
|
|
@ -199,11 +199,9 @@ let drawTime = function() {
|
|||
let y = y1;
|
||||
let date = new Date();
|
||||
|
||||
let hours = String(date.getHours());
|
||||
let minutes = date.getMinutes();
|
||||
minutes = minutes < 10 ? String("0") + minutes : minutes;
|
||||
let colon = settings.hideColon ? "" : ":";
|
||||
let timeStr = hours + colon + minutes;
|
||||
var timeStr = locale.time(date, 1);
|
||||
if (settings.hideColon)
|
||||
timeStr = timeStr.replace(":", "");
|
||||
|
||||
// Set y coordinates correctly
|
||||
y += parseInt((H - y)/2) + 5;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "bwclklite",
|
||||
"name": "BW Clock Lite",
|
||||
"version": "0.34",
|
||||
"version": "0.35",
|
||||
"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",
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
"description": "Show the current and upcoming events synchronized from Gadgetbridge",
|
||||
"icon": "calclock.png",
|
||||
"type": "clock",
|
||||
"tags": "clock agenda",
|
||||
"tags": "clock,agenda",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
|
|
|
|||
|
|
@ -19,3 +19,4 @@
|
|||
Display Widgets in menus
|
||||
0.17: Load holidays before events so the latter is not overpainted
|
||||
0.18: Minor code improvements
|
||||
0.19: Read events synchronized from Gadgetbridge
|
||||
|
|
|
|||
|
|
@ -60,6 +60,12 @@ const loadEvents = () => {
|
|||
date.setSeconds(time.s);
|
||||
return {date: date, msg: a.msg, type: "e"};
|
||||
}));
|
||||
// all events synchronized from Gadgetbridge
|
||||
events = events.concat((require("Storage").readJSON("android.calendar.json",1) || []).map(a => {
|
||||
// timestamp is in seconds, Date requires milliseconds
|
||||
const date = new Date(a.timestamp * 1000);
|
||||
return {date: date, msg: a.title, type: "e"};
|
||||
}));
|
||||
};
|
||||
|
||||
const loadSettings = () => {
|
||||
|
|
@ -221,8 +227,8 @@ const drawCalendar = function(date) {
|
|||
}, []);
|
||||
let i = 0;
|
||||
g.setFont("8x12", fontSize);
|
||||
for (y = 0; y < rowN - 1; y++) {
|
||||
for (x = 0; x < colN; x++) {
|
||||
for (let y = 0; y < rowN - 1; y++) {
|
||||
for (let x = 0; x < colN; x++) {
|
||||
i++;
|
||||
const day = days[i];
|
||||
const curMonth = day < 15 ? month+1 : day < 50 ? month-1 : month;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "calendar",
|
||||
"name": "Calendar",
|
||||
"version": "0.18",
|
||||
"version": "0.19",
|
||||
"description": "Monthly calendar, displays holidays uploaded from the web interface and scheduled events.",
|
||||
"icon": "calendar.png",
|
||||
"screenshots": [{"url":"screenshot_calendar.png"}],
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.01: New app!
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
# Shortcuts
|
||||
|
||||
An app that allows you to create custom ClockInfos that act as shortcuts to your favourite apps.
|
||||
|
||||
## Create a Shortcut
|
||||
After installing the app, you can open the app to add and manage existing shortcuts. If no shortcuts exist, the app will display a ``[+] Shortcuts`` button as a ClockInfo on your Clock (see screenshots), which when clicked will quickly launch into the app so you can add new shortcuts.
|
||||
|
||||
When adding a shortcut, first select the app you wish to use, then select the icon you wish to register to the shortcut. If a keyboard is installed, you'll get the option to rename the shortcut before saving.
|
||||
|
||||
Once created, your shortcut will appear on any Clocks with ClockInfo support, and tapping the shortcut will launch the chosen app
|
||||
|
After Width: | Height: | Size: 471 B |
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEw4UB/4ACBIM889VAHmqAAwKCrQLH0oLCuBoFhoLCtJ1HtILBtYLH9ILBtALHlILQlRFCwALSnWwgECBY8O1gLJgeoBaojLHZfqAQILIFwMDBY8CFwMO2QLGhwuBlWuBY0K4ED1aDHBYJUBlQLGnRUChQLIKgJHHBYJUBZY8KgZUBBZHCKgILHh2CBZMC0fABZC+CBZBSBC5JUB14MDcY2q1YLIDAILGtY4EAAXpBYNpBY9pBYNauAKFhulBYWqAAwLCqoLHBQQA6A="))
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
var storage = require("Storage");
|
||||
var keyboard = "textinput";
|
||||
try {
|
||||
keyboard = require(keyboard);
|
||||
} catch (e) {
|
||||
keyboard = null;
|
||||
}
|
||||
|
||||
var icons = [
|
||||
{name:"agenda", img :"GBiBAAAAAAA8AAB+AA/n8B/n+BgAGBgAGBn/mBn/mBgAGBgAGBn/mBn/+BgD/BgHDhn+Bhn8MxgMIxgMIx/8Ew/+BgAHDgAD/AAA8A=="},
|
||||
{name:"alarm", img:"GBiBAAAAAAAAAAYAYA4AcBx+ODn/nAOBwAcA4A4YcAwYMBgYGBgYGBgYGBgYGBgeGBgHGAwBMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="},
|
||||
{name:"mail", img:"GBiBAAAAAAAAAAAAAAAAAB//+D///DAADDgAHDwAPDcA7DPDzDDnDDA8DDAYDDAADDAADDAADDAADD///B//+AAAAAAAAAAAAAAAAA=="},
|
||||
{name:"android", img: "GBiBAAAAAAEAgAD/AAD/AAHDgAGBgAMkwAMAwAP/wBv/2BsA2BsA2BsA2BsA2BsA2BsA2Bv/2AP/wADnAADnAADnAADnAADnAAAAAA=="},
|
||||
{name:"add", img:"GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgYGBgYGBgYGBgYGBn/mBn/mBgYGBgYGBgYGBgYGBgAGBgAGB//+A//8AAAAAAAAAAAAA=="},
|
||||
{name:"bangle", img:"GBiBAAD+AAH+AAH+AAH+AAH/AAOHAAYBgAwAwBgwYBgwYBgwIBAwOBAwOBgYIBgMYBgAYAwAwAYBgAOHAAH/AAH+AAH+AAH+AAD+AA=="},
|
||||
{name:"bike", img:"GBiBAAAAAAAAAAAAAAAD+AAD/AADjAABjAfhnAfjyAMDwAcGwB4O+H8M/GGZ5sD7c8fzM8fjM8DDA2GBhn8B/h4AeAAAAAAAAAAAAA=="},
|
||||
{name:"map", img:"GBiBAAAAAAAAAAAAAADgGAf8+B//+BjHGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjDGBjjGB//+B8/4BgHAAAAAAAAAAAAAA=="},
|
||||
{name:"play", img:"GBiBAAAAAAAAAAAAAA//8B//+BgAGBjAGBjwGBj8GBjeGBjHmBjB2BjB2BjHmBjeGBj8GBjwGBjAGBgAGB//+A//8AAAAAAAAAAAAA=="},
|
||||
{name:"fast forward", img:"GBiBAAAAAAAAAAAAAH///v///8AAA8YYA8eeA8f/g8b7w8Y488YYO8YYO8Y488b7w8f/g8eeA8YYA8AAA////3///gAAAAAAAAAAAA=="},
|
||||
{name:"rewind", img:"GBiBAAAAAAAAAAAAAH///v///8AAA8AYY8B548H/48PfY88cY9wYY9wYY88cY8PfY8H/48B548AYY8AAA////3///gAAAAAAAAAAAA=="},
|
||||
{name:"timer", img:"GBiBAAAAAAB+AAB+AAAAMAB+OAH/nAOByAcA4A4YcAwYMBgYGBgYGBgYGBgYGBgAGBgAGAwAMA4AcAcA4AOBwAH/gAB+AAAAAAAAAA=="},
|
||||
{name:"connected", img:"GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBngGBn4GBgcGBgOGBnHGBnzGBgxmBgZmBmZmBmZmBgAGBgAGB//+A//8AAAAAAAAAAAAA=="},
|
||||
{name:"lock", img:"GBiBAAAAAAA8AAD/AAHDgAGBgAMAwAMAwAMAwAf/4A//8AwAMAwAMAwAMAwYMAw8MAw8MAwYMAwAMAwAMAwAMA//8Af/4AAAAAAAAA=="},
|
||||
{name:"battery", img:"GBiBAAAAAAAAAAB+AAB+AAHngAPnwAMAwAMAwAMIwAMIwAMYwAM4wAM+wAN8wAMcwAMYwAMQwAMQwAMAwAMAwAP/wAH/gAAAAAAAAA=="},
|
||||
{name:"game", img:"GBiBAAAAAAAAAAAAAAA8AAB+AABmAABmAAB+AAA8AAAYAAAYAAAYAAMYAA//8B//+BgAGBgAGBgAGBgAGB//+A//8AAAAAAAAAAAAA=="},
|
||||
{name:"dice", img:"GBiBAAAAAB//8D//+HAAPGMDHmeHnmeHnmMDHmAAHmMDHmeHnmeHnmMDHmAAHmMDHmeHnmeHnmMDHnAAPn///j///h///g///AAAAA=="},
|
||||
{name:"gear", img:"GBiBAAAAAAAAAAA8AAB+AABmAA3nsA/D8B8A+Dg8HBx+OAznMAzDMAzDMAznMBx+ODg8HB8A+A/D8A3nsABmAAB+AAA8AAAAAAAAAA=="},
|
||||
{name:"wrench", img:"GBiBAAAAAAAAAAAAAAAHgAAfwAA7gAAzEABjOABj+ABh+ABgGADgMAHAcAOP4AcfgA44AB9wADHgADHAADGAAB8AAA4AAAAAAAAAAA=="},
|
||||
{name:"calendar", img:"FhgBDADAMAMP/////////////////////8AADwAAPAAA8AADwAAPAAA8AADwAAPAAA8AADwAAPAAA8AADwAAP///////"},
|
||||
{name:"power", img:"GBiBAAAAAAAAAAB+AAH/gAeBwA4YcAwYMBjbGBnbmDGZjDMYzDMYzDMAzDMAzDGBjBnDmBj/GAw8MA4AcAeB4AH/gAB+AAAAAAAAAA=="},
|
||||
{name:"terminal", img:"GBiBAAAAAAAAAAAAAA//8B//+B//+B//+B//+BgAGBgAGBgAGBmAGBjAGBhgGBhgGBjAGBmPmBgAGBgAGB//+A//8AAAAAAAAAAAAA=="},
|
||||
{name:"camera", img:"GBiBAAAAAAAAAAD/AAH/gAMAwD8A/H8A/mA8BmD/BmHDhmGBhmMAxmMAxmMAxmMAxmGBhmHDhmD/BmA8BmAABn///j///AAAAAAAAA=="},
|
||||
{name:"phone", img:"GBiBAAAAAAAAAAOAAA/AABzgADBgADBgADBgABjgABjAABzAAAxgAA5wAAc58AMf+AGHHADgDABwDAA8GAAfGAAH8AAA4AAAAAAAAA=="},
|
||||
{name:"two prong plug", img:"GBiBAAABgAADwAAHwAAPgACfAAHOAAPkBgHwDwP4Hwf8Pg/+fB//OD//kD//wD//4D//8D//4B//QB/+AD/8AH/4APnwAHAAACAAAA=="},
|
||||
{name:"steps", img:"GBiBAAcAAA+AAA/AAA/AAB/AAB/gAA/g4A/h8A/j8A/D8A/D+AfH+AAH8AHn8APj8APj8AHj4AHg4AADAAAHwAAHwAAHgAAHgAADAA=="},
|
||||
{name:"graph", img:"GBiBAAAAAAAAAAAAAAAAAAAAAADAAADAAAHAAAHjAAHjgAPngH9n/n82/gA+AAA8AAA8AAAcAAAYAAAYAAAAAAAAAAAAAAAAAAAAAA=="},
|
||||
{name:"hills", img:"GBiBAAAAAAAAAAAAAAAAAAAAAAACAAAGAAAPAAEZgAOwwAPwQAZgYAwAMBgAGBAACDAADGAABv///////wAAAAAAAAAAAAAAAAAAAA=="},
|
||||
{name:"sun", img:"GBiBAAAYAAAYAAAYAAgAEBwAOAx+MAD/AAHDgAMAwAcA4AYAYOYAZ+YAZwYAYAcA4AMAwAHDgAD/AAx+MBwAOAgAEAAYAAAYAAAYAA=="},
|
||||
{name:"home", img:"GBiBAAAAAAAAAAAAAAH/gAP/wAdg4A5wYA44MBwf+DgP/BgAGBgAGBgAGBnnmBnnmBnnmBnnmBngGBngGB//+B//+AAAAAAAAAAAAA=="},
|
||||
{name:"bell", img:"GBiBAAAAAAAAAAAfgAB/2ADw+AHAMAOAGAcAGD4ADHgADDgADBwADA4AHAcAGAOAOAHAcAPg4ANxwAM5gAP/AAHvAAAHAAACAAAAAA=="},
|
||||
{name:"bin", img:"GBiBAAAAAAAAAAB+AB//+B//+AwAMAwAMAxmMAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYANmwAMAwAMAwAP/wAH/gAAAAAAAAA=="},
|
||||
];
|
||||
|
||||
let storedApps;
|
||||
var showMainMenu = () => {
|
||||
storedApps = storage.readJSON("clkshortcuts.json", 1) || {};
|
||||
|
||||
var mainMenu = {
|
||||
"": {
|
||||
title: "Shortcuts",
|
||||
},
|
||||
"< Back": () => {
|
||||
load();
|
||||
},
|
||||
"New": () => {
|
||||
// Select the app
|
||||
getSelectedApp().then((app) => {
|
||||
getSelectedIcon().then((icon) => {
|
||||
promptForRename(app.name).then((name) => {
|
||||
E.showMessage("Saving...");
|
||||
storedApps[app.src] = {
|
||||
name: name, src: app.src, icon: icon
|
||||
};
|
||||
storage.writeJSON("clkshortcuts.json", storedApps);
|
||||
showMainMenu();
|
||||
}).catch(() => {
|
||||
E.showMessage("Saving...");
|
||||
storedApps[app.src] = {
|
||||
name: app.name, src: app.src, icon: icon
|
||||
};
|
||||
storage.writeJSON("clkshortcuts.json", storedApps);
|
||||
showMainMenu();
|
||||
} );
|
||||
}).catch(() => {showMainMenu();});
|
||||
}).catch(() => {showMainMenu();});
|
||||
},
|
||||
};
|
||||
getStoredAppsArray(storedApps).forEach((app) => {
|
||||
mainMenu[app.name] = {
|
||||
onchange: () => {
|
||||
showEditMenu(app).then((dirty) => {
|
||||
if (dirty) {
|
||||
E.showMessage("Saving...");
|
||||
storage.writeJSON("clkshortcuts.json", storedApps);
|
||||
}
|
||||
showMainMenu();
|
||||
});
|
||||
},
|
||||
format: v=>"\0" + atob(app.icon)
|
||||
};
|
||||
});
|
||||
E.showMenu(mainMenu);
|
||||
};
|
||||
|
||||
var showEditMenu = (app) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
var editMenu = {
|
||||
"": {
|
||||
title: "Edit " + app.name,
|
||||
},
|
||||
"< Back": () => {
|
||||
resolve(false);
|
||||
},
|
||||
"Name":{
|
||||
onchange: () => {
|
||||
promptForRename(app.name).then((name) => {
|
||||
storedApps[app.src].name = name;
|
||||
resolve(true);
|
||||
}).catch();
|
||||
},
|
||||
format: v=>app.name.substring(0, 7)
|
||||
},
|
||||
"Icon": {
|
||||
onchange: () => {
|
||||
getSelectedIcon().then((icon) => {
|
||||
storedApps[app.src].icon = icon;
|
||||
resolve(true);
|
||||
}).catch(() => resolve(false));
|
||||
},
|
||||
format: v=>"\0" + atob(app.icon)
|
||||
},
|
||||
"Delete": {
|
||||
onchange: () => {
|
||||
delete storedApps[app.src]
|
||||
resolve(true);
|
||||
},
|
||||
format: v=>"\0" + atob("GBiBAAAAAAAAAAB+AB//+B//+AwAMAwAMAxmMAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYAZmYANmwAMAwAMAwAP/wAH/gAAAAAAAAA==")
|
||||
}
|
||||
};
|
||||
E.showMenu(editMenu);
|
||||
});
|
||||
};
|
||||
|
||||
var promptForRename = (name) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (!keyboard) { reject("No textinput is available"); }
|
||||
else {
|
||||
return require("textinput").input({text:name}).then((result) => resolve(result));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
var getStoredAppsArray = (apps) => {
|
||||
var appList = Object.keys(apps);
|
||||
var storedAppArray = [];
|
||||
for (var i = 0; i < appList.length; i++) {
|
||||
var app = "" + appList[i];
|
||||
storedAppArray.push(
|
||||
apps[app]
|
||||
);
|
||||
}
|
||||
return storedAppArray;
|
||||
};
|
||||
|
||||
var getSelectedIcon = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
var iconMenu = {
|
||||
"": {
|
||||
title: "Select Icon",
|
||||
},
|
||||
"< Back": () => {
|
||||
reject("The user cancelled the operation");
|
||||
},
|
||||
};
|
||||
|
||||
icons.forEach((icon) => {
|
||||
iconMenu["\0" + atob(icon.img) + " " + icon.name] = () => {
|
||||
resolve(icon.img);
|
||||
};
|
||||
});
|
||||
|
||||
E.showMenu(iconMenu);
|
||||
});
|
||||
};
|
||||
|
||||
var getAppList = () => {
|
||||
var appList = storage
|
||||
.list(/\.info$/)
|
||||
.map((appInfoFileName) => {
|
||||
var appInfo = storage.readJSON(appInfoFileName, 1);
|
||||
return (
|
||||
appInfo && {
|
||||
name: appInfo.name,
|
||||
sortorder: appInfo.sortorder,
|
||||
src: appInfo.src,
|
||||
}
|
||||
);
|
||||
})
|
||||
.filter((app) => app && !!app.src);
|
||||
appList.sort((a, b) => {
|
||||
var n = (0 | a.sortorder) - (0 | b.sortorder);
|
||||
if (n) return n;
|
||||
if (a.name < b.name) return -1;
|
||||
if (a.name > b.name) return 1;
|
||||
return 0;
|
||||
});
|
||||
|
||||
return appList;
|
||||
};
|
||||
|
||||
var getSelectedApp = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
E.showMessage("Loading apps...");
|
||||
var selectAppMenu = {
|
||||
"": {
|
||||
title: "Select App",
|
||||
},
|
||||
"< Back": () => {
|
||||
reject("The user cancelled the operation");
|
||||
},
|
||||
};
|
||||
|
||||
var appList = getAppList();
|
||||
appList.forEach((app) => {
|
||||
selectAppMenu[app.name] = () => {
|
||||
resolve(app);
|
||||
};
|
||||
});
|
||||
|
||||
E.showMenu(selectAppMenu);
|
||||
});
|
||||
};
|
||||
|
||||
showMainMenu();
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
|
|
@ -0,0 +1,45 @@
|
|||
(function() {
|
||||
var storage = require("Storage");
|
||||
var storedApps = storage.readJSON("clkshortcuts.json", 1) || {};
|
||||
var items = [];
|
||||
if (Object.keys(storedApps).length !== 0) {
|
||||
for (var key in storedApps) {
|
||||
var source = {
|
||||
name: storedApps[key].name,
|
||||
img: storedApps[key].icon,
|
||||
src: storedApps[key].src,
|
||||
get : function() {
|
||||
return {
|
||||
text : this.name,
|
||||
img : atob(this.img)
|
||||
}
|
||||
},
|
||||
run: function() { load(this.src);},
|
||||
show : function() {},
|
||||
hide : function() {},
|
||||
}
|
||||
items.push(source);
|
||||
}
|
||||
}
|
||||
else {
|
||||
var source = {
|
||||
name: "Shortcuts",
|
||||
img: "GBiBAAAAAAAAAAAAAA//8B//+BgAGBgAGBgYGBgYGBgYGBgYGBn/mBn/mBgYGBgYGBgYGBgYGBgAGBgAGB//+A//8AAAAAAAAAAAAA==",
|
||||
src: "clkshortcuts.app.js",
|
||||
get : function() {
|
||||
return {
|
||||
text : this.name,
|
||||
img : atob(this.img)
|
||||
}
|
||||
},
|
||||
run: function() { load(this.src);},
|
||||
show : function() {},
|
||||
hide : function() {},
|
||||
};
|
||||
items = [source];
|
||||
}
|
||||
return {
|
||||
name: "Shortcuts",
|
||||
items: items
|
||||
};
|
||||
})
|
||||
|
After Width: | Height: | Size: 622 B |
|
|
@ -0,0 +1,17 @@
|
|||
{ "id": "clkshortcuts",
|
||||
"name": "Shortcuts",
|
||||
"shortName": "Shortcuts",
|
||||
"version": "0.01",
|
||||
"description": "Add shortcuts to launch your favourite apps straight from the Clock",
|
||||
"icon": "app.png",
|
||||
"screenshots": [{"url":"add_shortcuts_screenshot.png"}, {"url":"example_shortcuts_screenshot.png"}],
|
||||
"tags": "clkinfo,clockinfo",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{ "name": "clkshortcuts.app.js", "url": "app.js" },
|
||||
{ "name": "clkshortcuts.img", "url": "app-icon.js", "evaluate": true },
|
||||
{"name":"clkshortcuts.clkinfo.js","url":"clkinfo.js"}
|
||||
],
|
||||
"data": [{"name":"clkshortcuts.json"}]
|
||||
}
|
||||
|
|
@ -13,3 +13,4 @@
|
|||
0.12: Add drawFilledImage to allow drawing icons with a separately coloured middle
|
||||
0.13: Cache loaded ClockInfos so if we have clockInfoWidget and a clock, we don't load them twice (saves ~300ms)
|
||||
0.14: Check for .clkinfocache and use that if exists (from boot 0.64)
|
||||
0.15: Fix error when displaying a category with only one clockinfo (fix #3728)
|
||||
|
|
|
|||
|
|
@ -283,7 +283,7 @@ exports.addInteractive = function(menu, options) {
|
|||
//in the worst case we come back to 0
|
||||
} while(menu[options.menuA].items.length==0);
|
||||
// When we change, ensure we don't display the same thing as another clockinfo if we can avoid it
|
||||
while ((options.menuB < menu[options.menuA].items.length) &&
|
||||
while ((options.menuB < menu[options.menuA].items.length-1) &&
|
||||
exports.clockInfos.some(m => (m!=options) && m.menuA==options.menuA && m.menuB==options.menuB))
|
||||
options.menuB++;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{ "id": "clock_info",
|
||||
"name": "Clock Info Module",
|
||||
"shortName": "Clock Info",
|
||||
"version":"0.14",
|
||||
"version":"0.15",
|
||||
"description": "A library used by clocks to provide extra information on the clock face (Altitude, BPM, etc)",
|
||||
"icon": "app.png",
|
||||
"type": "module",
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"version": "0.03",
|
||||
"description": "Displays RGB565 and RGB888 colors, its name and code in screen.",
|
||||
"icon": "app.png",
|
||||
"tags": "Color,input,buttons,touch,UI",
|
||||
"tags": "color,input,buttons,touch,ui",
|
||||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
|
|
|
|||
|
|
@ -0,0 +1,6 @@
|
|||
0.01: New App!
|
||||
0.02: update to my current preferences.
|
||||
0.03: update app list
|
||||
0.04: change app name "mysetup" -> "anotherconf"
|
||||
0.05: remove apps that are not "core" to the experience.
|
||||
0.06: change name "anotherconf" -> "confthyttan"
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
# Thyttan's Default Config
|
||||
|
||||
A different default set of apps and configurations. Brings many quality of life improvements. Opinionated based on the creators taste. Read more below before installing.
|
||||
|
||||
## Usage
|
||||
|
||||
Before installing do this:
|
||||
|
||||
1. Backup your current setup (via the "More..." tab of the App Loader) so you can restore it later if you want.
|
||||
2. Install this app (you'll be prompted about all data being removed from your Bangle)
|
||||
3. Try it out, switch out apps to your favorites and tweak to your liking!
|
||||
|
||||
## Features
|
||||
|
||||
There will not be a trace of a "Thyttan's Default Config" app on your watch after installation. Only the apps it installed and the configurations.
|
||||
|
||||
On the clock face:
|
||||
- Swipe right on the screen to open the launcher (Desktop Launcher) - or press the hardware button.
|
||||
- Swipe left to open a flashlight app.
|
||||
- Swipe up to open the messages.
|
||||
- Swipe down for quick access to music and podcast controls.
|
||||
- (Do a subsequent left or right swipe to enter the listed apps)
|
||||
- (Check out the "Quick Launch" app readme for more info)
|
||||
|
||||
## Requests
|
||||
|
||||
Add to the espruino/BangleApps issue tracker and mention @thyttan for bug reports and suggestions.
|
||||
|
||||
## Creator
|
||||
|
||||
thyttan
|
||||
|
After Width: | Height: | Size: 1.7 KiB |
|
|
@ -0,0 +1 @@
|
|||
{"mode":0,"apps":[{"name":"Run+","src":"runplus.app.js","files":"runplus.info,runplus.app.js,runplus.img,runplus.settings.js,runplus_karvonen"}],"timeout":10}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"mode":0,"apps":[{"name":"Calculator","src":"calculator.app.js"},{"name":"SleepLog","src":"sleeplog.app.js"},{"name":"Messages","sortorder":-9,"src":"messagegui.app.js"},{"name":"Messages","sortorder":-9,"src":"messagegui.app.js","files":"messagegui.info,messagegui,messagegui.app.js,messagegui.new.js,messagegui.boot.js,messagegui.img"}],"standardNumSwipeHandlers":5,"standardNumDragHandlers":1}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"showClocks":true,"showLaunchers":true,"direct":false,"swipeExit":false,"timeOut":"15s"}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"buzzOnCharge":true,"monthFirst":true,"twentyFourH":true,"showAmPm":false,"showSeconds":true,"showWeather":false,"stepGoal":10000,"stepBar":true,"weekBar":true,"mondayFirst":true,"dayBar":true,"redrawOnStep":false}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{useAppHistory:true,disregardQuicklaunch:true,hideLoading:true}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{"colors":"011","image":"heart","touchOn":"always","oversize":7,"dragDelay":500,"minValue":0.01,"tapToLock":false,"unlockSide":"","tapSide":"","tapOn":"always","tOut":2000,"minFlash":0.2,"isOn":true,"value":0.9109}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{vibrateTimeout:10,vibrate:":",vibrateCalls:":::",flash:false}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
{ "id": "confthyttan",
|
||||
"name": "Thyttan's Default Config",
|
||||
"version":"0.06",
|
||||
"description": "A different default set of apps and configurations. Brings many quality of life improvements. Opinionated based on the creators taste. Read more below before installing.",
|
||||
"icon": "app.png",
|
||||
"type": "defaultconfig",
|
||||
"tags": "system,configuration,config,anotherconfig,thyttan",
|
||||
"supports" : ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"dependencies" : {
|
||||
"sched":"app",
|
||||
"kbmulti":"app",
|
||||
"messageicons":"app",
|
||||
"widmsggrid":"app",
|
||||
"msgwakefup":"app",
|
||||
"delaylock":"app",
|
||||
"notify":"app",
|
||||
"health":"app",
|
||||
"widminbate":"app",
|
||||
"podadrem":"app",
|
||||
"spotrem":"app",
|
||||
"android":"app",
|
||||
"widanclk":"app",
|
||||
"backswipe":"app",
|
||||
"torch":"app",
|
||||
"calculator":"app",
|
||||
"widbt_notify":"app",
|
||||
"smpltmr":"app",
|
||||
"clkinfostopw":"app",
|
||||
"runplus":"app",
|
||||
"dtlaunch":"app",
|
||||
"quicklaunch":"app",
|
||||
"kineticscroll":"app",
|
||||
"alarm":"app",
|
||||
"recorder":"app",
|
||||
"agenda":"app",
|
||||
"edgeclk":"app",
|
||||
"autoreset":"app",
|
||||
"chargent":"app",
|
||||
"setting":"app",
|
||||
"fastload":"app",
|
||||
"boot":"app",
|
||||
"ateatimer":"app",
|
||||
"drained":"app"
|
||||
},
|
||||
"storage": [
|
||||
{"name":"backswipe.json",
|
||||
"url":"backswipe.json"},
|
||||
{"name":"autoreset.json",
|
||||
"url":"autoreset.json"},
|
||||
{"name":"dtlaunch.json",
|
||||
"url":"dtlaunch.json"},
|
||||
{"name":"fastload.json",
|
||||
"url":"fastload.json"},
|
||||
{"name":"quicklaunch.json",
|
||||
"url":"quicklaunch.json"},
|
||||
{"name":"messages.settings.json",
|
||||
"url":"messages.settings.json"},
|
||||
{"name":"widbt_notify.json",
|
||||
"url":"widbt_notify.json"},
|
||||
{"name":"recorder.json",
|
||||
"url":"recorder.json"},
|
||||
{"name":"edgeclk.settings.json",
|
||||
"url":"edgeclk.settings.json"},
|
||||
{"name":"setting.json",
|
||||
"url":"setting.json"}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{lapp:{name:"Show Launcher",sortorder:-12,src:"no source"},rapp:{name:"torch",type:"app",sortorder:-11,src:"torch.app.js"},uapp:{name:"Messages",sortorder:-9,src:"messagegui.app.js"},dapp:{name:"Extension",type:"app",sortorder:-11,src:"quicklaunch.app.js"},tapp:{name:""},dlapp:{name:"PA Remote",src:"podadrem.app.js"},drapp:{name:"Remote for Spotify",src:"spotrem.app.js"},duapp:{name:""},ddapp:{name:"Extension",type:"app",sortorder:-11,src:"quicklaunch.app.js"},dtapp:{name:""},ddlapp:{name:"Alarms",src:"alarm.app.js"},ddrapp:{name:"Run+",src:"runplus.app.js"},dduapp:{name:""},dddapp:{name:"Agenda",src:"agenda.app.js"},ddtapp:{name:""},rlapp:{name:""},rrapp:{name:""},ruapp:{name:""},rdapp:{name:""},rtapp:{name:""},trace:"dr"}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{recording:false,period:10,record:["gps","hrm","steps"],file:"recorder.log0.csv"}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{ble:true,blerepl:true,log:false,quiet:0,timeout:10,vibrate:true,beep:true,timezone:2,HID:false,clock:"edgeclk.app.js","12hour":false,firstDayOfWeek:1,brightness:0.5,options:{wakeOnBTN1:true,wakeOnBTN2:true,wakeOnBTN3:true,wakeOnFaceUp:false,wakeOnTouch:false,wakeOnTwist:false,twistThreshold:819.2,twistMaxY:-800,twistTimeout:1000,btnLoadTimeout:700},theme:{fg:65535,bg:0,fg2:65535,bg2:8,fgH:65535,bgH:31,dark:true},clockHasWidgets:true,launcher:"dtlaunch.app.js",touch:{x1:6,y1:14,x2:197,y2:178}}
|
||||
|
|
@ -0,0 +1 @@
|
|||
{showWidget:true,buzzOnConnect:false,buzzOnLoss:false,hideConnected:false,showMessage:false,nextBuzz:30000}
|
||||
|
|
@ -2,3 +2,4 @@
|
|||
0.02: Added Settings & readme
|
||||
0.03: Fix lint warnings
|
||||
0.04: Fix lint warnings
|
||||
0.05: Fix on not reading counter defaults in Settings
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"id": "counter2",
|
||||
"name": "Counter2",
|
||||
"version": "0.04",
|
||||
"version": "0.05",
|
||||
"description": "Dual Counter",
|
||||
"readme":"README.md",
|
||||
"icon": "counter2-icon.png",
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
"": { "title": "Counter2" },
|
||||
"< Back": () => back(),
|
||||
'Default C1': {
|
||||
value: settings[0],
|
||||
value: settings.max0,
|
||||
min: -99, max: 99,
|
||||
onchange: v => {
|
||||
settings.max0 = v;
|
||||
|
|
@ -26,7 +26,7 @@
|
|||
}
|
||||
},
|
||||
'Default C2': {
|
||||
value: settings[2],
|
||||
value: settings.max1,
|
||||
min: -99, max: 99,
|
||||
onchange: v => {
|
||||
settings.max1 = v;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
|
||||
/* eslint-env node */
|
||||
|
||||
var imageconverter = require("../../../webtools/imageconverter.js").imageconverter;
|
||||
var imageconverter = require("../../../webtools/imageconverter.js");
|
||||
var icons = JSON.parse(require("fs").readFileSync(__dirname+"/icon_names.json"));
|
||||
const imgOptions = {
|
||||
mode : "1bit",
|
||||
|
|
|
|||
|
|
@ -261,7 +261,7 @@ var locales = {
|
|||
ampm: { 0: "am", 1: "pm" },
|
||||
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
||||
datePattern: { 0: "%d %B %Y", "1": "%d/%m/%Y" }, // 1 mars 2020 // 01/03/2020
|
||||
abmonth: "janv,févr,mars,avril,mai,juin,juil,août,sept,oct,nov,déc",
|
||||
abmonth: "janv,févr,mars,avr,mai,juin,juil,août,sept,oct,nov,déc",
|
||||
month: "janvier,février,mars,avril,mai,juin,juillet,août,septembre,octobre,novembre,décembre",
|
||||
abday: "dim,lun,mar,mer,jeu,ven,sam",
|
||||
day: "dimanche,lundi,mardi,mercredi,jeudi,vendredi,samedi",
|
||||
|
|
@ -423,7 +423,7 @@ var locales = {
|
|||
ampm: { 0: "am", 1: "pm" },
|
||||
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
||||
datePattern: { 0: "%A %B %d %Y", "1": "%d/%m/%y" }, // dimanche 1 mars 2020 // 01/03/20
|
||||
abmonth: "janv.,févr.,mars,avril,mai,juin,juil.,août,sept.,oct.,nov.,déc.",
|
||||
abmonth: "janv,févr,mars,avr,mai,juin,juil,août,sept,oct,nov,déc",
|
||||
month: "janvier,février,mars,avril,mai,juin,juillet,août,septembre,octobre,novembre,décembre",
|
||||
abday: "dim,lun,mar,mer,jeu,ven,sam",
|
||||
day: "dimanche,lundi,mardi,mercredi,jeudi,vendredi,samedi",
|
||||
|
|
@ -471,7 +471,7 @@ var locales = {
|
|||
ampm: { 0: "AM", 1: "PM" },
|
||||
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
||||
datePattern: { 0: "%A %d %B %Y", "1": "%d/%m/%y" }, // dimanche 1 mars 2020 // 01/03/20
|
||||
abmonth: "janv.,févr.,mars,avril,mai,juin,juil.,août,sept.,oct.,nov.,déc.",
|
||||
abmonth: "janv,févr,mars,avr,mai,juin,juil,août,sept,oct,nov,déc",
|
||||
month: "janvier,février,mars,avril,mai,juin,juillet,août,septembre,octobre,novembre,décembre",
|
||||
abday: "dim,lun,mar,mer,jeu,ven,sam",
|
||||
day: "dimanche,lundi,mardi,mercredi,jeudi,vendredi,samedi",
|
||||
|
|
@ -567,7 +567,7 @@ var locales = {
|
|||
ampm: { 0: "am", 1: "pm" },
|
||||
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
||||
datePattern: { 0: "%A %d %B de %Y", "1": "%d/%m/%Y" }, // dimenge 1 de març de 2020 // 01/03/2020
|
||||
abmonth: "gen.,febr.,març,abril,mai,junh,julh,ago.,set.,oct.,nov.,dec.",
|
||||
abmonth: "gen,febr,març,abril,mai,junh,julh,ago,set,oct,nov,dec",
|
||||
month: "genièr,febrièr,març,abril,mai,junh,julhet,agost,setembre,octòbre,novembre,decembre",
|
||||
abday: "dg,dl,dm,dc,dj,dv,ds",
|
||||
day: "dimenge,diluns,dimars,dimècres,dijòus,divendres,dissabte",
|
||||
|
|
@ -612,10 +612,10 @@ var locales = {
|
|||
speed: "km/h",
|
||||
distance: { 0: "m", 1: "km" },
|
||||
temperature: "°C",
|
||||
ampm: { 0: "dop.", 1: "pop." },
|
||||
ampm: { 0: "dop", 1: "pop" },
|
||||
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
||||
datePattern: { 0: "%-d. %b %Y", 1: "%-d.%-m.%Y" }, // "3. jan. 2020" // "3.1.2020"(short)
|
||||
abmonth: "sij.,velj.,ožu.,tra.,svi,lip.,srp.,kol.,ruj.,lis.,stu.,pro.",
|
||||
abmonth: "sij,velj,ožu,tra,svi,lip,srp,kol,ruj,lis,stu,pro",
|
||||
month: "siječanj,veljača,ožujak,travanj,svibanj,lipanj,srpanj,kolovoz,rujan,listopad,studeni,prosinac",
|
||||
abday: "ned.,pon.,uto.,sri.,čet.,pet.,sub.",
|
||||
day: "nedjelja,ponedjeljak,utorak,srijeda,četvrtak,petak,subota",
|
||||
|
|
@ -628,7 +628,7 @@ var locales = {
|
|||
speed: "km/h",
|
||||
distance: { 0: "m", 1: "km" },
|
||||
temperature: "°C",
|
||||
ampm: { 0: "dop.", 1: "pop." },
|
||||
ampm: { 0: "dop", 1: "pop" },
|
||||
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
||||
datePattern: { 0: "%-d. %b %Y", 1: "%-d.%-m.%Y" }, // "3. jan. 2020" // "3.1.2020"(short)
|
||||
abmonth: "jan.,feb.,mar.,apr.,maj,jun.,jul.,avg.,sep.,okt.,nov.,dec.",
|
||||
|
|
@ -728,7 +728,7 @@ var locales = {
|
|||
ampm: { 0: "am", 1: "pm" },
|
||||
timePattern: { 0: "%HH:%MM:%SS", 1: "%HH:%MM" },
|
||||
datePattern: { 0: "%d %B %Y", "1": "%d/%m/%y" },
|
||||
abmonth: "gen.,febr.,març,abr.,maig,juny,jul.,ag.,set.,oct.,nov.,des.",
|
||||
abmonth: "gen,febr,març,abr,maig,juny,jul,ag,set,oct,nov,des",
|
||||
month: "gener,febrer,març,abril,maig,juny,juliol,agost,setembre,octubre,novembre,desembre",
|
||||
abday: "dg.,dl.,dt.,dc.,dj.,dv.,ds.",
|
||||
day: "diumenge,dilluns,dimarts,dimecres,dijous,divendres,dissabte",
|
||||
|
|
|
|||
|
|
@ -15,6 +15,6 @@
|
|||
{"name":"messagesoverlay.settings.js","url":"settings.js"},
|
||||
{"name":"messagesoverlay.default.json","url":"default.json"}
|
||||
],
|
||||
"data": [{"name":"bthrm.json"}],
|
||||
"data":[{"name":"messagesoverlay.json"}],
|
||||
"screenshots": [{"url":"screen_call.png"} ,{"url":"screen_message.png"} ]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,3 +30,8 @@
|
|||
1.28: increased vibration strength, added some comments, & some QOL
|
||||
1.29: changed image
|
||||
1.30: changed image, again
|
||||
1.40: added various settings for controlling when & how to throw dice
|
||||
1.41: fixed dumb mistake
|
||||
1.42: okay maby I should've read the *whole* error log
|
||||
1.43: playing whackamole with ESLint
|
||||
1.44: fixed (?) settings app
|
||||
|
|
|
|||
|
|
@ -1,12 +1,20 @@
|
|||
var menu = true; // default to have the selection menu open
|
||||
var settings = Object.assign({
|
||||
vibrate: true,
|
||||
shake: true,
|
||||
screen: false,
|
||||
shake_timeout: 200,
|
||||
shake_duration: 100,
|
||||
}, require('Storage').readJSON("multidice.json", true) || {});
|
||||
|
||||
var menu = true; // defaults to having the menu open
|
||||
const DICE_ARRAY = [0, 4, 6, 8, 10, 12, 20, 100]; // 0 means nothing selected
|
||||
const SELECTION_ARRAY = [6, 0, 0, 0, 0, 0, 0, 0]; // default to selecting a single d20
|
||||
|
||||
// function to draw the selection menu
|
||||
function drawMenu() {
|
||||
|
||||
stringArr = new Array ("", "", "", "", "", "", "", "");
|
||||
for (i = 0; i < 8; i++) {
|
||||
var stringArr = new Array ("", "", "", "", "", "", "", "");
|
||||
for (var i = 0; i < 8; i++) {
|
||||
|
||||
if (SELECTION_ARRAY [i] != 0) {
|
||||
|
||||
|
|
@ -41,6 +49,7 @@ function touchHandler (button, xy) {
|
|||
return;
|
||||
}
|
||||
|
||||
var selection;
|
||||
if (xy.x <= 87) { // left
|
||||
|
||||
if (xy.y <= 43) { // first
|
||||
|
|
@ -84,15 +93,30 @@ function touchHandler (button, xy) {
|
|||
drawMenu();
|
||||
}
|
||||
|
||||
var shaken = false;
|
||||
var last_shaken = null;
|
||||
function accelHandler (xyz) {
|
||||
|
||||
// if the screen should be on *and* it isn't, return
|
||||
if (settings.screen && ! Bangle.isBacklightOn()) {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (xyz.diff >= 0.3) {
|
||||
|
||||
menu = false;
|
||||
mutex (rollDice).catch (() => {
|
||||
shaken = true;
|
||||
last_shaken = Date.now();
|
||||
} else if (shaken && last_shaken !== null) {
|
||||
|
||||
return; // not necessary, but prevents spamming the logs
|
||||
});
|
||||
if (Date.now() - last_shaken > settings.shake_timeout) {
|
||||
|
||||
last_shaken = null;
|
||||
shaken = false;
|
||||
menu = false;
|
||||
|
||||
mutex (rollDice).catch (() => { return; });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -123,8 +147,8 @@ function mutex (functionRef) {
|
|||
// function to roll all selected dice, and display them
|
||||
function rollDice() {
|
||||
|
||||
resultsArr = new Uint8Array (8);
|
||||
for (i = 0; i < 8; i++) {
|
||||
var resultsArr = new Uint8Array (8);
|
||||
for (var i = 0; i < 8; i++) {
|
||||
|
||||
if (SELECTION_ARRAY [i] != 0) {
|
||||
|
||||
|
|
@ -135,7 +159,7 @@ function rollDice() {
|
|||
g.clear();
|
||||
g.setFont ("Vector", 40);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (var i = 0; i < 4; i++) {
|
||||
|
||||
if (SELECTION_ARRAY [i] != 0) {
|
||||
|
||||
|
|
@ -143,7 +167,7 @@ function rollDice() {
|
|||
}
|
||||
}
|
||||
|
||||
for (i = 4; i < 8; i++) {
|
||||
for (var i = 4; i < 8; i++) {
|
||||
|
||||
if (SELECTION_ARRAY [i] != 0) {
|
||||
|
||||
|
|
@ -157,14 +181,19 @@ function rollDice() {
|
|||
// triggers the vibration, then pauses before returning
|
||||
function vibrate() {
|
||||
|
||||
if (! settings.vibrate) {
|
||||
|
||||
return (Promise.resolve (0));
|
||||
}
|
||||
|
||||
return new Promise ((resolve, reject) => {
|
||||
|
||||
return Bangle.buzz (50, 1).then ((value) => {
|
||||
return Bangle.buzz (settings.shake_duration, 1).then ((value) => {
|
||||
|
||||
setTimeout (() => {
|
||||
|
||||
resolve (value);
|
||||
}, 200);
|
||||
}, 2 * settings.shake_duration + settings.shake_timeout);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -177,7 +206,7 @@ function random (max) {
|
|||
|
||||
drawMenu();
|
||||
Bangle.on ('touch', touchHandler);
|
||||
Bangle.on ('accel', accelHandler);
|
||||
if (settings.shake) { Bangle.on ('accel', accelHandler); }
|
||||
setWatch (function() {
|
||||
|
||||
menu = false;
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
{ "id": "multidice",
|
||||
"name": "multiple dice roller",
|
||||
"shortName":"multidice",
|
||||
"version":"1.30",
|
||||
"version":"1.44",
|
||||
"description": "roll anywhere from 1-8 dice at the same time",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,game",
|
||||
|
|
@ -10,6 +10,8 @@
|
|||
"allow_emulator": true,
|
||||
"storage": [
|
||||
{"name":"multidice.app.js","url":"app.js"},
|
||||
{"name":"multidice.settings.js","url":"settings.js"},
|
||||
{"name":"multidice.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
],
|
||||
"data": [{"name": "multidice.json"}]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
(function(back) {
|
||||
var settings = Object.assign({
|
||||
vibrate: true,
|
||||
shake: true,
|
||||
screen: false,
|
||||
shake_timeout: 200,
|
||||
shake_duration: 100,
|
||||
}, require('Storage').readJSON("multidice.json", true) || {});
|
||||
|
||||
function writeSettings() {
|
||||
require('Storage').writeJSON("multidice.json", settings);
|
||||
}
|
||||
|
||||
// Show the menu
|
||||
E.showMenu({
|
||||
"" : { "title" : "multi dice roll" },
|
||||
"< Back" : () => back(),
|
||||
'vibrate on roll?': {
|
||||
value: !!settings.vibrate,
|
||||
onchange: v => {
|
||||
settings.vibrate = v;
|
||||
writeSettings();
|
||||
}
|
||||
},
|
||||
'allow shaking?': {
|
||||
value: !!settings.shake,
|
||||
onchange: v => {
|
||||
settings.shake = v;
|
||||
writeSettings();
|
||||
}
|
||||
},
|
||||
'screen on to shake?': {
|
||||
value: !!settings.screen,
|
||||
onchange: v => {
|
||||
settings.screen = v;
|
||||
writeSettings();
|
||||
}
|
||||
},
|
||||
'shake timeout': {
|
||||
value: settings.shake_timeout / 5,
|
||||
min: 10, max: 40,
|
||||
format: v => v * 5,
|
||||
onchange: v => {
|
||||
settings.shake_timeout = v * 5;
|
||||
writeSettings();
|
||||
}
|
||||
},
|
||||
'shake duration': {
|
||||
value: settings.shake_duration / 5,
|
||||
min: 10, max: 40,
|
||||
format: v => v * 5,
|
||||
onchange: v => {
|
||||
settings.shake_duration = v * 5;
|
||||
writeSettings();
|
||||
}
|
||||
},
|
||||
});
|
||||
})
|
||||
|
|
@ -49,7 +49,7 @@ Alarms are stored in an array in `sched.json`, and take the form:
|
|||
// e.g. repeat every 2 months: { interval: "month", num: 2 }.
|
||||
// Supported intervals: day, week, month, year
|
||||
vibrate : "...", // OPTIONAL pattern of '.', '-' and ' ' to use for when buzzing out this alarm (defaults to '..' if not set)
|
||||
hidden : false, // OPTIONAL if false, the widget should not show an icon for this alarm
|
||||
hidden : false, // OPTIONAL if true, the widget should not show an icon for this alarm
|
||||
as : false, // auto snooze
|
||||
timer : 5*60*1000, // OPTIONAL - if set, this is a timer and it's the time in ms
|
||||
del : false, // OPTIONAL - if true, delete the timer after expiration
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"description": "A basic implementation of the famous consice workout",
|
||||
"icon": "icon.png",
|
||||
"type":"app",
|
||||
"tags": "Training, Workout",
|
||||
"tags": "training,workout",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"allow_emulator":true,
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
"version": "0.08",
|
||||
"description": "App to test the bangle.js input interface. It displays the user action in text, circle buttons or on/off switch UI elements.",
|
||||
"icon": "app.png",
|
||||
"tags": "input,interface,buttons,touch,UI",
|
||||
"tags": "input,interface,buttons,touch,ui",
|
||||
"supports": ["BANGLEJS"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
0.01: New App!
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
# txtreader
|
||||
|
||||
Very basic text reader with an integrated file selector.
|
||||
|
||||
## Features
|
||||
|
||||
- select files from storage (.txt)
|
||||
- display their contents
|
||||
- browse pages
|
||||
|
||||
## Controls
|
||||
|
||||
Bangle.js 2
|
||||
- tap the right side of the screen to flip to the next page
|
||||
- tap the left side of the screen to flip to the previous page
|
||||
- exit by pressing the physical button
|
||||
|
||||
## Creator
|
||||
|
||||
<https://topkekker.rip/>
|
||||
|
|
@ -0,0 +1 @@
|
|||
require("heatshrink").decompress(atob("mEwwkCkQA/AH4A/AAcosd2m9jw04AQlyC5WL1e63YCG3lUC5WPj/x/8f+H/h4CBj/3jYXLv/3/4CCt4FC/IXM/4AI/YXk/WZzOfCgWfAoIXN/F3u9/C4V/AoIvUI6H3F4p3oC6/73e734XTR4wXQ/vd7vfC6f85gAG55HQAAppBC5n5xAAGz4vmzIAGF/33F49/C5v6F4+vC5rrFd6JHCv4XTI4WfF6lms1vF6mq1WvC6Z3WxfdABHVugXKlFUogAHoVCC5QA/AH4A6A"))
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
function showFileSelector() {
|
||||
let files = require("Storage").list().filter(f => f.endsWith('.txt'));
|
||||
|
||||
let menuItems = {};
|
||||
files.forEach(file => {
|
||||
menuItems[file] = () => {
|
||||
E.showPrompt(`Select ${file}?`).then(confirm => {
|
||||
if (confirm) {
|
||||
onFileSelected(file);
|
||||
} else {
|
||||
showFileSelector();
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
|
||||
menuItems['< Back'] = () => { load(); };
|
||||
E.showMenu(menuItems);
|
||||
}
|
||||
|
||||
function onFileSelected(file) {
|
||||
const chunkSize = 1024;
|
||||
let currentOffset = 0;
|
||||
let currentPage = 1;
|
||||
let history = [];
|
||||
|
||||
function displayText(offset, pageNumber) {
|
||||
g.clear();
|
||||
g.setFont("6x8", 1);
|
||||
g.setColor(g.theme.fg);
|
||||
g.drawString("Page " + pageNumber, 10, 2);
|
||||
//g.drawString("Offset " + offset, 60, 2);
|
||||
g.drawString(file, g.getWidth() - file.length * 6, 2);
|
||||
|
||||
var text = require("Storage").read(file, offset, chunkSize);
|
||||
var lines = text.split("\n");
|
||||
var y = 15; // Text start, top row reserved for page number
|
||||
var linesDisplayed = 0; // Lines per page
|
||||
var totalCharsDisplayed = 0; // Total characters per page
|
||||
|
||||
for (var i = 0; i < lines.length; i++) {
|
||||
var wrappedLines = g.wrapString(lines[i], g.getWidth() - 20);
|
||||
for (var j = 0; j < wrappedLines.length; j++) {
|
||||
g.drawString(wrappedLines[j], 10, y);
|
||||
y += 10; // Move down for the next line
|
||||
linesDisplayed++;
|
||||
totalCharsDisplayed += wrappedLines[j].length + (j < wrappedLines.length - 1 ? 0 : 1); // Add newline character for the last wrapped line
|
||||
if (y >= g.getHeight() - 10) {
|
||||
// If we run out of space, stop drawing
|
||||
return { nextOffset: offset + totalCharsDisplayed, linesDisplayed: linesDisplayed };
|
||||
}
|
||||
}
|
||||
}
|
||||
return null; // No more lines to display
|
||||
}
|
||||
|
||||
// Initial display
|
||||
var result = displayText(currentOffset, currentPage);
|
||||
history.push({ offset: currentOffset, linesDisplayed: result.linesDisplayed });
|
||||
|
||||
// Handle touch events
|
||||
Bangle.on('touch', function(button) {
|
||||
if (button === 2) { // Right side of the screen (next page)
|
||||
var nextOffset = displayText(currentOffset, currentPage + 1);
|
||||
if (nextOffset !== null) {
|
||||
currentOffset = nextOffset.nextOffset;
|
||||
currentPage++;
|
||||
history.push({ offset: currentOffset, linesDisplayed: nextOffset.linesDisplayed });
|
||||
displayText(currentOffset, currentPage);
|
||||
} else {
|
||||
currentOffset = 0;
|
||||
currentPage = 1;
|
||||
history = [{ offset: currentOffset, linesDisplayed: result.linesDisplayed }];
|
||||
displayText(currentOffset, currentPage);
|
||||
}
|
||||
} else if (button === 1) { // Left side of the screen (previous page)
|
||||
if (currentPage > 1) {
|
||||
history.pop(); // Remove current page from history
|
||||
var previousPage = history[history.length - 1];
|
||||
currentOffset = previousPage.offset;
|
||||
currentPage--;
|
||||
displayText(currentOffset, currentPage);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
showFileSelector();
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
{
|
||||
"id": "txtreader",
|
||||
"name": "txtreader",
|
||||
"shortName": "txtreader",
|
||||
"version": "0.01",
|
||||
"description": "Basic text reader with pages and a file selector.",
|
||||
"icon": "txtreader.png",
|
||||
"screenshots": [{"url":"screenshot_txtreader.png"}],
|
||||
"tags": "app,tool",
|
||||
"supports": ["BANGLEJS2"],
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"txtreader.app.js","url":"app.js"},
|
||||
{"name":"txtreader.img","url":"app-icon.js","evaluate":true}
|
||||
]
|
||||
}
|
||||
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
|
@ -2,6 +2,31 @@
|
|||
/* Checks for any obvious problems in apps.json
|
||||
*/
|
||||
|
||||
var BASEDIR = __dirname+"/../";
|
||||
var APPSDIR_RELATIVE = "apps/";
|
||||
var APPSDIR = BASEDIR + APPSDIR_RELATIVE;
|
||||
var showAllErrors = process.argv.includes("--show-all");
|
||||
|
||||
if (process.argv.includes("--help")) {
|
||||
console.log(`BangleApps Sanity Check
|
||||
------------------------
|
||||
|
||||
Checks apps in this repository for common issues that might
|
||||
cause problems.
|
||||
|
||||
USAGE:
|
||||
|
||||
bin/sanitycheck.js
|
||||
- default, runs all tests (hides known errors)
|
||||
bin/sanitycheck.js --show-all
|
||||
- show all warnings/errors (including known ones)
|
||||
bin/sanitycheck.js --help
|
||||
- show this message
|
||||
`);
|
||||
process.exit(0);
|
||||
}
|
||||
|
||||
|
||||
var fs = require("fs");
|
||||
var vm = require("vm");
|
||||
var heatshrink = require("../webtools/heatshrink");
|
||||
|
|
@ -27,40 +52,42 @@ var jsparse = (() => {
|
|||
return str => acorn.parse(str, { ecmaVersion: 2020 });
|
||||
})();
|
||||
|
||||
var BASEDIR = __dirname+"/../";
|
||||
var APPSDIR_RELATIVE = "apps/";
|
||||
var APPSDIR = BASEDIR + APPSDIR_RELATIVE;
|
||||
|
||||
var knownWarningCount = 0;
|
||||
var knownErrorCount = 0;
|
||||
var warningCount = 0;
|
||||
var errorCount = 0;
|
||||
var warningList = [];
|
||||
var errorList = [];
|
||||
|
||||
function ERROR(msg, opt) {
|
||||
// file=app.js,line=1,col=5,endColumn=7
|
||||
opt = opt||{};
|
||||
errorList.push(msg);
|
||||
if (KNOWN_ERRORS.includes(msg)) {
|
||||
console.log(`Known error : ${msg}`);
|
||||
knownErrorCount++;
|
||||
} else {
|
||||
if (!showAllErrors) return;
|
||||
msg += " (KNOWN)"
|
||||
}
|
||||
console.log(`::error${Object.keys(opt).length?" ":""}${Object.keys(opt).map(k=>k+"="+opt[k]).join(",")}::${msg}`);
|
||||
errorCount++;
|
||||
}
|
||||
}
|
||||
function WARN(msg, opt) {
|
||||
// file=app.js,line=1,col=5,endColumn=7
|
||||
opt = opt||{};
|
||||
warningList.push(msg);
|
||||
if (KNOWN_WARNINGS.includes(msg)) {
|
||||
console.log(`Known warning : ${msg}`);
|
||||
knownWarningCount++;
|
||||
} else {
|
||||
if (!showAllErrors) return;
|
||||
msg += " (KNOWN)"
|
||||
}
|
||||
console.log(`::warning${Object.keys(opt).length?" ":""}${Object.keys(opt).map(k=>k+"="+opt[k]).join(",")}::${msg}`);
|
||||
warningCount++;
|
||||
}
|
||||
}
|
||||
/* These are errors that we temporarily allow */
|
||||
var KNOWN_ERRORS = [
|
||||
"In locale en_CA, long date output must be shorter than 15 characters (Wednesday, September 10, 2024 -> 29)",
|
||||
"In locale fr_FR, long date output must be shorter than 15 characters (10 septembre 2024 -> 17)",
|
||||
"In locale fr_FR, short month must be shorter than 5 characters",
|
||||
"In locale sv_SE, speed must be shorter than 5 characters",
|
||||
"In locale en_SE, long date output must be shorter than 15 characters (September 10 2024 -> 17)",
|
||||
"In locale en_NZ, long date output must be shorter than 15 characters (Wednesday, September 10, 2024 -> 29)",
|
||||
|
|
@ -69,51 +96,23 @@ var KNOWN_ERRORS = [
|
|||
"In locale en_IL, long date output must be shorter than 15 characters (Wednesday, September 10, 2024 -> 29)",
|
||||
"In locale es_ES, long date output must be shorter than 15 characters (miércoles, 10 de septiembre de 2024 -> 35)",
|
||||
"In locale fr_BE, long date output must be shorter than 15 characters (dimanche septembre 10 2024 -> 26)",
|
||||
"In locale fr_BE, short month must be shorter than 5 characters",
|
||||
"In locale fr_BE, short month must be shorter than 5 characters",
|
||||
"In locale fr_BE, short month must be shorter than 5 characters",
|
||||
"In locale fr_BE, short month must be shorter than 5 characters",
|
||||
"In locale fr_BE, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, long date output must be shorter than 15 characters (keskiviikkona 10. maaliskuuta 2024 -> 34)",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale fi_FI, short month must be shorter than 5 characters",
|
||||
"In locale de_CH, meridian must be shorter than 4 characters",
|
||||
"In locale de_CH, meridian must be shorter than 4 characters",
|
||||
"In locale de_CH, long date output must be shorter than 15 characters (Donnerstag, 10. September 2024 -> 30)",
|
||||
"In locale fr_CH, long date output must be shorter than 15 characters (dimanche 10 septembre 2024 -> 26)",
|
||||
"In locale fr_CH, short month must be shorter than 5 characters",
|
||||
"In locale fr_CH, short month must be shorter than 5 characters",
|
||||
"In locale fr_CH, short month must be shorter than 5 characters",
|
||||
"In locale fr_CH, short month must be shorter than 5 characters",
|
||||
"In locale fr_CH, short month must be shorter than 5 characters",
|
||||
"In locale wae_CH, long date output must be shorter than 15 characters (Sunntag, 10. Herbštmánet 2024 -> 29)",
|
||||
"In locale tr_TR, long date output must be shorter than 15 characters (10 Haziran 2024 Pazartesi -> 25)",
|
||||
"In locale hu_HU, long date output must be shorter than 15 characters (2024 Szep 10, Csütörtök -> 23)",
|
||||
"In locale oc_FR, long date output must be shorter than 15 characters (divendres 10 setembre de 2024 -> 29)",
|
||||
"In locale oc_FR, short month must be shorter than 5 characters",
|
||||
"In locale oc_FR, short month must be shorter than 5 characters",
|
||||
"In locale hr_HR, meridian must be shorter than 4 characters",
|
||||
"In locale hr_HR, meridian must be shorter than 4 characters",
|
||||
"In locale hr_HR, short month must be shorter than 5 characters",
|
||||
"In locale sl_SI, meridian must be shorter than 4 characters",
|
||||
"In locale sl_SI, meridian must be shorter than 4 characters",
|
||||
"In locale ca_ES, long date output must be shorter than 15 characters (10 setembre 2024 -> 16)",
|
||||
"In locale ca_ES, short month must be shorter than 5 characters",
|
||||
];
|
||||
/* These are warnings we know about but don't want in our output */
|
||||
var KNOWN_WARNINGS = [
|
||||
"App gpsrec data file wildcard .gpsrc? does not include app ID",
|
||||
"App owmweather data file weather.json is also listed as data file for app weather",
|
||||
"App messagegui storage file messagegui is also listed as storage file for app messagelist",
|
||||
"App carcrazy has a setting file but no corresponding data entry (add `\"data\":[{\"name\":\"carcrazy.settings.json\"}]`)",
|
||||
"App loadingscreen has a setting file but no corresponding data entry (add `\"data\":[{\"name\":\"loadingscreen.settings.json\"}]`)",
|
||||
"App trex has a setting file but no corresponding data entry (add `\"data\":[{\"name\":\"trex.settings.json\"}]`)",
|
||||
|
|
@ -169,7 +168,7 @@ const APP_KEYS = [
|
|||
const STORAGE_KEYS = ['name', 'url', 'content', 'evaluate', 'noOverwite', 'supports', 'noOverwrite'];
|
||||
const DATA_KEYS = ['name', 'wildcard', 'storageFile', 'url', 'content', 'evaluate'];
|
||||
const SUPPORTS_DEVICES = ["BANGLEJS","BANGLEJS2"]; // device IDs allowed for 'supports'
|
||||
const METADATA_TYPES = ["app","clock","widget","bootloader","RAM","launch","scheduler","notify","locale","settings","textinput","module","clkinfo"]; // values allowed for "type" field
|
||||
const METADATA_TYPES = ["app","clock","widget","bootloader","RAM","launch","scheduler","notify","locale","settings","textinput","module","clkinfo","defaultconfig"]; // values allowed for "type" field - listed in README.md
|
||||
const FORBIDDEN_FILE_NAME_CHARS = /[,;]/; // used as separators in appid.info
|
||||
const VALID_DUPLICATES = [ '.tfmodel', '.tfnames' ];
|
||||
const GRANDFATHERED_ICONS = ["s7clk", "snek", "astral", "alpinenav", "slomoclock", "arrow", "pebble", "rebble"];
|
||||
|
|
@ -207,6 +206,10 @@ apps.forEach((app,appIdx) => {
|
|||
if (!app.name) ERROR(`App ${app.id} has no name`, {file:metadataFile});
|
||||
var isApp = !app.type || app.type=="app";
|
||||
var appTags = app.tags ? app.tags.split(",") : [];
|
||||
if (appTags.some(tag => tag!=tag.trim()))
|
||||
WARN(`App ${app.id} 'tag' list contains whitespace ("${app.tags}")`, {file:metadataFile});
|
||||
if (appTags.some(tag => tag!=tag.toLowerCase()))
|
||||
WARN(`App ${app.id} 'tag' list contains uppercase ("${app.tags}")`, {file:metadataFile});
|
||||
if (app.name.length>20 && !app.shortName && isApp) ERROR(`App ${app.id} has a long name, but no shortName`, {file:metadataFile});
|
||||
if (app.type && !METADATA_TYPES.includes(app.type))
|
||||
ERROR(`App ${app.id} 'type' is one one of `+METADATA_TYPES, {file:metadataFile});
|
||||
|
|
@ -296,6 +299,7 @@ apps.forEach((app,appIdx) => {
|
|||
if (INTERNAL_FILES_IN_APP_TYPE[app.type].includes(file.name))
|
||||
fileInternal = true;
|
||||
}
|
||||
if (!app.type=="defaultconfig")
|
||||
allFiles.push({app: app.id, file: file.name, internal:fileInternal});
|
||||
if (file.url) if (!fs.existsSync(appDir+file.url)) ERROR(`App ${app.id} file ${file.url} doesn't exist`, {file:metadataFile});
|
||||
if (!file.url && !file.content && !app.custom) ERROR(`App ${app.id} file ${file.name} has no contents`, {file:metadataFile});
|
||||
|
|
@ -494,7 +498,7 @@ while(fileA=allFiles.pop()) {
|
|||
if (isGlob(nameA)||isGlob(nameB))
|
||||
ERROR(`App ${fileB.app} ${typeB} file ${nameB} matches app ${fileA.app} ${typeB} file ${nameA}`);
|
||||
else if (fileA.app != fileB.app && (!fileA.internal) && (!fileB.internal))
|
||||
WARN(`App ${fileB.app} ${typeB} file ${nameB} is also listed as ${typeA} file for app ${fileA.app}`);
|
||||
WARN(`App ${fileB.app} ${typeB} file ${nameB} is also listed as ${typeA} file for app ${fileA.app}`, {file:APPSDIR_RELATIVE+fileB.app+"/metadata.json"});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
@ -520,8 +524,17 @@ function sanityCheckLocales(){
|
|||
}
|
||||
|
||||
promise.then(function() {
|
||||
KNOWN_ERRORS.forEach(msg => {
|
||||
if (!errorList.includes(msg))
|
||||
WARN(`Known error '${msg}' no longer occurs`);
|
||||
});
|
||||
KNOWN_WARNINGS.forEach(msg => {
|
||||
if (!warningList.includes(msg))
|
||||
WARN(`Known warning '${msg}' no longer occurs`);
|
||||
});
|
||||
console.log("==================================");
|
||||
console.log(`${errorCount} errors, ${warningCount} warnings (and ${knownErrorCount} known errors, ${knownWarningCount} known warnings)`);
|
||||
console.log(`${errorCount} errors, ${warningCount} warnings`);
|
||||
console.log(`${knownErrorCount} known errors, ${knownWarningCount} known warnings${(knownErrorCount||knownWarningCount)?", run with --show-all to see them":""}`);
|
||||
console.log("==================================");
|
||||
if (errorCount) {
|
||||
process.exit(1);
|
||||
|
|
|
|||
2
core
|
|
@ -1 +1 @@
|
|||
Subproject commit bf08b484830ef4e811faf67ec663ebf839b5d09b
|
||||
Subproject commit 3ec8e289a26a545d0d0c50f6945978584fb3d7f8
|
||||
|
|
@ -14,4 +14,4 @@ type AppInfo = {
|
|||
|
||||
type AppType = "app" | "clock" | "widget" | "module" | "bootloader" |
|
||||
"settings" | "clkinfo" | "RAM" | "launch" | "textinput" | "scheduler" |
|
||||
"notify" | "locale";
|
||||
"notify" | "locale" | "defaultconfig";
|
||||
|
|
|
|||