Skip to content

Instantly share code, notes, and snippets.

@back2dos
Created April 30, 2017 11:21
Show Gist options
  • Save back2dos/ca262deaca81ba03d9a6c201af89f9a1 to your computer and use it in GitHub Desktop.
Save back2dos/ca262deaca81ba03d9a6c201af89f9a1 to your computer and use it in GitHub Desktop.
Coconut swapper.
import tink.state.*;
import coconut.ui.*;
using tink.CoreApi;
class Swapper<T> extends BaseView {
public function new(options:Observable<{
className:String,
data: Promised<T>,
renderData:T->RenderResult,
?renderError:Error->RenderResult,
?delay:Float,
}>) {
var stack:Array<RenderResult> = [];
function renderStack(state, ?other):RenderResult {
var old = stack.copy();
var nu = old.pop();
return hxx('
<div class="swapper ${options.value.className}" data-state=$state>
<div class="old">{old}</div>
{nu}
{other}
</div>
');
}
var lastData:T = null;
super(
Observable.create(
function () {
var m = options.measure(),
updated = Future.trigger();
return new Measurement(switch m.value.data {
case Loading:
renderStack("loading");
case Failed(e):
renderStack("error",
switch m.value.renderError {
case null:
hxx('
<div class="error">
{e.message}
</div>
');
case f: f(e);
}
);
case Done(v):
var delay = switch m.value.delay {
case Math.isNaN(_) => true: 1000;
case v: Std.int(v * 1000);
}
if (lastData != v) {
lastData = v;
var view = m.value.renderData(v);
stack.push(view);
switch stack[stack.length - 2] {
case null:
case old:
if (delay <= 0)
stack.remove(old)
else
haxe.Timer.delay(function () {
if (stack.remove(old))
updated.trigger(Noise);
}, 2000);
}
}
renderStack("done");
}, m.becameInvalid.first(updated));
}
),
function (r) return r
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment