mirror of https://github.com/espruino/BangleApps
124 lines
3.3 KiB
JavaScript
124 lines
3.3 KiB
JavaScript
|
var Storage = require("Storage");
|
||
|
var Layout = require("Layout");
|
||
|
|
||
|
var font = "6x15";
|
||
|
var largeFont = "12x20";
|
||
|
var currentApp = 0;
|
||
|
var overscroll = 0;
|
||
|
var blankImage = Graphics.createImage(` `);
|
||
|
var rowHeight = g.getHeight()/3;
|
||
|
|
||
|
// Load apps list
|
||
|
var apps = Storage.list(/\.info$/).map(app=>{
|
||
|
var a=Storage.readJSON(app,1);
|
||
|
return a&&{
|
||
|
name:a.name,
|
||
|
type:a.type,
|
||
|
icon:a.icon ? Storage.read(a.icon) : a.icon,
|
||
|
sortorder:a.sortorder,
|
||
|
src:a.src
|
||
|
};
|
||
|
}).filter(app=>app && (
|
||
|
app.type=="app"
|
||
|
// || (app.type=="clock" && settings.showClocks)
|
||
|
|| !app.type
|
||
|
));
|
||
|
apps.sort((a,b)=>{
|
||
|
var n=(0|a.sortorder)-(0|b.sortorder);
|
||
|
if (n) return n; // do sortorder first
|
||
|
if (a.name<b.name) return -1;
|
||
|
if (a.name>b.name) return 1;
|
||
|
return 0;
|
||
|
});
|
||
|
|
||
|
// Initialize layout
|
||
|
var layout = new Layout({
|
||
|
type:"v", c:[
|
||
|
// A row for the previous app
|
||
|
{ type:"h", height:rowHeight, c:[
|
||
|
{type: "img", id:"prev_icon", src:blankImage, width:48, height:48, scale:0.8, pad:8},
|
||
|
{type: "txt", id:"prev_name", label:"", font:font, fillx:1, wrap:1},
|
||
|
]},
|
||
|
// A row for the current app
|
||
|
{ type:"h", height:rowHeight, c:[
|
||
|
{type: "img", id:"cur_icon", src:apps[currentApp].icon, width:48, height:48},
|
||
|
{type: "txt", id:"cur_name", label:apps[currentApp].name, font:largeFont, fillx:1, wrap:1},
|
||
|
]},
|
||
|
// A row for the next app
|
||
|
{ type:"h", height:rowHeight, c:[
|
||
|
{type: "img", id:"next_icon", src:blankImage, width:48, height:48, scale:0.8, pad:8},
|
||
|
{type: "txt", id:"next_name", label:"", font:font, fillx:1, wrap:1},
|
||
|
]},
|
||
|
]
|
||
|
});
|
||
|
|
||
|
// Drawing logic
|
||
|
function render() {
|
||
|
// Previous app
|
||
|
if (currentApp > 0) {
|
||
|
layout.prev_icon.src = apps[currentApp-1].icon;
|
||
|
layout.prev_name.label = apps[currentApp-1].name;
|
||
|
} else {
|
||
|
layout.prev_icon.src = blankImage;
|
||
|
layout.prev_name.label = "";
|
||
|
}
|
||
|
|
||
|
// Current app
|
||
|
layout.cur_icon.src = apps[currentApp].icon;
|
||
|
layout.cur_name.label = apps[currentApp].name;
|
||
|
|
||
|
// Next app
|
||
|
if (currentApp < apps.length-1) {
|
||
|
layout.next_icon.src = apps[currentApp+1].icon;
|
||
|
layout.next_name.label = apps[currentApp+1].name;
|
||
|
} else {
|
||
|
layout.next_icon.src = blankImage;
|
||
|
layout.next_name.label = "";
|
||
|
}
|
||
|
|
||
|
g.clear();
|
||
|
layout.render();
|
||
|
}
|
||
|
|
||
|
// Launch the currently selected app
|
||
|
function launch() {
|
||
|
var app = apps[currentApp];
|
||
|
if (!app) return;
|
||
|
if (!app.src || Storage.read(app.src)===undefined) {
|
||
|
E.showMessage(/*LANG*/"App Source\nNot found");
|
||
|
setTimeout(drawMenu, 2000);
|
||
|
} else {
|
||
|
E.showMessage(/*LANG*/"Loading...");
|
||
|
load(app.src);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Select previous/next app
|
||
|
function move(step) {
|
||
|
if ((currentApp == 0 && step < 0) || (currentApp >= apps.length-1 && step > 0)) {
|
||
|
// When we hit the end of the list (top or bottom), the step is
|
||
|
// counted towards the overscroll value. When the overscroll
|
||
|
// threshold is exceeded, we return to the clock face.
|
||
|
overscroll += step;
|
||
|
} else {
|
||
|
// This is the default case: the step is countedf towards the currentApp index
|
||
|
currentApp += step;
|
||
|
overscroll = 0;
|
||
|
return render();
|
||
|
}
|
||
|
|
||
|
// Overscroll threshold reached, return to clock
|
||
|
if (Math.abs(overscroll) > 3) {
|
||
|
Bangle.buzz(500, 1);
|
||
|
return load();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Wire up user input
|
||
|
Bangle.setUI('updown', dir => {
|
||
|
if (dir) move(-1*dir);
|
||
|
else launch();
|
||
|
});
|
||
|
|
||
|
render();
|