forked from FOSS/BangleApps
Working GPS track recording - just need to fix the 'interface.html' to do the comms and do something with the data collected
parent
a59ea3eee6
commit
2bca5d4747
|
@ -193,6 +193,10 @@ about the app.
|
||||||
// iframe, and it must post back an 'app' structure
|
// iframe, and it must post back an 'app' structure
|
||||||
// like this one with 'storage','name' and 'id' set up
|
// like this one with 'storage','name' and 'id' set up
|
||||||
|
|
||||||
|
"interface": "interface.html", // if supplied, apps/interface.html is loaded in an
|
||||||
|
// iframe, and it may interact with the connected Bangle
|
||||||
|
// to retrieve information from it
|
||||||
|
|
||||||
"allow_emulator":true, // if 'app.js' will run in the emulator, set to true to
|
"allow_emulator":true, // if 'app.js' will run in the emulator, set to true to
|
||||||
// add an icon to allow your app to be tested
|
// add an icon to allow your app to be tested
|
||||||
|
|
||||||
|
|
21
apps.json
21
apps.json
|
@ -173,7 +173,7 @@
|
||||||
"icon": "gpstime.png",
|
"icon": "gpstime.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "Update the Bangle.js's clock based on the time from the GPS receiver",
|
"description": "Update the Bangle.js's clock based on the time from the GPS receiver",
|
||||||
"tags": "tool",
|
"tags": "tool,gps",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+gpstime","url":"gpstime.json"},
|
{"name":"+gpstime","url":"gpstime.json"},
|
||||||
{"name":"-gpstime","url":"gpstime.js"},
|
{"name":"-gpstime","url":"gpstime.js"},
|
||||||
|
@ -185,7 +185,7 @@
|
||||||
"icon": "openlocation.png",
|
"icon": "openlocation.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "Convert your current GPS location to a series of characters",
|
"description": "Convert your current GPS location to a series of characters",
|
||||||
"tags": "tool,outdoors",
|
"tags": "tool,outdoors,gps",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+openloc","url":"openlocation.json"},
|
{"name":"+openloc","url":"openlocation.json"},
|
||||||
{"name":"-openloc","url":"openlocation.js","evaluate":true}
|
{"name":"-openloc","url":"openlocation.js","evaluate":true}
|
||||||
|
@ -196,13 +196,28 @@
|
||||||
"icon": "speedo.png",
|
"icon": "speedo.png",
|
||||||
"version":"0.01",
|
"version":"0.01",
|
||||||
"description": "Show the current speed according to the GPS",
|
"description": "Show the current speed according to the GPS",
|
||||||
"tags": "tool,outdoors",
|
"tags": "tool,outdoors,gps",
|
||||||
"storage": [
|
"storage": [
|
||||||
{"name":"+speedo","url":"speedo.json"},
|
{"name":"+speedo","url":"speedo.json"},
|
||||||
{"name":"-speedo","url":"speedo.js"},
|
{"name":"-speedo","url":"speedo.js"},
|
||||||
{"name":"*speedo","url":"speedo-icon.js","evaluate":true}
|
{"name":"*speedo","url":"speedo-icon.js","evaluate":true}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{ "id": "gpsrec",
|
||||||
|
"name": "GPS Recorder",
|
||||||
|
"icon": "app.png",
|
||||||
|
"version":"0.01",
|
||||||
|
"interface": "interface.html",
|
||||||
|
"description": "Application that allows you to record a GPS track. Can run in background",
|
||||||
|
"tags": "tool,outdoors,gps",
|
||||||
|
"storage": [
|
||||||
|
{"name":"+gpsrec","url":"app.json"},
|
||||||
|
{"name":"-gpsrec","url":"app.js"},
|
||||||
|
{"name":"@gpsrec","url":"app-settings.json","evaluate":true},
|
||||||
|
{"name":"*gpsrec","url":"app-icon.js","evaluate":true},
|
||||||
|
{"name":"=gpsrec","url":"widget.js"}
|
||||||
|
]
|
||||||
|
},
|
||||||
{ "id": "slevel",
|
{ "id": "slevel",
|
||||||
"name": "Spirit Level",
|
"name": "Spirit Level",
|
||||||
"icon": "spiritlevel.png",
|
"icon": "spiritlevel.png",
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
0.00: New App!
|
|
@ -0,0 +1 @@
|
||||||
|
require("heatshrink").decompress(atob("mEwxH+AH4A/AH4A/AF/W63P54XVCigACF4IACC6QsUF44yKC44sUF5QyEC5QuWF5fPC5Yv/F/3OAYgviwNdroqCwF6wHP1V6vQwKF61eiAABGAQqBFYOkAYOr62rwADBF63V1ZOCmgvCmgvB1Wk1QEB0ml6vVGYOAF65PBDQU6F4rvH6qYB0ovXDQN66vW1hgBmhnBF5AwBAgOlSQgvR5+lC4fPFpAvECASSFd6weBABR3HSQYvpSQQvsUILWBF9XVX4OkF9bvd0ocB5/O1XOR5er0oIDF62AJoPPAYIzBF5QAFF6QoBE4OrVgKACGYIvI6GI1gvXFYN60q/D52k5ySFFwc0iEQrxfXK4TvGSQoTCwQuBAAJhDF6GIxHQ6vVGgQAESQfOTwQvZnQWBmgXDF4qSC5+kGYOr62sR4U0R6WsI4eCF5AzETwYYBwWC6AvlX4gAIR553DR5Ivhd4OCFwYvpAAwv/F7wMBF6ouLF5APHF54sMF44SNF5IsPF4gUSGQQXVAH4A/AH4A/ADY"))
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"recording":false,
|
||||||
|
"file":0,
|
||||||
|
"period":1
|
||||||
|
}
|
|
@ -0,0 +1,115 @@
|
||||||
|
Bangle.loadWidgets();
|
||||||
|
Bangle.drawWidgets();
|
||||||
|
|
||||||
|
var settings = require("Storage").readJSON("@gpsrec")||{};
|
||||||
|
|
||||||
|
function getFN(n) {
|
||||||
|
return ".gpsrc"+n.toString(36);
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateSettings() {
|
||||||
|
require("Storage").write("@gpsrec", settings);
|
||||||
|
if (WIDGETS["gpsrec"])
|
||||||
|
WIDGETS["gpsrec"].reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
function showMainMenu() {
|
||||||
|
const mainmenu = {
|
||||||
|
'': { 'title': 'GPS Record' },
|
||||||
|
'RECORD': {
|
||||||
|
value: !!settings.recording,
|
||||||
|
format: v=>v?"On":"Off",
|
||||||
|
onchange: v => {
|
||||||
|
settings.recording = v;
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'File #': {
|
||||||
|
value: settings.file|0,
|
||||||
|
min: 0,
|
||||||
|
max: 35,
|
||||||
|
step: 1,
|
||||||
|
onchange: v => {
|
||||||
|
settings.recording = false;
|
||||||
|
settings.file = v;
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'Time Period': {
|
||||||
|
value: settings.period||1,
|
||||||
|
min: 1,
|
||||||
|
max: 60,
|
||||||
|
step: 1,
|
||||||
|
onchange: v => {
|
||||||
|
settings.recording = false;
|
||||||
|
settings.period = v;
|
||||||
|
updateSettings();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'View Tracks': viewTracks,
|
||||||
|
'< Back': ()=>{load();}
|
||||||
|
};
|
||||||
|
return E.showMenu(mainmenu);
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewTracks() {
|
||||||
|
const menu = {
|
||||||
|
'': { 'title': 'GPS Tracks' }
|
||||||
|
};
|
||||||
|
var found = false;
|
||||||
|
for (var n=0;n<36;n++) {
|
||||||
|
var f = require("Storage").open(getFN(n),"r");
|
||||||
|
if (f.readLine()!==undefined) {
|
||||||
|
menu["Track "+n] = viewTrack.bind(null,n);
|
||||||
|
found = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!found)
|
||||||
|
menu["No Tracks found"] = function(){};
|
||||||
|
menu['< Back'] = showMainMenu;
|
||||||
|
return E.showMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
function viewTrack(n) {
|
||||||
|
const menu = {
|
||||||
|
'': { 'title': 'GPS Track '+n }
|
||||||
|
};
|
||||||
|
var trackCount = 0;
|
||||||
|
var trackTime;
|
||||||
|
var f = require("Storage").open(getFN(n),"r");
|
||||||
|
var l = f.readLine();
|
||||||
|
if (l!==undefined) {
|
||||||
|
var c = l.split(",");
|
||||||
|
trackTime = new Date(0|c[0]);
|
||||||
|
}
|
||||||
|
while (l!==undefined) {
|
||||||
|
trackCount++;
|
||||||
|
// TODO: min/max/length of track?
|
||||||
|
l = f.readLine();
|
||||||
|
}
|
||||||
|
if (trackTime)
|
||||||
|
menu[" "+trackTime.toISOString().substr(0,16).replace("T"," ")] = function(){};
|
||||||
|
menu[trackCount+" records"] = function(){};
|
||||||
|
// TODO: option to draw it? Just scan through, project using min/max
|
||||||
|
menu['Erase'] = function() {
|
||||||
|
E.showPrompt("Delete Track?").then(function(v) {
|
||||||
|
if (v) {
|
||||||
|
settings.recording = false;
|
||||||
|
updateSettings();
|
||||||
|
var f = require("Storage").open(getFN(n),"r");
|
||||||
|
f.erase();
|
||||||
|
viewTracks();
|
||||||
|
} else
|
||||||
|
viewTrack(n);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
menu['< Back'] = viewTracks;
|
||||||
|
print(menu);
|
||||||
|
return E.showMenu(menu);
|
||||||
|
}
|
||||||
|
|
||||||
|
showMainMenu();
|
||||||
|
|
||||||
|
|
||||||
|
// f = require("Storage").open(".gpsrc"+n,"r");
|
||||||
|
// f.readLine()...
|
|
@ -0,0 +1,5 @@
|
||||||
|
{
|
||||||
|
"name":"GPS Recorder",
|
||||||
|
"icon":"*gpsrec",
|
||||||
|
"src":"-gpsrec"
|
||||||
|
}
|
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
|
@ -0,0 +1,37 @@
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<p>Hello!</p>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
var __id = 0, __idlookup = [];
|
||||||
|
var Puck = {
|
||||||
|
eval : function(data,callback) {
|
||||||
|
__id++;
|
||||||
|
__idlookup[__id] = callback;
|
||||||
|
window.postMessage({type:"eval",data:data,id:__id});
|
||||||
|
},write : function(data,callback) {
|
||||||
|
__id++;
|
||||||
|
__idlookup[__id] = callback;
|
||||||
|
window.postMessage({type:"write",data:data,id:__id});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
window.addEventListener("message", function(event) {
|
||||||
|
var msg = event.data;
|
||||||
|
if (msg.type=="evalrsp" || msg.type=="writersp") {
|
||||||
|
var cb = __idlookup[msg.id];
|
||||||
|
delete __idlookup[msg.id];
|
||||||
|
cb(msg.data);
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
|
||||||
|
Puck.eval("E.getTemperature()",function(d) {
|
||||||
|
console.log("GOT: "+d);
|
||||||
|
});
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,76 @@
|
||||||
|
(() => {
|
||||||
|
// add the width
|
||||||
|
var xpos = WIDGETPOS.tl;
|
||||||
|
WIDGETPOS.tl += 24;/* the widget width plus some extra pixel to keep distance to others */;
|
||||||
|
var settings = {};
|
||||||
|
var hasFix = false;
|
||||||
|
var fixToggle = false; // toggles once for each reading
|
||||||
|
var gpsTrack; // file for GPS track
|
||||||
|
var periodCtr = 0;
|
||||||
|
|
||||||
|
// draw your widget at xpos
|
||||||
|
function draw() {
|
||||||
|
g.reset();
|
||||||
|
g.setFont("4x6");
|
||||||
|
g.setFontAlign(0,0);
|
||||||
|
g.clearRect(xpos,0,xpos+23,23);
|
||||||
|
|
||||||
|
if (!settings.recording) {
|
||||||
|
g.setColor("#606060");
|
||||||
|
} else {
|
||||||
|
g.setColor("#ff0000");
|
||||||
|
if (hasFix) {
|
||||||
|
if (fixToggle) {
|
||||||
|
g.fillCircle(xpos+11,11,9);
|
||||||
|
g.setColor("#000000");
|
||||||
|
} else
|
||||||
|
g.drawCircle(xpos+11,11,9);
|
||||||
|
} else {
|
||||||
|
g.setColor(fixToggle ? "#ff0000" : "#7f0000");
|
||||||
|
g.drawString("NO",xpos+12,5);
|
||||||
|
g.drawString("FIX",xpos+12,19);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g.drawString("GPS",xpos+12,12);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onGPS(fix) {
|
||||||
|
hasFix = fix.fix;
|
||||||
|
fixToggle = !fixToggle;
|
||||||
|
draw();
|
||||||
|
if (hasFix) {
|
||||||
|
periodCtr--;
|
||||||
|
if (periodCtr<=0) {
|
||||||
|
periodCtr = settings.period;
|
||||||
|
if (gpsTrack) gpsTrack.write([
|
||||||
|
fix.time.getTime()|0,
|
||||||
|
fix.lat.toFixed(5),
|
||||||
|
fix.lon.toFixed(5),
|
||||||
|
fix.alt
|
||||||
|
].join(",")+"\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Called by the GPS app to reload settings and decide what's
|
||||||
|
function reload() {
|
||||||
|
settings = require("Storage").readJSON("@gpsrec")||{};
|
||||||
|
settings.period = settings.period||1;
|
||||||
|
settings.file |= 0;
|
||||||
|
|
||||||
|
Bangle.removeListener('GPS',onGPS);
|
||||||
|
if (settings.recording) {
|
||||||
|
Bangle.on('GPS',onGPS);
|
||||||
|
Bangle.setGPSPower(1);
|
||||||
|
var n = settings.file.toString(36);
|
||||||
|
gpsTrack = require("Storage").open(".gpsrc"+n,"a");
|
||||||
|
} else {
|
||||||
|
Bangle.setGPSPower(0);
|
||||||
|
gpsTrack = undefined;
|
||||||
|
}
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
reload();
|
||||||
|
// add the widget
|
||||||
|
WIDGETS["gpsrec"]={draw:draw,reload:reload};
|
||||||
|
})()
|
66
index.js
66
index.js
|
@ -86,6 +86,8 @@ function showPrompt(title, text) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
function handleCustomApp(app) {
|
function handleCustomApp(app) {
|
||||||
|
// Pops up an IFRAME that allows an app to be customised
|
||||||
|
if (!app.custom) throw new Error("App doesn't have custom HTML");
|
||||||
return new Promise((resolve,reject) => {
|
return new Promise((resolve,reject) => {
|
||||||
var modal = htmlElement(`<div class="modal active">
|
var modal = htmlElement(`<div class="modal active">
|
||||||
<a href="#close" class="modal-overlay " aria-label="Close"></a>
|
<a href="#close" class="modal-overlay " aria-label="Close"></a>
|
||||||
|
@ -119,6 +121,58 @@ function handleCustomApp(app) {
|
||||||
}, false);
|
}, false);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function handleAppInterface(app) {
|
||||||
|
// IFRAME interface window that can be used to get data from the app
|
||||||
|
if (!app.interface) throw new Error("App doesn't have interface HTML");
|
||||||
|
return new Promise((resolve,reject) => {
|
||||||
|
var modal = htmlElement(`<div class="modal active">
|
||||||
|
<a href="#close" class="modal-overlay " aria-label="Close"></a>
|
||||||
|
<div class="modal-container" style="height:100%">
|
||||||
|
<div class="modal-header">
|
||||||
|
<a href="#close" class="btn btn-clear float-right" aria-label="Close"></a>
|
||||||
|
<div class="modal-title h5">${escapeHtml(app.name)}</div>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body" style="height:100%">
|
||||||
|
<div class="content" style="height:100%">
|
||||||
|
<iframe style="width:100%;height:100%;border:0px;">
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>`);
|
||||||
|
document.body.append(modal);
|
||||||
|
htmlToArray(modal.getElementsByTagName("a")).forEach(button => {
|
||||||
|
button.addEventListener("click",event => {
|
||||||
|
event.preventDefault();
|
||||||
|
modal.remove();
|
||||||
|
//reject("Window closed");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
var iframe = modal.getElementsByTagName("iframe")[0];
|
||||||
|
var iwin = iframe.contentWindow;
|
||||||
|
iwin.addEventListener("message", function(event) {
|
||||||
|
var msg = event.data;
|
||||||
|
if (msg.type=="eval") {
|
||||||
|
Puck.eval(msg.data, function(result) {
|
||||||
|
iwin.postMessage({
|
||||||
|
type : "evalrsp",
|
||||||
|
data : result,
|
||||||
|
id : msg.id
|
||||||
|
});
|
||||||
|
});
|
||||||
|
} else if (msg.type=="write") {
|
||||||
|
Puck.write(msg.data, function() {
|
||||||
|
iwin.postMessage({
|
||||||
|
type : "writersp",
|
||||||
|
id : msg.id
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}, false);
|
||||||
|
iframe.src = `apps/${app.id}/${app.interface}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// =========================================== Top Navigation
|
// =========================================== Top Navigation
|
||||||
function showTab(tabname) {
|
function showTab(tabname) {
|
||||||
htmlToArray(document.querySelectorAll("#tab-navigate .tab-item")).forEach(tab => {
|
htmlToArray(document.querySelectorAll("#tab-navigate .tab-item")).forEach(tab => {
|
||||||
|
@ -162,6 +216,7 @@ function refreshLibrary() {
|
||||||
<p class="tile-subtitle">${escapeHtml(app.description)}</p>
|
<p class="tile-subtitle">${escapeHtml(app.description)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tile-action">
|
<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>
|
||||||
<button class="btn btn-link btn-action btn-lg ${app.allow_emulator?"":"d-hide"}" appid="${app.id}" title="Try in Emulator"><i class="icon icon-share"></i></button>
|
<button class="btn btn-link btn-action btn-lg ${app.allow_emulator?"":"d-hide"}" appid="${app.id}" title="Try in Emulator"><i class="icon icon-share"></i></button>
|
||||||
<button class="btn btn-link btn-action btn-lg ${version.canUpdate?"":"d-hide"}" appid="${app.id}" title="Update App"><i class="icon icon-refresh"></i></button>
|
<button class="btn btn-link btn-action btn-lg ${version.canUpdate?"":"d-hide"}" appid="${app.id}" title="Update App"><i class="icon icon-refresh"></i></button>
|
||||||
<button class="btn btn-link btn-action btn-lg ${!appInstalled?"":"d-hide"}" appid="${app.id}" title="Upload App"><i class="icon icon-upload"></i></button>
|
<button class="btn btn-link btn-action btn-lg ${!appInstalled?"":"d-hide"}" appid="${app.id}" title="Upload App"><i class="icon icon-upload"></i></button>
|
||||||
|
@ -236,6 +291,8 @@ function refreshLibrary() {
|
||||||
icon.classList.remove("icon-refresh");
|
icon.classList.remove("icon-refresh");
|
||||||
icon.classList.add("loading");
|
icon.classList.add("loading");
|
||||||
updateApp(app);
|
updateApp(app);
|
||||||
|
} else if (icon.classList.contains("icon-download")) {
|
||||||
|
handleAppInterface(app);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -272,6 +329,7 @@ function updateApp(app) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function appNameToApp(appName) {
|
function appNameToApp(appName) {
|
||||||
var app = appJSON.find(app=>app.id==appName);
|
var app = appJSON.find(app=>app.id==appName);
|
||||||
if (app) return app;
|
if (app) return app;
|
||||||
|
@ -301,9 +359,9 @@ function refreshMyApps() {
|
||||||
var panelbody = document.querySelector("#myappscontainer .panel-body");
|
var panelbody = document.querySelector("#myappscontainer .panel-body");
|
||||||
var tab = document.querySelector("#tab-myappscontainer a");
|
var tab = document.querySelector("#tab-myappscontainer a");
|
||||||
tab.setAttribute("data-badge", appsInstalled.length);
|
tab.setAttribute("data-badge", appsInstalled.length);
|
||||||
panelbody.innerHTML = appsInstalled.map(appJSON => {
|
panelbody.innerHTML = appsInstalled.map(appInstalled => {
|
||||||
var app = appNameToApp(appJSON.id);
|
var app = appNameToApp(appInstalled.id);
|
||||||
var version = getVersionInfo(app, appJSON);
|
var version = getVersionInfo(app, appInstalled);
|
||||||
return `<div class="tile column col-6 col-sm-12 col-xs-12">
|
return `<div class="tile column col-6 col-sm-12 col-xs-12">
|
||||||
<div class="tile-icon">
|
<div class="tile-icon">
|
||||||
<figure class="avatar"><img src="apps/${app.icon?`${app.id}/${app.icon}`:"unknown.png"}" alt="${escapeHtml(app.name)}"></figure>
|
<figure class="avatar"><img src="apps/${app.icon?`${app.id}/${app.icon}`:"unknown.png"}" alt="${escapeHtml(app.name)}"></figure>
|
||||||
|
@ -313,6 +371,7 @@ return `<div class="tile column col-6 col-sm-12 col-xs-12">
|
||||||
<p class="tile-subtitle">${escapeHtml(app.description)}</p>
|
<p class="tile-subtitle">${escapeHtml(app.description)}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="tile-action">
|
<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>
|
||||||
<button class="btn btn-link btn-action btn-lg ${version.canUpdate?'':'d-hide'}" appid="${app.id}" title="Update App"><i class="icon icon-refresh"></i></button>
|
<button class="btn btn-link btn-action btn-lg ${version.canUpdate?'':'d-hide'}" appid="${app.id}" title="Update App"><i class="icon icon-refresh"></i></button>
|
||||||
<button class="btn btn-link btn-action btn-lg" appid="${app.id}" title="Remove App"><i class="icon icon-delete"></i></button>
|
<button class="btn btn-link btn-action btn-lg" appid="${app.id}" title="Remove App"><i class="icon icon-delete"></i></button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -328,6 +387,7 @@ return `<div class="tile column col-6 col-sm-12 col-xs-12">
|
||||||
// check icon to figure out what we should do
|
// check icon to figure out what we should do
|
||||||
if (icon.classList.contains("icon-delete")) removeApp(app);
|
if (icon.classList.contains("icon-delete")) removeApp(app);
|
||||||
if (icon.classList.contains("icon-refresh")) updateApp(app);
|
if (icon.classList.contains("icon-refresh")) updateApp(app);
|
||||||
|
if (icon.classList.contains("icon-download")) handleAppInterface(app)
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue