Reputation: 99
class Pomodoro extends React.Component {
constructor(props) {
super(props);
this.state = {
breakLength : 5,
sessionLength : 25,
clockMode: 'Session',
clicked: 'timerOff',
timeMin: '25',
timeSec: '00'
}
this.incBreakLength = this.incBreakLength.bind(this);
this.decBreakLength = this.decBreakLength.bind(this);
this.incSessionLength = this.incSessionLength.bind(this);
this.decSessionLength = this.decSessionLength.bind(this);
this.handleTimer = this.handleTimer.bind(this);
this.onTimer = this.onTimer.bind(this);
this.offTimer = this.offTimer.bind(this);
this.init = this.init.bind(this);
}
incBreakLength() {
this.state.breakLength >= 60 ?
this.setState({
breakLength: 60
})
:
this.setState({
breakLength: this.state.breakLength + 1
})
}
decBreakLength() {
this.state.breakLength <= 1 ?
this.setState({
breakLength: 1
})
:
this.setState({
breakLength: this.state.breakLength - 1
})
}
incSessionLength() {
this.state.sessionLength >= 60 ?
this.setState({
sessionLength: 60,
timeMin: '60'
})
:
this.setState({
sessionLength: this.state.sessionLength + 1,
timeMin: this.state.sessionLength + 1
})
}
decSessionLength() {
this.state.sessionLength <= 1 ?
this.setState({
sessionLength: 1,
timeMin: '1'
})
:
this.setState({
sessionLength: this.state.sessionLength - 1,
timeMin: this.state.sessionLength - 1
})
}
onTimer() {
let totalSec = this.state.sessionLength * 60;
this.timer = setInterval(() => {
let min = Math.floor(totalSec / 60);
let sec = Math.floor(totalSec % 60);
totalSec -= 1;
this.setState({
timeMin: min.toString(),
timeSec: sec > 9 ? sec.toString() : '0' + sec.toString()
})
if(totalSec < 0) {
if(this.state.clockMode === 'Session') {
this.setState({
clockMode: 'Break'
})
totalSec = this.state.breakLength * 60;
} else {
this.setState({
clockMode: 'Session'
})
totalSec = this.state.sessionLength * 60;
}
}
}, 1000);
}
offTimer() {
clearInterval(this.timer)
}
handleTimer() {
if(this.state.clicked === 'timerOff') {
this.setState({
clicked : 'timerOn'
})
this.onTimer();
}
else {
this.setState({
clicked : 'timerOff'
})
this.offTimer();
}
}
init() {
this.offTimer();
this.setState({
breakLength : 5,
sessionLength : 25,
clockMode: 'Session',
clicked: 'timerOff',
timeMin: '25',
timeSec: '00'
})
}
render() {
return (
<div>
<div id='break-label'>
<div id='break-length'>Break/{this.state.breakLength}</div>
<button id='break-increment' onClick={this.incBreakLength}>+1</button>
<button id='break-decrement' onClick={this.decBreakLength}>-1</button>
</div>
<div id='session-label'>
<div id='session-length'>Session/{this.state.sessionLength}</div>
<button id='session-increment' onClick={this.incSessionLength}>+1</button>
<button id='session-decrement' onClick={this.decSessionLength}>-1</button>
</div>
<div id='time-label'>
{this.state.clockMode}/{this.state.clicked}
<div id='time-left'>{this.state.timeMin}:{this.state.timeSec}</div>
</div>
<button id='start_stop' onClick={this.handleTimer}>Start / Pause</button>
<button id='reset' onClick={this.init}>Reset</button>
</div>
)
}
}
ReactDOM.render(<Pomodoro />, document.getElementById('app'));
I am writing the code to make Pomodoro Clock through FreeCodeCamp. The counter should decrement from the sessionLength I set.
I should be able to stop and resume the counter with one button. What I have been trying to do is I made the method called handleTimer deciding whether timer is on or off, and I made onTimer and offTimer method.
Where I am stuck is to resume the counter from the moment I stop. I think I need to make a state global. but I cannot come up with any idea now. Any idea would help me.
Upvotes: 0
Views: 468
Reputation: 1679
Here is one way of doing it, I just added a state paused (boolean) and removed clicked. If the state paused is true, I skip all the part inside the setInterval. If it's not i continue. I also set this.timer to null after the clear interval to use it inside the handleTimer function, if the timer is null we need to call onTimer to initialize it, if timer is not null, we just do nothing because onTimer have been already called.
class Pomodoro extends React.Component {
constructor(props) {
super(props);
this.state = {
breakLength: 5,
sessionLength: 25,
clockMode: 'Session',
timeMin: '25',
timeSec: '00',
paused: true,
}
this.incBreakLength = this.incBreakLength.bind(this);
this.decBreakLength = this.decBreakLength.bind(this);
this.incSessionLength = this.incSessionLength.bind(this);
this.decSessionLength = this.decSessionLength.bind(this);
this.handleTimer = this.handleTimer.bind(this);
this.onTimer = this.onTimer.bind(this);
this.offTimer = this.offTimer.bind(this);
this.init = this.init.bind(this);
}
incBreakLength() {
this.state.breakLength >= 60 ?
this.setState({
breakLength: 60
}) :
this.setState({
breakLength: this.state.breakLength + 1
})
}
decBreakLength() {
this.state.breakLength <= 1 ?
this.setState({
breakLength: 1
}) :
this.setState({
breakLength: this.state.breakLength - 1
})
}
incSessionLength() {
this.state.sessionLength >= 60 ?
this.setState({
sessionLength: 60,
timeMin: '60'
}) :
this.setState({
sessionLength: this.state.sessionLength + 1,
timeMin: this.state.sessionLength + 1
})
}
decSessionLength() {
this.state.sessionLength <= 1 ?
this.setState({
sessionLength: 1,
timeMin: '1'
}) :
this.setState({
sessionLength: this.state.sessionLength - 1,
timeMin: this.state.sessionLength - 1
})
}
onTimer() {
let totalSec = this.state.sessionLength * 60;
this.timer = setInterval(() => {
if (this.state.paused)
return;
let min = Math.floor(totalSec / 60);
let sec = Math.floor(totalSec % 60);
totalSec -= 1;
this.setState({
timeMin: min.toString(),
timeSec: sec > 9 ? sec.toString() : '0' + sec.toString()
})
if (totalSec < 0) {
if (this.state.clockMode === 'Session') {
this.setState({
clockMode: 'Break'
})
totalSec = this.state.breakLength * 60;
} else {
this.setState({
clockMode: 'Session'
})
totalSec = this.state.sessionLength * 60;
}
}
}, 1000);
}
offTimer() {
if (this.timer) {
clearInterval(this.timer)
this.timer = null;
}
}
handleTimer() {
this.setState(prev => ({
...prev,
paused: !prev.paused,
}), () => !this.timer && this.onTimer()
);
}
init() {
this.offTimer();
this.setState({
breakLength: 5,
sessionLength: 25,
clockMode: 'Session',
paused: true,
timeMin: '25',
timeSec: '00'
})
}
render() {
return ( <
div >
<
div id = 'break-label' >
<
div id = 'break-length' > Break / {
this.state.breakLength
} < /div> <
button id = 'break-increment'
onClick = {
this.incBreakLength
} > +1 < /button> <
button id = 'break-decrement'
onClick = {
this.decBreakLength
} > -1 < /button> <
/div>
<
div id = 'session-label' >
<
div id = 'session-length' > Session / {
this.state.sessionLength
} < /div> <
button id = 'session-increment'
onClick = {
this.incSessionLength
} > +1 < /button> <
button id = 'session-decrement'
onClick = {
this.decSessionLength
} > -1 < /button> <
/div>
<
div id = 'time-label' > {
this.state.clockMode
}
/{this.state.clicked} <
div id = 'time-left' > {
this.state.timeMin
}: {
this.state.timeSec
} < /div> <
/div>
<
button id = 'start_stop'
onClick = {
this.handleTimer
} > Start / Pause < /button> <
button id = 'reset'
onClick = {
this.init
} > Reset < /button> <
/div>
)
}
}
ReactDOM.render( < Pomodoro / > , document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="app"></div>
Upvotes: 3