tomadoro/src/components/Timer.js

218 lines
4.7 KiB
JavaScript
Raw Normal View History

2019-03-14 16:53:56 +01:00
import React, { Component } from 'react';
2019-03-15 10:33:22 +01:00
import { Button, Container, Row, Col } from 'reactstrap';
2019-03-14 16:53:56 +01:00
import './Timer.css';
2019-03-15 10:33:22 +01:00
import logo from '../logo.svg';
2019-03-15 15:24:47 +01:00
import Notification from 'react-web-notification';
import sound from '../sound.mp3';
2019-03-14 16:53:56 +01:00
2019-03-15 10:33:22 +01:00
class Timer extends Component {
2019-03-14 16:53:56 +01:00
constructor(props) {
super(props);
2019-03-15 15:58:29 +01:00
this.defaultSeconds = 1500;
2019-03-15 10:33:22 +01:00
this.defaultLogoSpin = 'App-logo-rotation';
2019-03-14 16:53:56 +01:00
this.state = {
seconds: this.defaultSeconds,
2019-03-15 10:33:22 +01:00
started: false,
2019-03-15 15:24:47 +01:00
logoSpin: '',
ignore: true,
title: ''
2019-03-14 16:53:56 +01:00
};
2019-03-15 15:24:47 +01:00
// binding
2019-03-14 16:53:56 +01:00
this.startTimer = this.startTimer.bind(this);
this.stopTimer = this.stopTimer.bind(this);
this.resetTimer = this.resetTimer.bind(this);
2019-03-15 15:24:47 +01:00
this.handlePermissionGranted = this.handlePermissionGranted.bind(this);
this.handlePermissionDenied = this.handlePermissionDenied.bind(this);
this.handleNotSupported = this.handleNotSupported.bind(this);
this.sendNotification = this.sendNotification.bind(this);
this.handleNotificationOnShow = this.handleNotificationOnShow.bind(this);
this.playSound = this.playSound.bind(this);
2019-03-14 16:53:56 +01:00
}
2019-03-15 15:24:47 +01:00
formatMinute(s){
return ( s - ( s%=60 )) / 60 + ( 9 < s ?':':':0') +s;
}
// handleNotification
handlePermissionGranted() {
this.setState({
ignore: false
});
}
handlePermissionDenied() {
this.setState({
ignore: true
});
}
handleNotSupported() {
this.setState({
ignore: true
});
}
handleNotificationOnError(e, tag){
console.log(e, 'Notification error tag:' + tag);
}
playSound(){
document.getElementById('sound').play();
}
handleNotificationOnShow() {
this.playSound();
}
sendNotification() {
if (this.state.ignore) {
return;
}
const title = 'tomadoro';
const body = 'Time is Up! 🍅';
const tag = Date.now();
const options = {
tag: tag,
body: body,
lang: 'en',
sound: {sound}
};
this.setState({
title: title,
options: options
});
}
2019-03-14 16:53:56 +01:00
tick() {
this.setState(state => ({
seconds: state.seconds -1
}));
2019-03-15 15:24:47 +01:00
if (this.state.seconds <= 0) {
this.sendNotification();
this.stopTimer();
this.resetTimer();
}
2019-03-14 16:53:56 +01:00
}
startTimer() {
2019-03-15 10:33:22 +01:00
this.setState({
started: true,
logoSpin: this.defaultLogoSpin
});
2019-03-14 16:53:56 +01:00
this.interval = setInterval(() => this.tick(), 1000);
}
stopTimer() {
2019-03-15 10:33:22 +01:00
this.setState({
started: false,
logoSpin: null
});
2019-03-14 16:53:56 +01:00
clearInterval(this.interval);
}
resetTimer() {
this.stopTimer();
this.setState({ seconds: this.defaultSeconds});
}
render() {
return (
<div className="App">
2019-03-15 10:33:22 +01:00
<Container>
<Row>
<Col>
2019-03-15 15:24:47 +01:00
<img
className={`App-logo ${this.state.logoSpin}`}
src={logo}
alt="Tomato"
>
</img>
2019-03-15 10:33:22 +01:00
</Col>
</Row>
<Row>
<Col>
<p
2019-03-15 15:24:47 +01:00
className="timer"
2019-03-15 10:33:22 +01:00
>
2019-03-15 15:24:47 +01:00
{this.formatMinute(this.state.seconds)}
2019-03-15 10:33:22 +01:00
</p>
</Col>
</Row>
<div className="buttons-box">
<Row>
<Col>
2019-03-15 15:24:47 +01:00
<Button
2019-03-15 10:33:22 +01:00
className="buttons"
block
size="lg"
color="success"
onClick={this.startTimer}
disabled={this.state.started}
>
2019-03-15 15:24:47 +01:00
START
2019-03-15 10:33:22 +01:00
</Button>
</Col>
</Row>
2019-03-15 15:24:47 +01:00
<Row
className="top-margin"
>
2019-03-15 10:33:22 +01:00
<Col>
2019-03-15 15:24:47 +01:00
<Button
2019-03-15 10:33:22 +01:00
className="buttons"
block
2019-03-14 16:53:56 +01:00
color="danger"
size="lg"
onClick={this.stopTimer}
disabled={!this.state.started}
2019-03-15 10:33:22 +01:00
>
2019-03-15 15:24:47 +01:00
STOP
2019-03-15 10:33:22 +01:00
</Button>
</Col>
2019-03-14 16:53:56 +01:00
2019-03-15 10:33:22 +01:00
<Col>
2019-03-15 15:24:47 +01:00
<Button
2019-03-15 10:33:22 +01:00
className="buttons"
block
color="secondary"
size="lg"
onClick={this.resetTimer}
2019-03-15 15:24:47 +01:00
disabled={this.state.started || this.state.seconds === this.defaultSeconds}
2019-03-15 10:33:22 +01:00
>
2019-03-15 15:24:47 +01:00
RESET
2019-03-15 10:33:22 +01:00
</Button>
</Col>
</Row>
</div>
</Container>
2019-03-15 15:24:47 +01:00
<Notification
ignore={this.state.ignore}
onPermissionGranted = {this.handlePermissionGranted}
onPermissionDenied = {this.handlePermissionDenied}
notSupported = {this.handleNotSupported}
onError = {this.onError}
timeout = {5000}
title = {this.state.title}
options = {this.state.options}
onShow = {this.handleNotificationOnShow}
>
</Notification>
<audio id='sound' preload='auto'>
<source src={sound} type='audio/mpeg' />
<embed hidden src={sound} />
</audio>
2019-03-14 16:53:56 +01:00
</div>
);
}
}
export default Timer;