40 lines
1.6 KiB
JavaScript
40 lines
1.6 KiB
JavaScript
/* Delegation survives HTMX swaps; all readout values are plain text. */
|
|
(() => {
|
|
if (window.workoutForecastEvents) return;
|
|
window.workoutForecastEvents = true;
|
|
function inspect(hit) {
|
|
const panel = hit.closest('.exercise-progress');
|
|
if (!panel) return;
|
|
for (const key of ['kind', 'date', 'e1rm', 'topset', 'range']) {
|
|
const field = panel.querySelector(`[data-readout="${key}"]`);
|
|
if (field) field.textContent = hit.dataset[key];
|
|
}
|
|
const cursor = panel.querySelector('.forecast-cursor');
|
|
if (cursor) {
|
|
cursor.setAttribute('x1', hit.dataset.position);
|
|
cursor.setAttribute('x2', hit.dataset.position);
|
|
}
|
|
panel.querySelectorAll('.forecast-hit').forEach(p => p.removeAttribute('data-selected'));
|
|
hit.dataset.selected = 'true';
|
|
}
|
|
for (const event of ['pointerover', 'click']) {
|
|
document.addEventListener(event, e => {
|
|
const hit = e.target.closest?.('.forecast-hit');
|
|
if (hit) inspect(hit);
|
|
});
|
|
}
|
|
document.addEventListener('keydown', e => {
|
|
if (!e.target.matches?.('.forecast-chart') || !['ArrowLeft', 'ArrowRight', 'Home', 'End'].includes(e.key)) return;
|
|
const hits = [...e.target.querySelectorAll('.forecast-hit')];
|
|
if (!hits.length) return;
|
|
let index = hits.findIndex(p => p.dataset.selected);
|
|
if (index < 0) {
|
|
index = hits.findIndex(p => p.dataset.kind === 'Current reading');
|
|
if (index < 0) index = hits.length - 1;
|
|
}
|
|
index = e.key === 'Home' ? 0 : e.key === 'End' ? hits.length - 1 : Math.max(0, Math.min(hits.length - 1, index + (e.key === 'ArrowRight' ? 1 : -1)));
|
|
e.preventDefault();
|
|
inspect(hits[index]);
|
|
});
|
|
})();
|