Skip to content

Instantly share code, notes, and snippets.

@milankinen
Created March 22, 2016 20:58
Show Gist options
  • Save milankinen/3fe25e2313610a4d5d08 to your computer and use it in GitHub Desktop.
Save milankinen/3fe25e2313610a4d5d08 to your computer and use it in GitHub Desktop.
"Advanced" Cycle.js list example
import {Observable as O} from 'rx'
import L from "partial.lenses"
import R from "ramda"
import {h3, div} from '@cycle/dom'
import isolate from '@cycle/isolate'
import Ticker from './ticker'
import {liftListById, flatCombine, flatMerge} from "stanga"
function intent(tickers$) {
// append new ticker every 5 sec
const insert$ = O.interval(2000).take(10).map(() => R.append({id: Date.now()}))
return insert$.map(tickers$.mod)
}
function view(DOM, tickers$) {
const children$$ = liftListById(tickers$, R.prop("id"), id => {
const tickerLens = L.find(R.whereEq({id}))
const remove$ = O.just(L.delete(tickerLens)).map(tickers$.mod)
const ticker = tickers$.lens(tickerLens)
return isolate(Ticker, `ticker-${id}`)({DOM, M: ticker, remove$})
})
//const childMods$ = O.empty()
const {M: childMods$} = flatMerge(children$$, "M")
const dom$ = flatCombine(children$$, "DOM")
// vdom containing children
const loading = h3('Loading...')
const vdom$ = dom$.map(children => div("#the-view", children.length ? children : [loading])).shareReplay(1)
return {vdom$, childMods$}
}
function App(sources) {
const tickers$ = sources.M.lens("tickers")
const mods$ = intent(tickers$)
const {vdom$, childMods$} = view(sources.DOM, tickers$)
return {
DOM: vdom$,
M: mods$.merge(childMods$)
}
}
export default App
import {Observable as O} from 'rx'
import R from "ramda"
import L from "partial.lenses"
import {div, h1, h4, button} from '@cycle/dom'
import combineLatestObj from 'rx-combine-latest-obj'
function makeRandomColor() {
let hexColor = Math.floor(Math.random() * 16777215).toString(16)
while (hexColor.length < 6) {
hexColor = '0' + hexColor
}
hexColor = '#' + hexColor
return hexColor
}
function intent(DOM, {x$, y$, color$}, remove$) {
// remove$ was already mod from the parent but let ticker to decide
// when that mod should be applied
const removeMe$ = remove$.sample(DOM.select('.remove-btn').events('click')).share()
// set "private" mods for ticker
const changeColor$ = O.interval(1000).map(makeRandomColor).takeUntil(removeMe$)
const changeX$ = O.interval(50).startWith(0).takeUntil(removeMe$)
const changeY$ = O.interval(100).startWith(0).takeUntil(removeMe$)
return O.merge(
changeX$.map(R.always).map(x$.mod),
changeY$.map(R.always).map(y$.mod),
changeColor$.map(R.always).map(color$.mod),
removeMe$
)
}
function view(state) {
return combineLatestObj(state).map(({color, x, y}) => {
const style = {color, backgroundColor: '#ECECEC'}
return div('.ticker', {style}, [
h4(`x${x} ${color}`),
h1(`Y${y} ${color}`),
button('.remove-btn', 'Remove')
])
}).shareReplay(1)
}
function Ticker(sources) {
// remove$ signals to parent that this component wants itself to be removed
const {DOM, remove$, M} = sources
const state = {
x$: M.lens("x", L.default(0)),
y$: M.lens("y", L.default(0)),
color$: M.lens("color", L.default("#000000"))
}
const mods$ = intent(DOM, state, remove$)
const vdom$ = view(state)
return {
DOM: vdom$,
M: mods$
}
}
export default Ticker
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment