Permalink
Browse files

Add a clock in the title

  • Loading branch information...
lucapette committed Mar 13, 2017
1 parent 977a01f commit 2bc71a668e475755cd141be1038a6dd855e0fc8b
Showing with 107 additions and 14 deletions.
  1. +1 −0 package.json
  2. +12 −7 src/Layout.js
  3. +25 −7 src/timer.js
  4. +26 −0 src/timer.test.js
  5. +43 −0 yarn.lock
View
@@ -22,6 +22,7 @@
"flowtype-loader": "^0.2.2",
"jest": "^19.0.2",
"react": "^15.4.2",
+ "react-document-title": "^2.0.2",
"react-dom": "^15.4.2",
"semantic-ui-css": "^2.2.4",
"semantic-ui-react": "^0.64.4",
View
@@ -1,6 +1,8 @@
//@flow
import React, { Component } from 'react'
+import DocumentTitle from 'react-document-title'
import { Segment } from 'semantic-ui-react'
+import _ from 'lodash'
import Timer from './timer'
@@ -21,7 +23,8 @@ export default class Layout extends Component {
constructor() {
super();
this.state = {
- page: 'home'
+ page: 'home',
+ title: 'home'
}
this.timer = new Timer();
@@ -51,18 +54,20 @@ export default class Layout extends Component {
break;
}
- this.setState({page})
+ this.setState({page: page})
}
render() {
return (
- <div id="container">
- <ContentPanel changePage={this.changePage.bind(this)} page={this.state.page}/>
+ <DocumentTitle title={`${_.join(_.compact([this.state.page, this.timer.clockFormat()]), ' - ')}`}>
+ <div id="container">
+ <ContentPanel changePage={this.changePage.bind(this)} page={this.state.page}/>
- <ControlPanel changePage={this.changePage.bind(this)} page={this.state.page}/>
+ <ControlPanel changePage={this.changePage.bind(this)} page={this.state.page}/>
- <ProgressPanel changePage={this.changePage.bind(this)} page={this.state.page} percent={this.state.progress}/>
- </div>
+ <ProgressPanel changePage={this.changePage.bind(this)} page={this.state.page} percent={this.state.progress}/>
+ </div>
+ </DocumentTitle>
)
}
}
View
@@ -1,33 +1,39 @@
//@flow
+import _ from 'lodash';
+
type CallbackType = 'tick' | 'done';
type Callback = (any) => void;
export default class Timer {
+ secondsToRun: number;
+ elapsed: number;
callbacks: Map<CallbackType, Callback>;
- interval: number;
+ interval: number | void;
constructor() {
this.callbacks = new Map();
}
start(seconds: number = 25 * 60) {
+ this.secondsToRun = seconds;
+ this.elapsed = 0;
+
let start = Date.now();
- let elapsed = 0;
let lastElapsed = 0;
this.interval = setInterval(() => {
- elapsed = Math.floor((Date.now() - start) / 1000);
+ this.elapsed = Math.floor((Date.now() - start) / 1000);
- if (elapsed != lastElapsed) {
- lastElapsed = elapsed;
+ if (this.elapsed != lastElapsed) {
+ lastElapsed = this.elapsed;
let callback = this.callbacks.get('tick');
if (callback) {
- callback(Math.floor((elapsed/seconds) * 100));
+ callback(Math.floor((this.elapsed/seconds) * 100));
}
}
- if (elapsed >= seconds) {
+ if (this.elapsed >= seconds) {
let callback = this.callbacks.get('done');
if (callback) {
callback();
@@ -40,13 +46,25 @@ export default class Timer {
stop() {
if (this.interval) {
clearInterval(this.interval);
+ this.interval = undefined;
}
}
isRunning() {
return this.interval != undefined;
}
+ clockFormat() {
+ if (!this.isRunning()) {
+ return;
+ }
+
+ let secondsLeft = this.secondsToRun - this.elapsed;
+ let minutes = Math.floor(secondsLeft / 60);
+ let seconds = secondsLeft % 60;
+
+ return `${_.padStart(minutes, 2, '0')}:${_.padStart(seconds, 2, '0')}`;
+ }
on(type : CallbackType, callback : Callback) {
this.callbacks.set(type, callback);
View
@@ -53,3 +53,29 @@ test('it stops correctly', () => {
expect(tick).toHaveBeenCalledTimes(1);
});
+
+describe('clockFormat', () => {
+ test('returns undefined when not running', () => {
+ var timer = new Timer();
+
+ expect(timer.clockFormat()).toBeUndefined();
+ });
+
+ test('formats no elapsed time correctly', () => {
+ var timer = new Timer();
+
+ timer.start(60);
+
+ expect(timer.clockFormat()).toEqual('01:00');
+ });
+
+ test('formats elapsed time correctly', () => {
+ var timer = new Timer();
+
+ timer.start();
+
+ jest.runTimersToTime(1000);
+
+ expect(timer.clockFormat()).toEqual('24:59');
+ });
+});
View

Some generated files are not rendered by default. Learn more.

Oops, something went wrong.

0 comments on commit 2bc71a6

Please sign in to comment.