0.16: Added ability to resume a run that was stopped previously (fix #1907)

pull/2770/head
Gordon Williams 2023-05-19 16:16:19 +01:00
parent 3ffce610e8
commit 625f31c8d4
4 changed files with 50 additions and 32 deletions

View File

@ -14,3 +14,4 @@
0.13: Revert #1578 (stop duplicate entries) as with 2v12 menus it causes other boxes to be wiped (fix #1643) 0.13: Revert #1578 (stop duplicate entries) as with 2v12 menus it causes other boxes to be wiped (fix #1643)
0.14: Fix Bangle.js 1 issue where after the 'overwrite track' menu, the start/stop button stopped working 0.14: Fix Bangle.js 1 issue where after the 'overwrite track' menu, the start/stop button stopped working
0.15: Keep run state between runs (allowing you to exit and restart the app) 0.15: Keep run state between runs (allowing you to exit and restart the app)
0.16: Added ability to resume a run that was stopped previously (fix #1907)

View File

@ -51,7 +51,18 @@ function setStatus(running) {
// Called to start/stop running // Called to start/stop running
function onStartStop() { function onStartStop() {
var running = !exs.state.active; var running = !exs.state.active;
var prepPromises = []; var shouldResume = false;
var promise = Promise.resolve();
if (running && exs.state.duration > 10000) { // if more than 10 seconds of duration, ask if we should resume?
promise = promise.
then(() => {
isMenuDisplayed = true;
return E.showPrompt("Resume run?",{title:"Run"});
}).then(r => {
isMenuDisplayed=false;shouldResume=r;
});
}
// start/stop recording // start/stop recording
// Do this first in case recorder needs to prompt for // Do this first in case recorder needs to prompt for
@ -59,35 +70,34 @@ function onStartStop() {
if (settings.record && WIDGETS["recorder"]) { if (settings.record && WIDGETS["recorder"]) {
if (running) { if (running) {
isMenuDisplayed = true; isMenuDisplayed = true;
prepPromises.push( promise = promise.
WIDGETS["recorder"].setRecording(true).then(() => { then(() => WIDGETS["recorder"].setRecording(true)).
then(() => {
isMenuDisplayed = false; isMenuDisplayed = false;
layout.setUI(); // grab our input handling again layout.setUI(); // grab our input handling again
layout.forgetLazyState(); layout.forgetLazyState();
layout.render(); layout.render();
}) });
);
} else { } else {
prepPromises.push( promise = promise.then(
WIDGETS["recorder"].setRecording(false) () => WIDGETS["recorder"].setRecording(false)
); );
} }
} }
if (!prepPromises.length) // fix for Promise.all bug in 2v12 promise = promise.then(() => {
prepPromises.push(Promise.resolve()); if (running) {
if (shouldResume)
Promise.all(prepPromises) exs.resume()
.then(() => { else
if (running) {
exs.start(); exs.start();
} else { } else {
exs.stop(); exs.stop();
} }
// if stopping running, don't clear state // if stopping running, don't clear state
// so we can at least refer to what we've done // so we can at least refer to what we've done
setStatus(running); setStatus(running);
}); });
} }
var lc = []; var lc = [];

View File

@ -1,6 +1,6 @@
{ "id": "run", { "id": "run",
"name": "Run", "name": "Run",
"version":"0.15", "version":"0.16",
"description": "Displays distance, time, steps, cadence, pace and more for runners.", "description": "Displays distance, time, steps, cadence, pace and more for runners.",
"icon": "app.png", "icon": "app.png",
"tags": "run,running,fitness,outdoors,gps", "tags": "run,running,fitness,outdoors,gps",

View File

@ -61,7 +61,9 @@ E.showMenu(menu);
*/ */
var state = { var state = {
active : false, // are we working or not? active : false, // are we working or not?
// startTime, // time exercise started // startTime, // time exercise started (in ms from 1970)
// lastTime, // time we had our last reading (in ms from 1970)
duration : 0, // the length of this exercise (in ms)
lastGPS:{}, thisGPS:{}, // This & previous GPS readings lastGPS:{}, thisGPS:{}, // This & previous GPS readings
// distance : 0, ///< distance in meters // distance : 0, ///< distance in meters
// avrSpeed : 0, ///< speed over whole run in m/sec // avrSpeed : 0, ///< speed over whole run in m/sec
@ -146,8 +148,7 @@ Bangle.on("GPS", function(fix) {
if (state.lastGPS.fix) if (state.lastGPS.fix)
state.distance += calcDistance(state.lastGPS, fix); state.distance += calcDistance(state.lastGPS, fix);
if (stats["dist"]) stats["dist"].emit("changed",stats["dist"]); if (stats["dist"]) stats["dist"].emit("changed",stats["dist"]);
var duration = Date.now() - state.startTime; // in ms state.avrSpeed = state.distance * 1000 / state.duration; // meters/sec
state.avrSpeed = state.distance * 1000 / duration; // meters/sec
if (!isNaN(fix.speed)) state.curSpeed = state.curSpeed*0.8 + fix.speed*0.2/3.6; // meters/sec if (!isNaN(fix.speed)) state.curSpeed = state.curSpeed*0.8 + fix.speed*0.2/3.6; // meters/sec
if (stats["pacea"]) stats["pacea"].emit("changed",stats["pacea"]); if (stats["pacea"]) stats["pacea"].emit("changed",stats["pacea"]);
if (stats["pacec"]) stats["pacec"].emit("changed",stats["pacec"]); if (stats["pacec"]) stats["pacec"].emit("changed",stats["pacec"]);
@ -160,8 +161,8 @@ Bangle.on("GPS", function(fix) {
Bangle.on("step", function(steps) { Bangle.on("step", function(steps) {
if (!state.active) return; if (!state.active) return;
if (stats["step"]) stats["step"].emit("changed",stats["step"]); if (stats["step"]) stats["step"].emit("changed",stats["step"]);
state.stepHistory[0] += steps-state.lastStepCount; state.stepHistory[0] += steps-state.lastSteps;
state.lastStepCount = steps; state.lastSteps = steps;
if (state.notify.step.increment > 0 && state.notify.step.next <= steps) { if (state.notify.step.increment > 0 && state.notify.step.next <= steps) {
stats["step"].emit("notify",stats["step"]); stats["step"].emit("notify",stats["step"]);
state.notify.step.next = state.notify.step.next + state.notify.step.increment; state.notify.step.next = state.notify.step.next + state.notify.step.increment;
@ -325,9 +326,10 @@ exports.getStats = function(statIDs, options) {
if (!state.active) return; if (!state.active) return;
// called once a second // called once a second
var now = Date.now(); var now = Date.now();
var duration = now - state.startTime; // in ms state.duration += now - state.lastTime; // in ms
state.lastTime = now;
// set cadence -> steps over last minute // set cadence -> steps over last minute
state.stepsPerMin = Math.round(60000 * E.sum(state.stepHistory) / Math.min(duration,60000)); state.stepsPerMin = Math.round(60000 * E.sum(state.stepHistory) / Math.min(state.duration,60000));
if (stats["caden"]) stats["caden"].emit("changed",stats["caden"]); if (stats["caden"]) stats["caden"].emit("changed",stats["caden"]);
// move step history onwards // move step history onwards
state.stepHistory.set(state.stepHistory,1); state.stepHistory.set(state.stepHistory,1);
@ -345,9 +347,9 @@ exports.getStats = function(statIDs, options) {
} }
}, 1000); }, 1000);
function reset() { function reset() {
state.startTime = Date.now(); state.startTime = state.lastTime = Date.now();
state.duration = 0;
state.startSteps = state.lastSteps = Bangle.getStepCount(); state.startSteps = state.lastSteps = Bangle.getStepCount();
state.lastSteps = 0;
state.stepHistory.fill(0); state.stepHistory.fill(0);
state.stepsPerMin = 0; state.stepsPerMin = 0;
state.distance = 0; state.distance = 0;
@ -374,12 +376,17 @@ exports.getStats = function(statIDs, options) {
stats : stats, stats : stats,
state : state, state : state,
start : function() { start : function() {
state.active = true;
reset(); reset();
state.active = true;
}, },
stop : function() { stop : function() {
state.active = false; state.active = false;
} },
resume : function() {
state.lastTime = Date.now();
state.lastSteps = Bangle.getStepCount()
state.active = true;
},
}; };
}; };