Skip to content

Commit 34cc044

Browse files
authored
Merge pull request #96 from vankeisb/feature/fix-subs
Fix subs
2 parents 915fcab + 96affba commit 34cc044

17 files changed

Lines changed: 582 additions & 248 deletions

File tree

.circleci/config.yml

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
version: 2
1+
version: 2.1
2+
orbs:
3+
browser-tools: circleci/browser-tools@1.1.1
24

35
defaults: &defaults
46
working_directory: ~/repo
@@ -16,6 +18,31 @@ jobs:
1618
root: ~/repo
1719
paths: .
1820

21+
webtests:
22+
working_directory: ~/repo
23+
docker:
24+
- image: circleci/openjdk:11-jdk-browsers
25+
environment:
26+
DISPLAY: :99
27+
28+
steps:
29+
- run: sudo Xvfb :99 -screen 0 1920x1200x24 > /dev/null 2>&1 &
30+
- attach_workspace:
31+
at: ~/repo
32+
- browser-tools/install-chrome
33+
- browser-tools/install-chromedriver
34+
- run:
35+
command: |
36+
google-chrome --version
37+
chromedriver --version
38+
ps -efa | grep Xvfb
39+
name: Check install
40+
- run: cd webtests && export DISPLAY=:99 && mvn clean install -Dwebdriver.chrome.driver=/usr/local/bin/chromedriver
41+
- store_artifacts:
42+
path: ~/repo/webtests/target/surefire-reports
43+
- store_artifacts:
44+
path: ~/repo/webtests/target/videos
45+
1946
deploy:
2047
<<: *defaults
2148
steps:
@@ -34,9 +61,13 @@ workflows:
3461
filters:
3562
tags:
3663
only: /\d+\.\d+\.\d+/
64+
- webtests:
65+
requires:
66+
- build
3767
- deploy:
3868
requires:
3969
- build
70+
- webtests
4071
filters:
4172
tags:
4273
only: /\d+\.\d+\.\d+/

build.sh

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,5 @@ cd core && \
55
cd ../tea-cup && \
66
./build.sh && \
77
cd ../samples && \
8-
yarn test --watchAll=false
8+
yarn test --watchAll=false && \
9+
yarn build

core/src/TeaCup/Animation.ts

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -25,20 +25,6 @@
2525

2626
import { Sub } from './Sub';
2727

28-
let subs: Array<RafSub<any>> = [];
29-
30-
let ticking = false;
31-
32-
function tick() {
33-
if (!ticking) {
34-
ticking = true;
35-
requestAnimationFrame((t: number) => {
36-
subs.forEach((s) => s.trigger(t));
37-
ticking = false;
38-
});
39-
}
40-
}
41-
4228
class RafSub<M> extends Sub<M> {
4329
readonly mapper: (t: number) => M;
4430

@@ -49,13 +35,9 @@ class RafSub<M> extends Sub<M> {
4935

5036
protected onInit() {
5137
super.onInit();
52-
subs.push(this);
53-
tick();
54-
}
55-
56-
protected onRelease() {
57-
super.onRelease();
58-
subs = subs.filter((s) => s !== this);
38+
setTimeout(() => {
39+
this.isActive() && requestAnimationFrame((t) => this.trigger(t));
40+
});
5941
}
6042

6143
trigger(t: number) {

core/src/TeaCup/Sub.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import { Dispatcher } from './Dispatcher';
2727

2828
export abstract class Sub<Msg> {
2929
protected dispatcher: Dispatcher<Msg> | undefined;
30+
private active: boolean = false;
3031

3132
static none<Msg>(): Sub<Msg> {
3233
return new SubNone();
@@ -38,16 +39,21 @@ export abstract class Sub<Msg> {
3839

3940
init(dispatch: Dispatcher<Msg>): void {
4041
this.dispatcher = dispatch;
42+
this.active = true;
4143
this.onInit();
4244
}
4345

4446
release(): void {
45-
this.dispatcher = undefined;
47+
this.active = false;
4648
this.onRelease();
4749
}
4850

51+
isActive() {
52+
return this.active;
53+
}
54+
4955
protected dispatch(m: Msg): void {
50-
this.dispatcher && this.dispatcher(m);
56+
this.dispatcher?.(m);
5157
}
5258

5359
protected onInit() {}

samples/src/App.tsx

Lines changed: 62 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -24,18 +24,7 @@
2424
*/
2525

2626
import React from 'react';
27-
import {
28-
Cmd,
29-
Dispatcher,
30-
just,
31-
map,
32-
Maybe,
33-
maybeOf,
34-
noCmd,
35-
nothing,
36-
Sub,
37-
Task,
38-
} from 'tea-cup-core';
27+
import { Cmd, Dispatcher, just, map, Maybe, maybeOf, noCmd, nothing, Sub, Task } from 'tea-cup-core';
3928
import {
4029
DevTools,
4130
newUrl,
@@ -60,7 +49,7 @@ import * as TimeSample from './Samples/TimeSample';
6049
import * as EventsSample from './Samples/EventsSample';
6150
import * as SelectSample from './Samples/SelectSample';
6251
import * as PortsSample from './Samples/PortsSample';
63-
import { appSamplePorts } from "./Samples/PortsSample";
52+
import { appSamplePorts } from './Samples/PortsSample';
6453

6554
enum Tab {
6655
All,
@@ -367,7 +356,7 @@ function mapPortsSample(m: PortsSample.Msg): Msg {
367356
return {
368357
type: 'portsSample',
369358
child: m,
370-
}
359+
};
371360
}
372361

373362
function view(dispatch: Dispatcher<Msg>, model: Model) {
@@ -464,16 +453,16 @@ function viewTodos(dispatch: Dispatcher<Msg>, todoMvc: TodoMvc) {
464453
{active ? (
465454
<span>{label}</span>
466455
) : (
467-
<a
468-
href="#x"
469-
onClick={(e) => {
470-
e.preventDefault();
471-
dispatch({ type: 'tabClicked', tab: t });
472-
}}
473-
>
474-
{label}
475-
</a>
476-
)}
456+
<a
457+
href="#x"
458+
onClick={(e) => {
459+
e.preventDefault();
460+
dispatch({ type: 'tabClicked', tab: t });
461+
}}
462+
>
463+
{label}
464+
</a>
465+
)}
477466
</li>
478467
);
479468
}
@@ -485,46 +474,46 @@ function viewTodos(dispatch: Dispatcher<Msg>, todoMvc: TodoMvc) {
485474
{todos.length === 0 ? (
486475
<p>You have nothing to do ! Neat !!</p>
487476
) : (
488-
<div>
489-
<ul>
490-
{viewTab(Tab.All)}
491-
{viewTab(Tab.Open)}
492-
{viewTab(Tab.Closed)}
493-
</ul>
494-
<ul>
495-
{todos
496-
.filter((todo) => {
497-
switch (tab) {
498-
case Tab.All:
499-
return true;
500-
case Tab.Open:
501-
return !todo.done;
502-
case Tab.Closed:
503-
return todo.done;
504-
}
505-
return false;
506-
})
507-
.map((todo) => {
508-
const style = {
509-
textDecoration: todo.done ? 'line-through' : 'none',
510-
};
511-
return (
512-
<li key={todo.id} style={style}>
513-
<a
514-
href="#x"
515-
onClick={(e) => {
516-
e.preventDefault();
517-
dispatch(navigateTo(todoRoute(todo.id)));
518-
}}
519-
>
520-
{todo.text}
521-
</a>
522-
</li>
523-
);
524-
})}
525-
</ul>
526-
</div>
527-
)}
477+
<div>
478+
<ul>
479+
{viewTab(Tab.All)}
480+
{viewTab(Tab.Open)}
481+
{viewTab(Tab.Closed)}
482+
</ul>
483+
<ul>
484+
{todos
485+
.filter((todo) => {
486+
switch (tab) {
487+
case Tab.All:
488+
return true;
489+
case Tab.Open:
490+
return !todo.done;
491+
case Tab.Closed:
492+
return todo.done;
493+
}
494+
return false;
495+
})
496+
.map((todo) => {
497+
const style = {
498+
textDecoration: todo.done ? 'line-through' : 'none',
499+
};
500+
return (
501+
<li key={todo.id} style={style}>
502+
<a
503+
href="#x"
504+
onClick={(e) => {
505+
e.preventDefault();
506+
dispatch(navigateTo(todoRoute(todo.id)));
507+
}}
508+
>
509+
{todo.text}
510+
</a>
511+
</li>
512+
);
513+
})}
514+
</ul>
515+
</div>
516+
)}
528517
</div>
529518
);
530519
}
@@ -566,7 +555,6 @@ function viewSamples(dispatch: Dispatcher<Msg>, samples: Samples) {
566555
return (
567556
<div>
568557
{backToHome(dispatch)}
569-
<h1>Samples</h1>
570558
<p>
571559
This is the samples app for <code>react-tea-cup</code>.
572560
</p>
@@ -594,10 +582,14 @@ function viewSamples(dispatch: Dispatcher<Msg>, samples: Samples) {
594582
{SelectSample.view(map(dispatch, mapSelectSample), samples.select)}
595583
<h2>Ports</h2>
596584
{PortsSample.view(map(dispatch, mapPortsSample), samples.ports)}
597-
<button onClick={() => {
598-
// call ports without going through any update loop
599-
appSamplePorts.setCounter.send(0)
600-
}}>Reset using port</button>
585+
<button
586+
onClick={() => {
587+
// call ports without going through any update loop
588+
appSamplePorts.setCounter.send(0);
589+
}}
590+
>
591+
Reset using port
592+
</button>
601593
</div>
602594
);
603595
}
@@ -661,7 +653,7 @@ function update(msg: Msg, model: Model): [Model, Cmd<Msg>] {
661653
const macTime = TimeSample.update(msg.child, s.time);
662654
return [{ ...s, time: macTime[0] }, macTime[1].map(mapTimeSample)];
663655
});
664-
case "portsSample":
656+
case 'portsSample':
665657
return mapSample((s: Samples) => {
666658
const mac = PortsSample.update(msg.child, s.ports);
667659
return [{ ...s, ports: mac[0] }, mac[1].map(mapPortsSample)];

samples/src/Samples/Counter.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,14 @@ export function init(): [Model, Cmd<Msg>] {
4242
// need this "dispatch" arg, so that you can emit Msgs
4343
export function view(dispatch: Dispatcher<Msg>, model: Model) {
4444
return (
45-
<div className="counter">
46-
<button onClick={(_) => dispatch({ type: 'dec' })}>-</button>
47-
<span>{model}</span>
48-
<button onClick={(_) => dispatch({ type: 'inc' })}>+</button>
45+
<div className="counter" id="sample-counter">
46+
<button id="counter-sub" onClick={(_) => dispatch({ type: 'dec' })}>
47+
-
48+
</button>
49+
<span id="counter-value">{model}</span>
50+
<button id="counter-add" onClick={(_) => dispatch({ type: 'inc' })}>
51+
+
52+
</button>
4953
</div>
5054
);
5155
}

0 commit comments

Comments
 (0)