Show HN: Programmable timer web app (for gym workouts or stretching sessions) (timer.jotaen.net)

30 points by jotaen ↗ HN
Over the last couple of months, I’ve been building a timer web app for myself that I use for workout and stretching sessions. My main use-case is gym routines that consist of repeatable sequences, e.g. where you are holding certain positions for a set time (rinse and repeat). The app counts down the program, beeps, and reads the activities out loud.

Two things (I suppose) are special about it:

- The timers are “programmable”, so you can freely express your own routines and procedures in a declarative notation.

- The app is all static (no backend): the entire program is encoded in the URL and can be bookmarked or shared/transferred via QR-code.

You can check it out at https://timer.jotaen.net, optionally with a demo program pre-loaded: https://timer.jotaen.net/#demo.

Source code is at https://github.com/jotaen/timer. I’ve also written up a small behind-the-scenes on my blog: https://www.jotaen.net/SAKxq

9 comments

[ 0.32 ms ] story [ 7.0 ms ] thread
My first reaction to this before clicking the link: why would anyone want a programmable timer?

After clicking the link and seeing the demo: man, I’ve always wanted a programmable timer.

This is awesome, can see myself using this for workouts and focus sessions. Thank you for sharing.

I’m wondering whether anything could be done in terms of name/“tagline” to clarify this? (Or maybe this is just a peculiar niche?)
Oh that's pretty cool! I also like how you can bookmark timers to save them and then keep a list of them for various activities/purposes.

Also when I saw the HN post I knew something was familiar and I remembered an old project of yours: x[it]!

From time to time I still think about that one. Are you still engaging with x[it] or have you moved on in a sense?

Nice work! Love it.
I love the declarative syntax, and it makes me wonder if there is a use case for a timeline-based scripting language.

Functions, variables, data structures... Intervals (timers) as a first-class citizen - an actual keyword "timer"[1] that works like const or let.

Anyway, this is really cool.

[1] Where are my VB6 devs??

Tested, browsed to another tab, switched to another app, turned off screen. Are there any limitations compared to a native app?

It needs an example of nested loop and skipping last item, with comments.

nice work … would love to have this on my apul watch
Years ago, I wrote something similar but simpler and non-programmable using Pith (JS with Python-like syntax).

https://gabrielsroka.github.io/webpages/pith.html

  cancel = false
  editor.style.display = 'none'
  debug.hide()
  btn = button('Stop', 'cancel=true id=stopBtn')
  bar.html(btn)
  beep = new Audio('beep.mp3')
  lock = await navigator.wakeLock.request('screen')
  stopBtn.style.fontSize = runProgram.style.fontSize = results.style.fontSize = '72px'
  
  wus = 'roll shoulders,arm circles,arm hugs,knee raises,rotate torso,rotate hips'
  wus = wus.split(',')
  
  sets = 'march in place,squat,push up,standing bicycle crunch,stand and box,split squat,push up,plank,jumping jacks,wall sit,push up,standing side crunch'
  sets = sets.split(',')
  
  cools = 'walk,hands up,hands forward,hands back,right leg,left leg,right hams,left hams,balance'
  cools = cools.split(',')
  
  await countdown('check volume.', 5, true)
  
  for wu in wus
    await countdown(wu, 12)
  
  await countdown('first up ' + sets[0])
  
  for set in range(sets.length)
    msg = (set + 1) + '. ' + sets[set]
    await countdown(msg, 30, true)
    if set < sets.length - 1
      await countdown('next up: ' + sets[set + 1])
  
  for cool in cools
    await countdown(cool, 15)
  
  results.html('done')
  lock.release()
  editor.style.display = ''
  
  async def countdown(msg, secs=5, play)
    for s in range(secs)
      results.html(msg + '<br>' + (secs - s))
      if play && secs - s <= 3
        beep.play()
      if cancel
        break
      await sleep(1000)