rep: incrementing counter

master
Rob Pilling 2023-05-18 22:39:11 +01:00
parent b4e5e8e1df
commit 223fc5087b
1 changed files with 104 additions and 64 deletions

View File

@ -1,57 +1,70 @@
// TODO: buzz on stage change, better setTimeout() // TODO: buzz on stage change, better setTimeout()
// TODO: fastload: scoping, unregister layout handlers etc // TODO: fastload: scoping, unregister layout handlers etc
// TODO: spaces vs tabs
// TODO: const colfg=g.theme.fg, colbg=g.theme.bg;
const Layout = require("Layout"); const Layout = require("Layout");
const entries /*: {dur: number, label: string}[]*/ = [ type Rep = {
// 1 X 4 mins - 4 min jog recovery dur: number,
// 2 X 2 mins - 2 min jog recoveries label: string,
// 4 X 1 min - 1 min jog recoveries (turn for home after the 2nd minute) };
// 8 X 30 secs - 30 sec jog recoveries
const reps: Rep[] = [
// 1 X 4 mins - 4 min recovery
// 2 X 2 mins - 2 min recoveries
// 4 X 1 min - 1 min recoveries (turn for home after the 2nd minute)
// 8 X 30 secs - 30 sec recoveries
// 3 min static recovery // 3 min static recovery
// 1 X 4 mins to finish // 1 X 4 mins to finish
{dur:1/60, label:"1st-sec"},
{dur:5/60, label:"5-sec"},
{dur:4, label:"jog"}, {dur:4, label:"jog"},
{dur:4, label:"jog recovery"}, {dur:4, label:"recovery"},
{dur:2, label:"jog"}, {dur:2, label:"jog"},
{dur:2, label:"jog recovery"}, {dur:2, label:"recovery"},
{dur:2, label:"jog"}, {dur:2, label:"jog"},
{dur:2, label:"jog recovery"}, {dur:2, label:"recovery"},
{dur:1, label:"jog"}, {dur:1, label:"jog"},
{dur:1, label:"jog recovery"}, {dur:1, label:"recovery"},
{dur:1, label:"jog"}, {dur:1, label:"jog"},
{dur:1, label:"jog recovery"}, {dur:1, label:"recovery"},
{dur:1, label:"jog"}, {dur:1, label:"jog"},
{dur:1, label:"jog recovery"}, {dur:1, label:"recovery"},
{dur:1, label:"jog"}, {dur:1, label:"jog"},
{dur:1, label:"jog recovery"}, {dur:1, label:"recovery"},
{dur:0.5, label:"jog"}, {dur:0.5, label:"jog recovery"}, {dur:0.5, label:"jog"}, {dur:0.5, label:"recovery"},
{dur:0.5, label:"jog"}, {dur:0.5, label:"jog recovery"}, {dur:0.5, label:"jog"}, {dur:0.5, label:"recovery"},
{dur:0.5, label:"jog"}, {dur:0.5, label:"jog recovery"}, {dur:0.5, label:"jog"}, {dur:0.5, label:"recovery"},
{dur:0.5, label:"jog"}, {dur:0.5, label:"jog recovery"}, {dur:0.5, label:"jog"}, {dur:0.5, label:"recovery"},
{dur:0.5, label:"jog"}, {dur:0.5, label:"jog recovery"}, {dur:0.5, label:"jog"}, {dur:0.5, label:"recovery"},
{dur:0.5, label:"jog"}, {dur:0.5, label:"jog recovery"}, {dur:0.5, label:"jog"}, {dur:0.5, label:"recovery"},
{dur:0.5, label:"jog"}, {dur:0.5, label:"jog recovery"}, {dur:0.5, label:"jog"}, {dur:0.5, label:"recovery"},
{dur:0.5, label:"jog"}, {dur:0.5, label:"jog recovery"}, {dur:0.5, label:"jog"}, {dur:0.5, label:"recovery"},
{dur:3, label:"static recovery"}, {dur:3, label:"static recovery"},
{dur:4, label:"finish"}, {dur:4, label:"finish"},
]; ];
const fontSzMain = 64;
const fontSzRep = 20;
const repLayout = (id: string): (Layout_.Hierarchy & {type:"txt"})[] => [ const repLayout = (id: string): (Layout_.Hierarchy & {type:"txt"})[] => [
{ {
id: `${id}_name`, id: `${id}_name`,
type: "txt", type: "txt",
font: "Vector:30", font: `Vector:${fontSzRep}`,
label: "Name PH", label: "Name PH",
pad: 4, pad: 4,
}, { }, {
id: `${id}_dur`, id: `${id}_dur`,
type: "txt", type: "txt",
font: "Vector:30", font: `Vector:${fontSzRep}`,
label: "DURATION", label: "DURATION",
pad: 4, pad: 4,
} }
@ -65,16 +78,16 @@ const layout = new Layout({
type: "v", type: "v",
c: [ c: [
{ {
type: "h", id: "cur_time",
c: repLayout("cur"), type: "txt",
font: `Vector:${fontSzMain}` as FontNameWithScaleFactor, // modified in draw
label: "MM:SS", // TODO: empty strings
fillx: 1,
filly: 1, filly: 1,
}, },
{ {
id: "cur_time", type: "h",
type: "txt", c: repLayout("cur"),
font: "Vector:40", // FIXME: bigger
label: "MM:SS", // TODO: empty strings
fillx: 1,
filly: 1, filly: 1,
}, },
{ {
@ -85,8 +98,10 @@ const layout = new Layout({
{ {
type: "h", type: "h",
c: [{ c: [{
id: "play",
type: "btn", type: "btn",
label: "Play", // TODO: change label: "Play", // TODO: change
fillx: 1,
cb: () => { cb: () => {
console.log("cb()"); console.log("cb()");
}, },
@ -97,22 +112,72 @@ const layout = new Layout({
}, {lazy: true}); }, {lazy: true});
let index = 0; let index = 0;
let begin: Date | undefined; let begin: number | undefined = Date.now(); // TODO: start null
let drawTimeout: number | undefined; let drawTimeout: number | undefined;
let paused = true; let paused = false;
let positioned = false; let positioned = false;
const pad2 = (s: number) => ('0' + s.toFixed(0)).slice(-2); const pad2 = (s: number) => ('0' + s.toFixed(0)).slice(-2);
const currentRepIndex = (elapsedMs: number) => {
let total = 0;
let ent;
for(let i = 0; ent = reps[i]; i++){
total += ent.dur * 60 * 1000;
if(elapsedMs < total)
return i;
}
return null;
};
const repToLabel = (i: number, id: string) => {
const rep = reps[i];
if(rep){
layout[`${id}_name`]!.label = `${i+1}: ${rep.label}`;
layout[`${id}_dur`]!.label = `${rep.dur}m`;
}else{
emptyLabel(id);
}
};
const emptyLabel = (id: string) => {
layout[`${id}_name`]!.label = "<none>";
layout[`${id}_dur`]!.label = `0m`;
};
const drawRep = () => { const drawRep = () => {
if(paused || !begin){ // TODO: separate case for paused
layout.clear();
layout["cur_time"]!.label = "Ready";
if(!positioned){
positioned = true;
layout.update(); // position
}
layout.render(layout["play"]);
layout.render(layout["cur_time"]);
return;
}
// TODO: layout.clear(layout.next_name); layout.render(layout.next_name) // TODO: layout.clear(layout.next_name); layout.render(layout.next_name)
layout["next_name"]!.label = "next"; const now = Date.now();
layout["next_dur"]!.label = `${30}`;
layout["cur_name"]!.label = "next";
layout["cur_dur"]!.label = `${30}`;
layout["cur_time"]!.label = "1:23"; const elapsed = now - begin;
const sec = Math.round(elapsed / 1000);
const min = Math.round(sec / 60);
const timeStr = min.toFixed(0) + ":" + pad2(sec % 60);
layout["cur_time"]!.label = timeStr;
const i = currentRepIndex(elapsed);
if(i !== null){
repToLabel(i, "cur");
repToLabel(i+1, "next");
}else{
emptyLabel("cur");
emptyLabel("next");
}
if(!positioned){ if(!positioned){
positioned = true; positioned = true;
@ -121,28 +186,8 @@ const drawRep = () => {
layout.render(); layout.render();
/* /*
const x = g.getWidth() / 2;
const y = g.getHeight() / 2;
const now = new Date();
const elapsed = now.getDate() - begin.getDate();
const sec = Math.round(elapsed / 1000) % 60;
const min = Math.round(sec / 60);
const timeStr = min + ":" + pad2(sec);
let current;
let i;
let total = 0;
for(i = 0; entries[i]; i++){
const ent = entries[i];
total += ent.dur;
if(total > elapsed)
break;
current = ent;
}
g.reset() g.reset()
.clearRect(Bangle.appRect) .clearRect(Bangle.appRect)
.setFontAlign(0, 0) .setFontAlign(0, 0)
@ -151,23 +196,18 @@ const drawRep = () => {
.setFont("Vector", 33) .setFont("Vector", 33)
.drawString(current ? current.label + " for " + current.dur : "<done>", x, y+48); .drawString(current ? current.label + " for " + current.dur : "<done>", x, y+48);
// TODO: figure out next rep change time? or every 5s, then countdown from 10-->0
if (drawTimeout) clearTimeout(drawTimeout); if (drawTimeout) clearTimeout(drawTimeout);
drawTimeout = setTimeout(function() { drawTimeout = setTimeout(function() {
drawTimeout = undefined; drawTimeout = undefined;
drawRep(); drawRep();
}, 1000 - (Date.now() % 1000)); }, 1000 - (Date.now() % 1000));
if(paused){
g.reset()
.clearRect(Bangle.appRect)
.setFontAlign(0, 0)
.setFont("Vector", 55)
.drawString("Start", g.getWidth() / 2, g.getHeight() / 2);
}
*/ */
}; };
g.clear(); g.clear();
var drawInterval = setInterval(drawRep, 1000);
drawRep(); drawRep();
// TODO: widgets // TODO: widgets