React Chrome Extension: что мне нужно перейти в фоновый режим, чтобы таймер продолжал действовать при закрытии всплывающего окна? - PullRequest
0 голосов
/ 13 июля 2020

Я работаю над 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...