Skip to content

Latest commit

 

History

History
86 lines (69 loc) · 2.42 KB

countdown-timer.md

File metadata and controls

86 lines (69 loc) · 2.42 KB

Countdown Timer

In this section we'll walk through a countdown timer example and learn how to use events.loaded to register global events.

Try it online

const pad = n => (n < 10 ? "0" + n : n)

const humanizeTime = t => {
  const hours = (t / 3600) >> 0
  const minutes = ((t - hours * 3600) / 60) >> 0
  const seconds = (t - hours * 3600 - minutes * 60) >> 0
  return `${hours} : ${pad(minutes)} : ${pad(seconds)}`
}

const SECONDS = 5

app({
  state: {
    count: SECONDS,
    paused: true
  },
  view: (state, actions) => (
    <main>
      <h1>{humanizeTime(state.count)}</h1>

      <button onclick={actions.toggle}>
        {state.paused ? "Start" : "paused"}
      </button>

      <button onclick={actions.reset}>Reset</button>
    </main>
  ),
  actions: {
    toggle: state => ({ paused: !state.paused }),
    reset: state => ({ count: SECONDS }),
    drop: state => ({ count: state.count - 1 }),
    tick: (state, actions) => {
      if (state.count === 0) {
        actions.reset()
        actions.toggle()
      } else if (!state.paused) {
        actions.drop()
      }
    }
  },
  events: {
    loaded: (state, actions) => setInterval(actions.tick, 1000)
  }
})

The state consists of count, a number to track the seconds elapsed; and paused, a boolean to check if the clock is running or not.

state: {
  count: SECONDS,
  paused: true
}

The view displays the current count wrapped in a <h1> element and binds two buttons to actions.toggle and actions.reset respectively.

There's also some logic in humanizeTime to display the time in a familiar format like hh:mm:ss.

The clock is implemented using setInterval that calls actions.tick on every second.

events: {
  loaded: (state, actions) => setInterval(actions.tick, 1000)
}

Inside tick, we check the current count to see if it has reached zero, and when it does, reset the counter back to SECONDS and toggle the running clock.

If state.count is greater than zero and the clock is not paused, we decrement the count by one.

if (state.count === 0) {
  actions.reset()
  actions.toggle()
} else if (!state.paused) {
  actions.drop()
}