feat(webapp): +/- sign toggle on weight input (feedback #9)

iOS numeric keypad has no minus key, so users couldn't enter
negative weights for assisted bodyweight exercises (e.g. -20 kg
assisted pull-ups).

Added a small +/- button next to the weight input that flips the
sign of whatever's there (or seeds a lone "-" when the field is
empty so the user can type digits after it). Active state lights
up the button so you can see at a glance that the value is
negative. Parses and stores as a negative REAL in SQLite; existing
display code (fmtWeight) already handles negative numbers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Danny 2026-04-23 15:36:21 +02:00
parent a127cc8f82
commit 9673bcbb7c
3 changed files with 49 additions and 0 deletions

View file

@ -268,6 +268,7 @@ const setsLabel = document.getElementById("sets-label");
const setsList = document.getElementById("sets-list");
const repsInput = document.getElementById("inp-reps");
const weightInput = document.getElementById("inp-weight");
const btnWeightSign = document.getElementById("btn-weight-sign");
const btnAddSet = document.getElementById("btn-add-set");
const btnSaveWorkout = document.getElementById("btn-save-workout");
const workoutExercises = document.getElementById("workout-exercises");
@ -351,6 +352,7 @@ function startExercise(name) {
nameInput.value = "";
repsInput.value = "";
weightInput.value = "";
syncWeightSignUI();
repsInput.focus();
notesSection.classList.remove("hidden");
stopRestTimer();
@ -420,6 +422,7 @@ function addSet() {
repsInput.value = "";
weightInput.value = weight ? String(weight) : "";
syncWeightSignUI();
repsInput.focus();
tg.HapticFeedback.impactOccurred("light");
saveDraft();
@ -427,6 +430,30 @@ function addSet() {
btnAddSet.addEventListener("click", addSet);
function syncWeightSignUI() {
const v = weightInput.value.trim();
const negative = v.startsWith("-");
btnWeightSign.classList.toggle("active", negative);
}
btnWeightSign.addEventListener("click", () => {
// Flip the sign of the current weight value. If empty, start with "-"
// so the user can type digits after it (iOS numeric keypad has no minus).
const v = weightInput.value.trim();
if (v === "" || v === "-") {
weightInput.value = v === "-" ? "" : "-";
} else if (v.startsWith("-")) {
weightInput.value = v.slice(1);
} else {
weightInput.value = "-" + v;
}
syncWeightSignUI();
weightInput.focus();
tg.HapticFeedback.selectionChanged();
});
weightInput.addEventListener("input", syncWeightSignUI);
repsInput.addEventListener("keydown", (e) => {
if (e.key === "Enter") {
e.preventDefault();
@ -561,6 +588,7 @@ function editExercise(idx) {
// Pre-fill weight input with last set's weight for convenience
const lastWeight = ex.sets_detail?.length ? ex.sets_detail[ex.sets_detail.length - 1].weight_kg : 0;
weightInput.value = lastWeight ? String(lastWeight) : "";
syncWeightSignUI();
repsInput.value = "";
repsInput.focus();

View file

@ -42,6 +42,7 @@
<input type="text" id="inp-reps" class="input input-small" placeholder="Reps" inputmode="numeric" pattern="[0-9]*" />
<span class="set-separator">x</span>
<input type="text" id="inp-weight" class="input input-small" placeholder="kg" inputmode="decimal" />
<button id="btn-weight-sign" class="btn-sign" title="Flip sign (for assisted exercises)" type="button">&plusmn;</button>
<button id="btn-add-set" class="btn-icon" title="Add set">+</button>
</div>
</div>

View file

@ -107,6 +107,26 @@ body {
.btn-icon:active { opacity: 0.7; }
.btn-sign {
width: 36px;
height: 44px;
border-radius: 10px;
border: 1px solid var(--tg-theme-hint-color, #999)55;
background: var(--tg-theme-secondary-bg-color, #f0f0f0);
color: var(--tg-theme-text-color, #000);
font-size: 18px;
cursor: pointer;
flex-shrink: 0;
}
.btn-sign:active { opacity: 0.6; }
.btn-sign.active {
background: var(--tg-theme-button-color, #3390ec);
color: var(--tg-theme-button-text-color, #fff);
border-color: var(--tg-theme-button-color, #3390ec);
}
.btn-link {
background: none;
border: none;