Skip to content

Commit 4e7c358

Browse files
Improve Echo builder UX and printing (#77) (#78)
1 parent 2a08678 commit 4e7c358

1 file changed

Lines changed: 105 additions & 69 deletions

File tree

js/builder.js

Lines changed: 105 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,9 @@ const createEntryFromPlanItem = (item, index) => {
791791
typeof setData.stopAtTop === 'boolean'
792792
? setData.stopAtTop
793793
: Boolean(item?.stopAtTop);
794+
if (set.mode === 'ECHO') {
795+
set.stopAtTop = false;
796+
}
794797
applyStoredProgressionConfig(set, setData, item);
795798
return set;
796799
};
@@ -974,14 +977,17 @@ export const loadPlanIntoBuilder = (planItems = [], options = {}) => {
974977
set.justLift =
975978
typeof setData.justLift === 'boolean'
976979
? setData.justLift
977-
: Boolean(item?.justLift);
978-
set.stopAtTop =
979-
typeof setData.stopAtTop === 'boolean'
980-
? setData.stopAtTop
981-
: Boolean(item?.stopAtTop);
982-
983-
return set;
984-
});
980+
: Boolean(item?.justLift);
981+
set.stopAtTop =
982+
typeof setData.stopAtTop === 'boolean'
983+
? setData.stopAtTop
984+
: Boolean(item?.stopAtTop);
985+
if (set.mode === 'ECHO') {
986+
set.stopAtTop = false;
987+
}
988+
989+
return set;
990+
});
985991

986992
const sets = sortedSets.length ? sortedSets : [createSet()];
987993

@@ -1146,10 +1152,13 @@ export const renderSetRow = (exerciseId, set, index) => {
11461152
if (typeof set.justLift !== 'boolean') {
11471153
set.justLift = set.justLift === true || set.justLift === 'true' || set.justLift === 1 || set.justLift === '1';
11481154
}
1149-
if (typeof set.stopAtTop !== 'boolean') {
1150-
set.stopAtTop =
1151-
set.stopAtTop === true || set.stopAtTop === 'true' || set.stopAtTop === 1 || set.stopAtTop === '1';
1152-
}
1155+
if (typeof set.stopAtTop !== 'boolean') {
1156+
set.stopAtTop =
1157+
set.stopAtTop === true || set.stopAtTop === 'true' || set.stopAtTop === 1 || set.stopAtTop === '1';
1158+
}
1159+
if (set.mode === 'ECHO') {
1160+
set.stopAtTop = false;
1161+
}
11531162

11541163
const setCell = document.createElement('td');
11551164
setCell.textContent = index + 1;
@@ -1445,20 +1454,24 @@ export const renderSetRow = (exerciseId, set, index) => {
14451454
justLiftNote.textContent = 'Always on in Echo Mode';
14461455
justLiftCell.append(justLiftWrapper, justLiftNote);
14471456

1448-
const stopAtTopCell = document.createElement('td');
1449-
stopAtTopCell.className = 'set-flag';
1450-
const stopAtTopWrapper = document.createElement('div');
1451-
stopAtTopWrapper.className = 'flag-control';
1452-
const stopAtTopCheckbox = document.createElement('input');
1453-
stopAtTopCheckbox.type = 'checkbox';
1454-
stopAtTopCheckbox.checked = Boolean(set.stopAtTop);
1455-
stopAtTopCheckbox.setAttribute('aria-label', 'Stop at the top of your final rep');
1456-
stopAtTopCheckbox.addEventListener('change', () => {
1457-
set.stopAtTop = stopAtTopCheckbox.checked;
1458-
persistState();
1459-
});
1460-
stopAtTopWrapper.appendChild(stopAtTopCheckbox);
1461-
stopAtTopCell.appendChild(stopAtTopWrapper);
1457+
const stopAtTopCell = document.createElement('td');
1458+
stopAtTopCell.className = 'set-flag';
1459+
const stopAtTopWrapper = document.createElement('div');
1460+
stopAtTopWrapper.className = 'flag-control';
1461+
const stopAtTopCheckbox = document.createElement('input');
1462+
stopAtTopCheckbox.type = 'checkbox';
1463+
stopAtTopCheckbox.checked = Boolean(set.stopAtTop);
1464+
stopAtTopCheckbox.setAttribute('aria-label', 'Stop at the top of your final rep');
1465+
stopAtTopCheckbox.addEventListener('change', () => {
1466+
set.stopAtTop = stopAtTopCheckbox.checked;
1467+
persistState();
1468+
});
1469+
stopAtTopWrapper.appendChild(stopAtTopCheckbox);
1470+
const stopAtTopNote = document.createElement('div');
1471+
stopAtTopNote.className = 'flag-note muted small';
1472+
stopAtTopNote.textContent = 'Disabled in Echo Mode';
1473+
stopAtTopNote.style.display = 'none';
1474+
stopAtTopCell.append(stopAtTopWrapper, stopAtTopNote);
14621475

14631476
const updateWeightVisibility = () => {
14641477
const isEcho = set.mode === 'ECHO';
@@ -1491,25 +1504,41 @@ export const renderSetRow = (exerciseId, set, index) => {
14911504
eccentricWrapper.style.display = isEcho ? '' : 'none';
14921505
};
14931506

1494-
const updateJustLiftControl = () => {
1495-
const isEcho = set.mode === 'ECHO';
1496-
justLiftWrapper.style.display = isEcho ? 'none' : '';
1497-
justLiftCheckbox.disabled = isEcho;
1498-
justLiftNote.style.display = isEcho ? '' : 'none';
1499-
};
1500-
1501-
modeSelect.addEventListener('change', () => {
1502-
set.mode = modeSelect.value;
1503-
if (set.mode === 'ECHO' && !Number.isFinite(Number.parseInt(set.eccentricPct, 10))) {
1504-
set.eccentricPct = 100;
1505-
}
1506-
persistState();
1507-
triggerRender();
1508-
});
1509-
1510-
updateWeightVisibility();
1511-
updateRepEditor();
1512-
updateJustLiftControl();
1507+
const updateJustLiftControl = () => {
1508+
const isEcho = set.mode === 'ECHO';
1509+
justLiftWrapper.style.display = isEcho ? 'none' : '';
1510+
justLiftCheckbox.disabled = isEcho;
1511+
justLiftNote.style.display = isEcho ? '' : 'none';
1512+
};
1513+
1514+
const updateStopAtTopControl = () => {
1515+
const isEcho = set.mode === 'ECHO';
1516+
stopAtTopWrapper.style.display = isEcho ? 'none' : '';
1517+
stopAtTopCheckbox.disabled = isEcho;
1518+
stopAtTopNote.style.display = isEcho ? '' : 'none';
1519+
if (isEcho && set.stopAtTop) {
1520+
set.stopAtTop = false;
1521+
stopAtTopCheckbox.checked = false;
1522+
}
1523+
};
1524+
1525+
modeSelect.addEventListener('change', () => {
1526+
set.mode = modeSelect.value;
1527+
if (set.mode === 'ECHO' && !Number.isFinite(Number.parseInt(set.eccentricPct, 10))) {
1528+
set.eccentricPct = 100;
1529+
}
1530+
if (set.mode === 'ECHO' && set.stopAtTop) {
1531+
set.stopAtTop = false;
1532+
stopAtTopCheckbox.checked = false;
1533+
}
1534+
persistState();
1535+
triggerRender();
1536+
});
1537+
1538+
updateWeightVisibility();
1539+
updateRepEditor();
1540+
updateJustLiftControl();
1541+
updateStopAtTopControl();
15131542

15141543
const actionsCell = document.createElement('td');
15151544
actionsCell.className = 'set-actions';
@@ -2030,16 +2059,21 @@ export const printWorkout = () => {
20302059
</section>`;
20312060
}).join('');
20322061

2033-
const printHtml = `<!doctype html><html><head><meta charset="utf-8"><title>Workout</title>
2034-
<style>
2035-
body { font-family: Arial, sans-serif; padding: 24px; color: #111; }
2036-
h1 { margin-bottom: 8px; }
2037-
section { margin-bottom: 24px; }
2038-
table { width: 100%; border-collapse: collapse; }
2039-
th, td { border: 1px solid #ccc; padding: 6px 8px; text-align: left; }
2040-
th { background: #f4f4f4; }
2041-
</style>
2042-
</head><body>
2062+
const printHtml = `<!doctype html><html><head><meta charset="utf-8"><title>Workout</title>
2063+
<style>
2064+
@page {
2065+
size: landscape;
2066+
margin: 0.5in;
2067+
}
2068+
body { font-family: Arial, sans-serif; padding: 24px; color: #111; }
2069+
h1 { margin-bottom: 8px; }
2070+
section { margin-bottom: 24px; page-break-inside: avoid; }
2071+
section table { margin-top: 8px; }
2072+
table { width: 100%; border-collapse: collapse; table-layout: fixed; }
2073+
th, td { border: 1px solid #ccc; padding: 6px 8px; text-align: left; vertical-align: top; white-space: normal; word-break: break-word; overflow-wrap: anywhere; }
2074+
th { background: #f4f4f4; }
2075+
</style>
2076+
</head><body>
20432077
<h1>Workout Plan</h1>
20442078
<p>Generated ${new Date().toLocaleString()}</p>
20452079
${sections}
@@ -2693,20 +2727,22 @@ const buildBuilderCard = (entry, displayIndex, options = {}) => {
26932727
quickSelect.value = '';
26942728
};
26952729

2696-
quickSelect.addEventListener('change', () => {
2697-
const chosen = quickSelect.value;
2698-
if (!chosen) return;
2699-
entry.sets.forEach((set) => {
2700-
if (activeQuickMode === PROGRESSION_MODES.PERCENT) {
2701-
set.progressionPercent = chosen;
2702-
set.progressionMode = PROGRESSION_MODES.PERCENT;
2703-
} else {
2704-
set.progression = chosen;
2705-
set.progressionMode = PROGRESSION_MODES.FLAT;
2706-
}
2707-
});
2708-
quickSelect.value = '';
2709-
persistState();
2730+
quickSelect.addEventListener('change', () => {
2731+
const chosen = quickSelect.value;
2732+
if (!chosen) return;
2733+
entry.sets.forEach((set) => {
2734+
if (activeQuickMode === PROGRESSION_MODES.PERCENT) {
2735+
set.progressionPercent = chosen;
2736+
set.overloadValue = '';
2737+
set.progressionMode = PROGRESSION_MODES.PERCENT;
2738+
} else {
2739+
set.overloadValue = chosen;
2740+
set.progressionPercent = '';
2741+
set.progressionMode = PROGRESSION_MODES.FLAT;
2742+
}
2743+
});
2744+
quickSelect.value = '';
2745+
persistState();
27102746
triggerRender();
27112747
});
27122748

0 commit comments

Comments
 (0)