Я работаю над React. js Pomodoro Timer и хочу сделать как веб-версию, так и расширение Chrome.
В настоящее время мое веб-приложение работает как предназначен для тикающего таймера, воспроизведения звука и переключения на второй таймер.
Когда я попытался заставить его работать как всплывающее окно в Chrome, я быстро обнаружил, что таймер не сохраняется когда вы щелкаете от всплывающего окна. Мои навыки google-fu говорят мне, что мне нужны фоновые скрипты ... и, возможно, использовать локальное хранилище или сообщения или слушатели .. . Я новичок в React / JS и ничего не знал о Chrome Extensions до начала этого проекта.
Я попытался начать с sendMessage, чтобы отправить что-то в фоновый режим. js. Но я не уверен, какой из моих кодов мне нужно перейти в фоновый режим. js. Возможно, что-то связанное с intervalID?
Приложение. js (основная часть скрипта для моего всплывающего окна)
import React, { useState, useEffect, useRef } from "react";
import Work from "./components/Work";
import Break from "./components/Break";
import Countdown from "./components/Countdown";
import "./App.css";
function App() {
const audioElement = useRef(null);
const [currentTimerType, setCurrentTimerType] = useState("Work");
const [intervalId, setIntervalId] = useState(null);
const [workTime, setWorkTime] = useState(60 * 25); // time in seconds
const [breakTime, setBreakTime] = useState(300);
const [countdown, setCountdown] = useState(workTime);
// Call this when the pop-up is shown
chrome.runtime.sendMessage({ cmd: "GET_TIME" }, response => {
if (response.time) {
// DO SOMETHING HERE
}
});
// Change countdown when workTime changes
useEffect(() => {
setCountdown(workTime);
}, [workTime]);
const lowerWorkTimeByOneMinute = () => {
const newWorkTime = workTime - 60;
if (newWorkTime < 0) {
setWorkTime(0);
} else if (newWorkTime === 0) {
return;
} else {
setWorkTime(newWorkTime);
}
};
const raiseWorkTimeByOneMinute = () => {
const newWorkTime = workTime + 60;
if (newWorkTime <= 60 * 60) {
setWorkTime(newWorkTime);
}
};
const isStarted = intervalId != null;
// if countdown is zero, change work to break or break to work
// TODO add popup alert
// TODO add button click between sessions
useEffect(() => {
if (countdown === 0) {
audioElement.current.play();
if (currentTimerType === "Work") {
setCurrentTimerType("Break");
setCountdown(breakTime);
} else if (currentTimerType === "Break") {
setCurrentTimerType("Work");
setCountdown(workTime);
}
}
}, [breakTime, currentTimerType, workTime, countdown]);
const handleStartStopClick = () => {
if (isStarted) {
// if timer is started
// we want to stop and clear
clearInterval(intervalId);
setCountdown(workTime);
setCurrentTimerType("Work");
setIntervalId(null);
} else {
// if timer is stopped:
// lower countdown for each second
// 1000 ms is 1 second
const newIntervalId = setInterval(() => {
setCountdown(prevCountdown => prevCountdown - 1);
// save to local
// chrome.storage.local.set({'countdown': countdown})
// console.log(chrome.storage.local.get({'countdown'}))
}, 100); // TODO reset to 1000
setIntervalId(newIntervalId);
}
};
const handleResetButtonClick = () => {
// reset audio
audioElement.current.load();
// clear the countdown interval
clearInterval(intervalId);
// set the intervalId null
setIntervalId(null);
// set the timertype to "Work"
setCurrentTimerType("Work");
// reset the workTime to 25 minutes
setWorkTime(25 * 60);
// reset the breakTime to 5
setBreakTime(60 * 5);
// reset the timer to 25 minutes (initial workTime)
setCountdown(25 * 60);
};
const lowerBreakTimeByOneMinute = () => {
const newBreakTime = breakTime - 60;
if (newBreakTime < 0) {
setBreakTime(0);
} else if (newBreakTime === 0) {
return;
} else {
setBreakTime(newBreakTime);
}
};
const raiseBreakTimeByOneMinute = () => {
const newBreakTime = breakTime + 60;
if (newBreakTime <= 60 * 60) {
setBreakTime(newBreakTime);
}
};
return (
<div className="App">
<Work
workTime={workTime}
lowerWorkTimeByOneMinute={lowerWorkTimeByOneMinute}
raiseWorkTimeByOneMinute={raiseWorkTimeByOneMinute}
/>
<Countdown
workTime={workTime}
breakTime={breakTime}
timerLabel={currentTimerType}
handleStartStopClick={handleStartStopClick}
startStopButtonLabel={isStarted ? "Stop" : "Start"}
countdown={countdown}
/>
<p>
<button id="reset" onClick={handleResetButtonClick}>
Reset
</button>
</p>
<Break
breakTime={breakTime}
lowerBreakTimeByOneMinute={lowerBreakTimeByOneMinute}
raiseBreakTimeByOneMinute={raiseBreakTimeByOneMinute}
/>
<audio id="alarm" ref={audioElement}>
<source src="https://www.soundjay.com/misc/sounds/magic-chime-01.mp3" />
</audio>
</div>
);
}
export default App;