Skip to content

Commit de65117

Browse files
committed
feat: add support for synchronizeWith property
1 parent cfbdf7c commit de65117

File tree

2 files changed

+33
-13
lines changed

2 files changed

+33
-13
lines changed

modules/timer.js

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,27 +18,36 @@ function timer(delay) {
1818
this.delay = delay;
1919
this.state = { tick: 0 };
2020

21+
this.synchronizeWith = props.synchronizeWith;
22+
this.synchronized = props.synchronizeWith !== undefined;
23+
2124
this.setTimeout = ::this.setTimeout;
2225
this.stop = ::this.stop;
2326
this.resume = ::this.resume;
2427
this.setDelay = ::this.setDelay;
2528
}
2629

2730
setTimeout() {
28-
const { delay, startTime } = this;
29-
const duration = delay - (startTime - Date.now()) % delay;
31+
const { delay, synchronizeWith } = this;
32+
const duration = delay - Math.abs(synchronizeWith - Date.now()) % delay;
3033

3134
this.timer = setTimeout(() => {
3235
this.setState({ tick: this.state.tick + 1 });
3336
if (!this.stopped) this.setTimeout();
34-
}, delay);
37+
}, duration);
38+
}
39+
40+
start() {
41+
this.stopped = false;
42+
if (!this.synchronized) {
43+
this.synchronizeWith = Date.now();
44+
}
45+
this.setTimeout();
3546
}
3647

3748
resume() {
3849
if (this.stopped) {
39-
this.stopped = false;
40-
this.startTime = Date.now();
41-
this.setTimeout();
50+
this.start();
4251
}
4352
}
4453

@@ -57,9 +66,7 @@ function timer(delay) {
5766
}
5867

5968
componentDidMount() {
60-
this.stopped = false;
61-
this.startTime = Date.now();
62-
this.setTimeout();
69+
this.start();
6370
}
6471

6572
componentWillUnmount() {

modules/timer.test.js

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,17 @@ class Counter extends Component {
1919
}
2020
}
2121

22+
const WrappedCounter = timer(1000)(Counter);
23+
2224
describe('Timer', function() {
2325
let clock, wrappedCounter, counter;
2426

2527
before(() => clock = sinon.useFakeTimers());
2628
after(() => clock.restore());
2729

2830
it('should pass down a timer property alongside other props', function() {
29-
const WrappedCounter = timer(1000)(Counter);
3031
expect(WrappedCounter.displayName).to.equal('Timer@1000[Counter]');
31-
32-
const wrappedCounter = renderIntoDocument(h(WrappedCounter, { customProp: 1 }));
33-
32+
wrappedCounter = renderIntoDocument(h(WrappedCounter, { customProp: 1 }));
3433
counter = findRenderedComponentWithType(wrappedCounter, Counter);
3534

3635
expect(counter.props.timer.tick).to.equal(0);
@@ -63,4 +62,18 @@ describe('Timer', function() {
6362
expect(counter.props.timer.tick).to.equal(3);
6463
counter.props.timer.stop();
6564
});
65+
66+
it('should be synchronized with a provided value', function() {
67+
clock.restore();
68+
clock = sinon.useFakeTimers(500);
69+
70+
wrappedCounter = renderIntoDocument(h(WrappedCounter, { synchronizeWith: 0 }));
71+
counter = findRenderedComponentWithType(wrappedCounter, Counter);
72+
73+
expect(counter.props.timer.tick).to.equal(0);
74+
clock.tick(600);
75+
expect(counter.props.timer.tick).to.equal(1);
76+
clock.tick(1000);
77+
expect(counter.props.timer.tick).to.equal(2);
78+
});
6679
});

0 commit comments

Comments
 (0)