Permalink
Branch: master
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
87 lines (69 sloc) 2.43 KB

Countdown Timer

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

View 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)
  }
})

Tthe 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()
}