Skip to content

Instantly share code, notes, and snippets.

@jizusun
Created August 5, 2018 11:45
Show Gist options
  • Save jizusun/94c9e8d64abbf24e44f2f2e7706e8e43 to your computer and use it in GitHub Desktop.
Save jizusun/94c9e8d64abbf24e44f2f2e7706e8e43 to your computer and use it in GitHub Desktop.
Pomodoro
<link href="https://fonts.googleapis.com/css?family=Rubik:300" rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Roboto:700" rel="stylesheet">
<div id="root"></div>
class Buzzer extends React.Component{
componentDidMount() {
document.getElementById('beep').play();
}
render(){
return (
<audio id="beep" autoplay='autoplay'><source src="http://www.freesound.org/data/previews/175/175081_1272140-lq.mp3" /></audio>
);
}
}
class SetTimer extends React.Component{
render(){
return (
<div className="set-timer">work <br/> session
<div className="minus-add">
<button className="setting-button" id="minus-timer" onClick={this.props.minus}>-</button>
<button className="setting-button" id="add-timer" onClick={this.props.add}>+</button>
</div>
</div>
);
}
}
class SetBreak extends React.Component{
render(){
return (
<div className="set-break"> break<br/> session
<div className="minus-add">
<button className="setting-button" id="minus-break" onClick={this.props.minusbreak}>-</button>
<button className="setting-button" id="add-break" onClick={this.props.addbreak}>+</button>
</div>
</div>
);
}
}
const leftPad = (time)=>{
return (time<10)? '0'+time :time
}
const TimerDisplay = (props) => (
<div className="timer-display"><span className="worklabel">Work session time</span><br/>
{leftPad(props.currentMoment.get('minutes'))+":"+leftPad(props.currentMoment.get('seconds'))}
<div className="breaktime"><span className="breaklabel">break session time</span><br/>{props.breakTime.get('minutes')+":"+leftPad(props.breakTime.get('seconds'))}</div>
</div>
);
// let baseTime= 25;
class App extends React.Component {
constructor(){
super();
this.state = {
currentMoment: moment.duration(25, 'minutes'),
breakMoment: moment.duration(5, 'minutes'),
baseMoment: null,
timer:null,
breaktimer:null,
startbuttonvisible:true,
pausebuttonvisible:false,
resumebuttonvisible:false,
stopbuttonvisible:false,
workFinish:false,
breakFinish:false
}
this.minus =this.minus.bind(this);
this.add =this.add.bind(this);
this.minusbreak =this.minusbreak.bind(this);
this.addbreak =this.addbreak.bind(this);
this.startTimer = this.startTimer.bind(this);
this.pauseTimer = this.pauseTimer.bind(this);
this.resumeTimer = this.resumeTimer.bind(this);
this.pauseBreakTimer = this.pauseBreakTimer.bind(this);
this.resumeBreakTimer = this.resumeBreakTimer.bind(this);
this.stopTimer = this.stopTimer.bind(this);
this.reduceTimer = this.reduceTimer.bind(this);
this.reduceBreakTimer = this.reduceBreakTimer.bind(this);
}
add(){
if(this.state.currentMoment.get('minutes') <= 58 ) {
this.setState({
currentMoment:this.state.currentMoment.add(1,'minutes')
});
}
}
minus(){
if(this.state.currentMoment.get('minutes') !== 0 ) {
this.setState({
currentMoment:this.state.currentMoment.subtract(1,'minutes')
});
}
}
addbreak(){
if(this.state.breakMoment.get('minutes') <= 58 ) {
this.setState({
breakMoment:this.state.breakMoment.add(1,'minutes')
});
}
}
minusbreak(){
if(this.state.breakMoment.get('minutes') !== 0 ) {
this.setState({
breakMoment:this.state.breakMoment.subtract(1,'minutes')
});
}
}
startTimer(){
this.setState({
timer: setInterval(this.reduceTimer, 1000),
baseMoment: this.state.currentMoment,
startbuttonvisible:false,
pausebuttonvisible:true,
stopbuttonvisible:true,
workFinish:false,
});
}
pauseTimer(){
clearInterval(this.state.timer);
this.setState({
pausebuttonvisible:false,
resumebuttonvisible:true,
});
}
resumeTimer(){
this.setState({
timer: setInterval(this.reduceTimer, 1000),
startbuttonvisible:false,
pausebuttonvisible:true,
stopbuttonvisible:true,
resumebuttonvisible:false,
});
}
pauseBreakTimer(){
clearInterval(this.state.breaktimer);
this.setState({
pausebuttonvisible:false,
resumebuttonvisible:true,
});
}
resumeBreakTimer(){
this.setState({
breaktimer: setInterval(this.reduceBreakTimer, 1000),
startbuttonvisible:false,
pausebuttonvisible:true,
stopbuttonvisible:true,
resumebuttonvisible:false,
});
}
stopTimer(){
clearInterval(this.state.timer);
clearInterval(this.state.breaktimer);
this.setState({
currentMoment:moment.duration(25, 'minutes'),
breakMoment:moment.duration(5, 'minutes'),
timer: null,
breaktimer: null,
startbuttonvisible:true,
pausebuttonvisible:false,
stopbuttonvisible:false,
resumebuttonvisible:false,
});
}
reduceTimer(){
if(this.state.currentMoment.get('minutes') === 0 && this.state.currentMoment.get('seconds') === 0) {
clearInterval(this.state.timer);
this.setState({
timer: null,
startbuttonvisible:true,
pausebuttonvisible:false,
stopbuttonvisible:false,
resumebuttonvisible:false,
workFinish: true,
});
if(this.state.breakMoment.get('minutes') !== 0 ) {
this.setState({
breaktimer: setInterval(this.reduceBreakTimer, 1000),
startbuttonvisible:false,
pausebuttonvisible:true,
stopbuttonvisible:true,
});
}
return;
}
else {
this.setState({
currentMoment: this.state.currentMoment.subtract(moment.duration(1, 'second')),
});
}
}
reduceBreakTimer(){
if(this.state.breakMoment.get('minutes') === 0 && this.state.breakMoment.get('seconds') === 0) {
clearInterval(this.state.breaktimer);
this.setState({
breaktimer: null,
startbuttonvisible:true,
pausebuttonvisible:false,
stopbuttonvisible:false,
resumebuttonvisible:false,
breakFinish:true,
});
return;
}
this.setState({
breakMoment: this.state.breakMoment.subtract(moment.duration(1, 'second')),
});
}
render() {
return (
<div className="container">
<div className="timebox">
<div className="header">
POMODORO POWER
{ (this.state.workFinish) &&
<Buzzer />
}
</div>
<TimerDisplay currentMoment={this.state.currentMoment} breakTime={this.state.breakMoment}/>
<div id="action-title">
<small>SETTINGS</small>
</div>
<div className="actions">
<SetTimer minus={this.minus} add={this.add}/>
<SetBreak minusbreak={this.minusbreak} addbreak={this.addbreak}/>
</div>
<div className="timer-control">
{this.state.startbuttonvisible ? <button id="start-timer" onClick={ this.startTimer }>
START
</button> : null}
{this.state.pausebuttonvisible ? <button id="pause-timer" onClick={this.state.workFinish ? this.pauseBreakTimer:this.pauseTimer}>
PAUSE
</button>: null}
{this.state.resumebuttonvisible ? <button id="resume-timer" onClick={this.state.workFinish ? this.resumeBreakTimer:this.resumeTimer}>
RESUME
</button>: null}
{this.state.stopbuttonvisible ? <button id="stop-timer" onClick={this.stopTimer}>
STOP
</button>: null}
</div>
</div>
</div>
);
}
}
React.render(
<App />,
document.getElementById('root')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.18.1/moment.min.js"></script>
html{
height: 100%;
}
body{
background: linear-gradient(to bottom right, #E2F448, #31BD8E 45%, #3AC5B6 59%, #2FAFD3);
font-family: "Rubik", sans-serif;
height: 100%;
}
*{
box-sizing:border-box;
}
.timebox {
box-shadow: 0 16px 28px 0 rgba(0, 0, 0, 0.8), 0 25px 55px 0 rgba(0, 0, 0, 0.21);
width: 300px;
height: 575px;
background-color: #1F2025;
color: #DADADB;
margin: 0 auto;
top: 50px;
position: relative;
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
flex-direction:column;
}
.header {
text-align: center;
padding: 20px;
font-size: 15.6px;
border-bottom: solid #18191d 1px;
}
#timer {
width: 100%;
height: 340px;
}
#action-title{
text-align: center;
margin-bottom: -10px;
}
#action-title small{
border-radius:8px;
border:1px solid #aaa;
padding: 2px 4px;
position: relative;
z-index: 10;
background-color: #1F2025;
}
.actions, .minus-add{
display: -webkit-flex;
display: -moz-flex;
display: -ms-flex;
display: -o-flex;
display: flex;
flex-direction:row;
text-align: center;
cursor:pointer;
align-items:center;
}
.set-timer, .set-break, .setting-button{
width:50%;
text-align: center;
text-transform: uppercase;
}
.set-timer, .set-break{
border-top: solid #18191d 1px;
padding-top: 40px;
}
.set-timer{
border-right: solid #18191d 1px;
}
/*.set-break{
border-top: solid #18191d 1px;
}*/
#start-timer{
background: linear-gradient(135deg, #31BD8E, #3AC5B6 50%, #2FAFD3);
box-shadow: 0 16px 28px 0 rgba(0, 0, 0, 0.8), 0 25px 55px 0 rgba(0, 0, 0, 0.21);
width: 100%;
text-align: center;
color: white;
padding: 20px 20px;
cursor: pointer;
border:none;
}
.timer-controls{
display:flex;
flex-direction:row;
}
#stop-timer{
background: linear-gradient(135deg, #FE7201, #C41E10 50%, #6F0617);
width: 50%;
text-align: center;
color: white;
padding: 20px 20px;
cursor: pointer;
border:none;
}
#resume-timer{
background: linear-gradient(135deg, #FFFE41, #AADD16 50%, #2FBC0B);
width: 50%;
text-align: center;
color: white;
padding: 20px 20px;
cursor: pointer;
border:none;
}
#pause-timer{
background: linear-gradient(135deg, #FEF43B, #FE9118 50%, #FF4F04);
width: 50%;
text-align: center;
color: white;
padding: 20px 20px;
cursor: pointer;
border:none;
}
.setting-button{
height: 50px;
padding: 10px 0;
font-size: 1.42em;
background-color: #1F2025;
border: none;
color: #DADADB;
cursor: pointer;
}
button:focus {outline:0;}
.timer-display{
/*position: relative;*/
padding: 1em 0;
width: 100%;
font-size: 2.3em;
font-family: 'Roboto', serif;
}
.breaktime{
padding:1em;
font-size: .55em;
}
.worklabel{
font-size:0.4em;
color:#aaa;
padding:0;
text-transform: uppercase;
}
.breaklabel{
font-size:0.5em;
color:#aaa;
padding:0;
text-transform: uppercase;
}
.timer-display {
text-align: center;
color: #a8d8f8;
/*text-shadow: 1px 1px 6px #79c3f4;*/
-webkit-transition: all 50ms ease-in;
-moz-transition: all 50ms ease-in;
-o-transition: all 50ms ease-in;
transition: all 50ms ease-in;
}
.unselectable {
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" rel="stylesheet" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment