Skip to content

v1.1.2

Choose a tag to compare

@thebigjoe1 thebigjoe1 released this 11 Aug 11:14
· 3 commits to main since this release
599028f

Patch release. Ten user-visible bug fixes and the latest AI model presets. Community reports + fixes from @backmind on most of these.

Added

  • Latest AI models in the picker. Claude Opus 5 and Claude Fable 5 join the existing Claude Opus 4.8; Sonnet 5 relabeled. Google Gemini 3.x and OpenAI GPT-5.6 added as presets. Existing saved selections keep working.

Fixed

  • The Login and Profile pages no longer render raw i18n keys as UI copy (#33). en.json declared the login and profile top-level sections twice; JSON.parse silently keeps only the last (biometric-only) block, dropping 21 login keys and 34 profile keys at runtime. Both sections now hold every key in one block. Also renamed two Settings sidebar titleKeys that pointed at non-existent keys and were rendering raw: AI Assistant now resolves via settings.trace.section and Backup & Restore via settings.backup.section. Diagnosed by @backmind.
  • Re-importing an exercise catalog no longer duplicates every row (#34). Every seeder used INSERT OR IGNORE against a table with no UNIQUE constraint, so importing free-db (873 rows), Wger, or ExerciseDB a second time silently doubled the whole library. A one-time boot migration merges duplicates (picks the lowest-id row as survivor, folds non-null user edits from duplicates onto it, rewrites exercise_id references inside the JSON blobs in workout_log / workout_templates / coach_prescriptions so past workouts + templates + coach prescriptions keep pointing at the right exercise, then deletes the duplicates), free-db now populates external_id, and a partial UNIQUE index locks in the fix. Full-backup restore force-runs the dedupe pass so a backup taken during the bug can't resurrect duplicates. Diagnosed by @backmind.
  • The All range on Statistics no longer hides body measurements taken before your first workout (#36). The body-weight chart bounded its query by the earliest workout date, but weigh-ins are independent of whether you trained that day. The All range now starts from the same 2000-01-01 floor the code already falls back to when there are no workouts.
  • Logging a cardio session with a distance or a heart rate no longer fails (#41). Both fields are <input type="number">, so the bound value became a number once you typed in them and null once you cleared them; the save path called .trim() on them as if they were still the empty string the form starts with, and threw. Both fields now test for emptiness rather than assuming a string.
  • Quick-log cardio templates now show up (#43). GET /api/cardio/templates was registered below GET /api/cardio/:date, and Express matches in registration order, so the request was answered by the date handler with templates read as a date. Feature has now worked since it was added. Pinning two sessions of the same activity also no longer gives you two identical chips.
  • Pre-caching exercise media for offline use no longer fails with "Exercise not found" (#44). GET /api/exercises/media-urls was registered below GET /api/exercises/:id and hit the id handler. Moved above.
  • Confirmation dialogs with two long button labels no longer overflow the dialog card (#39). .btn carries white-space: nowrap, so a flex item can never shrink below its one-line text width. Action row now wraps.
  • The body stats sheet no longer shows its units in capitals (#42). Field labels are uppercased by CSS, which took the unit along with the name and produced WEIGHT (KG), WAIST (CM). Unit symbols are case-sensitive: kg is kilograms, KG is not a unit. The symbol now opts out of the transform.
  • Weight placeholders in the workout editor and the plate calculator now follow the kg/lb setting. Both hard-coded pound examples (e.g. 135, e.g. 225) regardless of preference.
  • The rest field in the workout editor now reads REST (s) instead of REST (S). S is siemens; seconds is s.
  • Pull-to-refresh no longer fires mid-page on editor screens. The gesture gated on window.scrollY, but editor pages use their own scroll container. It now walks to the nearest actually-scrolling ancestor and gates on that.

services:
  lifttrace:
    image: ghcr.io/traceapps/lifttrace:latest
    #