Skip to content
Snippets Groups Projects
Commit cf38d62d authored by Duc Phan's avatar Duc Phan :speech_balloon:
Browse files

Merge branch 'duke' into 'main'

add eyecare mode

See merge request !9
parents ec74bbfe 745bda5c
No related branches found
No related tags found
1 merge request!9add eyecare mode
...@@ -14,8 +14,8 @@ function StudyMethod({method, setMethod }) { ...@@ -14,8 +14,8 @@ function StudyMethod({method, setMethod }) {
<option value="pomodoro">Pomodoro</option> <option value="pomodoro">Pomodoro</option>
<option value="flowtime">Flowtime Technique</option> <option value="flowtime">Flowtime Technique</option>
<option value="ultradian">Ultradian Sprints</option> <option value="ultradian">Ultradian Sprints</option>
<option value = "eyecare">Eye Care</option>
</select> </select>
<button onClick={setMethod(method)}>Confirm method</button>
</div> </div>
); );
} }
......
...@@ -8,28 +8,31 @@ import { useState, useRef, useEffect } from "react"; ...@@ -8,28 +8,31 @@ import { useState, useRef, useEffect } from "react";
function TimeDuration({ hour, setHour, minute, setMinute, method }) { function TimeDuration({ hour, setHour, minute, setMinute, method }) {
const [second, setSecond] = useState(0); const [second, setSecond] = useState(0);
const [targetSeconds, setTargetSeconds] = useState(0); const [targetSeconds, setTargetSeconds] = useState(0);
const [isRunning, setIsRunning] = useState(false) const [isRunning, setIsRunning] = useState(false);
const [mode, setMode] = useState("work") const [mode, setMode] = useState("work");
const intervalID = useRef(null); // This holds the interval ID across renders const intervalID = useRef(null); // This holds the interval ID across renders
const handleTimeInput = () => { const handleTimeInput = () => {
const second = convertInput(hour, minute); const second = convertInput(hour, minute);
return second return second;
} };
const notifyUser = async () => { const notifyUser = async () => {
//notify between work and break if (Notification.permission !== "granted") {
const message = mode !== "work" await Notification.requestPermission();
? "Take a break!" }
: "Time to work!";
if (Notification.permission === "granted") { if (Notification.permission === "granted") {
new Notification(message); let message;
} else if (Notification.permission !== "denied") { if (method == "pomodoro") {
const permission = await Notification.requestPermission(); message = mode === "work" ? "Take a 5 minutes break!" : "Back to work!";
if (permission === "granted") { } else if (method == "eyecare") {
new Notification(message); message = mode === "work" ? "Rest your eyes" : "Back to work!";
} else {
message = mode !== "work" ? "Take a break!" : "Time to work!";
} }
new Notification(message);
} }
}; };
...@@ -47,19 +50,24 @@ function TimeDuration({hour, setHour, minute, setMinute, method}) { ...@@ -47,19 +50,24 @@ function TimeDuration({hour, setHour, minute, setMinute, method}) {
}; };
useEffect(() => { useEffect(() => {
if(!isRunning) return; //avooid shooting this when time is 0 and no method initialized if (!isRunning) return;
if (second === 0 && intervalID.current) { if (second === 0 && intervalID.current) {
(async () => {
await notifyUser(); // wait for the notification process to finish
clearInterval(intervalID.current); clearInterval(intervalID.current);
notifyUser();
if (method !== "regular") { if (method !== "regular") {
if (mode === "work") { if (mode === "work") {
// Subtract 25 min from target if (method === "pomodoro") {
setTargetSeconds(prev => prev - 25 * 60); setTargetSeconds((prev) => prev - 25*60);
} else if (method === "eyecare") {
setTargetSeconds((prev) => prev - 20 * 60);
}
startBreak(); startBreak();
} else { } else {
startWork(); startWork();
} }
} }
})(); // immediately invoked function
} }
}, [second, mode, method, isRunning]); }, [second, mode, method, isRunning]);
...@@ -75,15 +83,14 @@ function TimeDuration({hour, setHour, minute, setMinute, method}) { ...@@ -75,15 +83,14 @@ function TimeDuration({hour, setHour, minute, setMinute, method}) {
function runTime() { function runTime() {
intervalID.current = setInterval(() => { intervalID.current = setInterval(() => {
setSecond(prev => { setSecond((prev) => {
if (prev == 0) { if (prev == 0) {
clearInterval(intervalID.current); clearInterval(intervalID.current);
return 0; return 0;
} }
return prev - 1 return prev - 1;
}) });
}, 1000 }, 1000);
)
} }
function startTimer() { function startTimer() {
...@@ -94,8 +101,7 @@ function TimeDuration({hour, setHour, minute, setMinute, method}) { ...@@ -94,8 +101,7 @@ function TimeDuration({hour, setHour, minute, setMinute, method}) {
const totalStudyTime = handleTimeInput(); // the goal the user entered const totalStudyTime = handleTimeInput(); // the goal the user entered
setTargetSeconds(totalStudyTime); setTargetSeconds(totalStudyTime);
startWork(); startWork();
} } else {
else{
const totalSec = handleTimeInput(); const totalSec = handleTimeInput();
setSecond(totalSec); //set the second only when the user prompt inputs setSecond(totalSec); //set the second only when the user prompt inputs
runTime(); runTime();
...@@ -103,36 +109,44 @@ function TimeDuration({hour, setHour, minute, setMinute, method}) { ...@@ -103,36 +109,44 @@ function TimeDuration({hour, setHour, minute, setMinute, method}) {
} }
function startWork() { function startWork() {
if(method == "pomodoro"){
setMode("work"); setMode("work");
if (method == "pomodoro") {
setHour(0); setHour(0);
setMinute(25); setMinute(25);
setSecond(25 *60 ); // 25 minutes setSecond(25 *60 ); // 25 minutes
runTime(); runTime();
} else if (method == "eyecare"){
setHour(0);
setMinute(20);
setSecond(20 * 60); // 20 minutes
runTime();
} }
else if (method == "flowtime") { else if (method == "flowtime") {
runTime() runTime();
} else if (method == "ultradian") { } else if (method == "ultradian") {
runTime() runTime();
} }
} }
function startBreak() { function startBreak() {
if(method == "pomodoro"){
setMode("break"); setMode("break");
if (method == "pomodoro") {
setHour(0); setHour(0);
setMinute(5); setMinute(5);
setSecond(5 *60); // 5 minutes setSecond(5 *60); // 5 minutes
runTime(); runTime();
} } else if (method == "flowtime") {
else if (method == "flowtime"){ runTime();
runTime()
} else if (method == "ultradian") { } else if (method == "ultradian") {
runTime();
} else if (method == "eyecare"){
setHour(0);
setMinute(0);
setSecond(20); //the eyes need to rest for 20 seconds
runTime() runTime()
} }
} }
return ( return (
<div className="time-duration-box"> <div className="time-duration-box">
<h3>Time Duration ({mode})</h3> <h3>Time Duration ({mode})</h3>
...@@ -155,14 +169,31 @@ function TimeDuration({hour, setHour, minute, setMinute, method}) { ...@@ -155,14 +169,31 @@ function TimeDuration({hour, setHour, minute, setMinute, method}) {
/> />
</div> </div>
<button onClick={startTimer}>Start timer</button> <button onClick={startTimer}>Start timer</button>
<button onClick={() => { clearInterval(intervalID.current); setIsRunning(false); }}>Stop timer</button> <button
onClick={() => {
clearInterval(intervalID.current);
setIsRunning(false);
}}
>
Stop timer
</button>
<button onClick={runTime}>Resume</button> <button onClick={runTime}>Resume</button>
<button onClick={() => { clearInterval(intervalID.current); setSecond(0); setIsRunning(false); }}>Reset timer</button> <button
onClick={() => {
clearInterval(intervalID.current);
setSecond(0);
setIsRunning(false);
}}
>
Reset timer
</button>
<h3>Hour: {Math.floor(second / 3600)}</h3> <h3>Hour: {Math.floor(second / 3600)}</h3>
<h3>Minute: {Math.floor((second % 3600) / 60)}</h3> <h3>Minute: {Math.floor((second % 3600) / 60)}</h3>
<h3>Second: {second % 60}</h3> <h3>Second: {second % 60}</h3>
{method === "pomodoro" && ( {method === "pomodoro" && (
<h4>Remaining Study Time: {Math.floor(targetSeconds / 60) - 25 } minutes</h4> <h4>
Remaining Study Time: {Math.floor(targetSeconds / 60) - 25} minutes
</h4>
)} )}
</div> </div>
); );
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment