added stopwatch example

added requestAnimationFrame polyfill

moved raf logic into a subscription

separated logic into multiple files, all state lives in a global namespaced model, reset no longer sends multiple actions only one
This commit is contained in:
traducer
2016-07-13 16:59:20 +00:00
parent a1795c29ee
commit 5f858cfdf5
5 changed files with 120 additions and 0 deletions
+15
View File
@@ -0,0 +1,15 @@
const choo = require('../../')
const stopwatch = require('./models/stopwatch')
const mainView = require('./views/main')
const app = choo()
app.model(stopwatch)
app.router((route) => [
route('/', mainView)
])
const tree = app.start()
document.body.appendChild(tree)
+34
View File
@@ -0,0 +1,34 @@
const xtend = require('xtend')
const raf = require('raf')
module.exports = {
state: {
elapsed: 0,
startTime: 0,
start: false,
laps: []
},
reducers: {
start: (data, state) => xtend(state, { start: true, startTime: Date.now() - state.elapsed }),
stop: (data, state) => xtend(state, { start: false }),
update: (data, state) => xtend(state, { elapsed: data }),
reset: (data, state) => xtend(state, { startTime: Date.now(), elapsed: 0, laps: [] }),
add: (data, state) => xtend(state, { laps: state.laps.concat(data) })
},
effects: {
now: (data, state, send, done) => {
if (state.start) {
let elapsed = data - state.startTime
send('update', elapsed, done)
}
}
},
subscriptions: [
(send, done) => {
raf(function loop () {
send('now', Date.now(), done)
raf(loop)
})
}
]
}
+20
View File
@@ -0,0 +1,20 @@
{
"name": "stopwatch",
"version": "1.0.0",
"description": "",
"main": "client.js",
"scripts": {
"start": "budo client.js -p 8080 -- -t es2020"
},
"keywords": [],
"author": "traducer <traducer21@gmail.com>",
"license": "ISC",
"dependencies": {
"budo": "^8.3.0",
"raf": "^3.2.0",
"xtend": "^4.0.1"
},
"devDependencies": {
"es2020": "^1.1.7"
}
}
+15
View File
@@ -0,0 +1,15 @@
function formatMinutes (minutes) {
return `${minutes >= 10 ? minutes : (minutes < 10) ? '0' + minutes : '00'}`
}
function formatSeconds (seconds) {
return `${seconds < 10 ? '0' + seconds : seconds}`
}
module.exports = function format (elapsed) {
const minutes = formatMinutes(Math.floor((elapsed / 1000) / 60))
const seconds = formatSeconds(Math.floor((elapsed / 1000) % 60))
const ms = formatSeconds(Math.floor((elapsed % 1000) / 10))
return `${minutes}:${seconds}.${ms}`
}
+36
View File
@@ -0,0 +1,36 @@
const html = require('../../../html')
const format = require('../utilities/format')
function toggle (state, send) {
if (state.start) {
send('stop')
} else {
send('start')
}
}
module.exports = (state, prev, send) => {
const start = state.start
const elapsed = state.elapsed
return html`
<main class="app">
<h1>stopwatch</h1>
<p>${format(elapsed)}</p>
<button
onclick=${e => toggle(state, send)}
>${start ? 'stop' : 'start'}</button>
<button
style="display:${start ? 'none' : 'inline'};"
onclick=${e => send('reset')}
>reset</button>
<button
style="display:${start ? 'inline' : 'none'};"
onclick=${e => send('add', format(elapsed))}
>lap</button>
<ol>
${state.laps.map(lap => html`<li>${lap}</li>`)}
</ol>
</main>
`
}