Секундомер, который работает в фоновом режиме после закрытия расширения Chrome. - PullRequest
0 голосов
/ 11 июля 2019

Я пытаюсь создать расширение секундомера, которое будет работать даже после его закрытия. Я использовал шаблон хром-расширения create-response-app. Я хочу, чтобы можно было открыть секундомер, закрыть «всплывающее окно», снова открыть «всплывающее окно», и секундомер продолжит отсчет. Когда я нажимаю на иконку, появляется «всплывающее окно», я вижу кнопки, на них отображается «00: 00: 00», но секундомер не реагирует на нажатия. Что не так с моим кодом?

manifest.json

{
  "name": "Chrome Extension Webpack",
  "options_page": "options.html",
  "background": {
    "scripts": ["background.bundle.js"],
    "persistent": true
  },
  "browser_action": {
    "default_popup": "popup.html",
    "default_icon": "icon-34.png"
  },
  "icons": {
    "128": "icon-128.png"
  },
  "manifest_version": 2,
  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
}

background.js

import '../img/icon-128.png'
import '../img/icon-34.png'

const isRunning = false;
const startTime = null;
const timer = null;
const timeElapsed = 0;
const delta = null;


/*startTimer*/
startTimer = () => {
    if (!isRunning) {
        startTime = Date.now();
        isRunning = true;
        timer = setInterval(this.updateTimer, 10);
    }
}

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse){
        if(request.msg == "startTimer") {
            startTimer();
        }
    }
);

/*StopTimer*/
stopTimer = () => {
    isRunning = false;
    clearInterval(timer);
}

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse){
        if(request.msg == "stopTimer") {
            stopTimer();
        }
    }
);

/*resetTimer*/
resetTimer = () =>  {
    isRunning = false,
    timeElapsed = 0,
    clearInterval(timer);
}

chrome.runtime.onMessage.addListener(
    function(request, sender, sendResponse){
        if(request.msg == "resetTimer") {
            resetTimer();
        }
    }
);

/*updateTimer*/
updateTimer = () => {
    delta = Date.now() - startTime;
    startTime = Date.now();
}

chrome.runtime.sendMessage({
    type: 'timeElapsed', 
    timeElapsed: timeElapsed + delta
});

/*lapTimer*/
lapTimer = () => {
    chrome.runtime.sendMessage({
        type: 'lapTimer', 
        lapTimer: timeElapsed
    });
}

Секундомер

import React from "react";
import icon from "../../img/icon-128.png"
import { hot } from "react-hot-loader";

class Stopwatch extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      timeElapsed: 0,
      lapTimes: []
    };

    this.startTimer = this.startTimer.bind(this);
    this.stopTimer= this.stopTimer.bind(this);
    this.resetTimer= this.resetTimer.bind(this);
    this.leftPad= this.leftPad.bind(this);
    this.lapTimer = this.lapTimer.bind(this);
  }

  leftPad(width, n) {
    if ((n + '').length > width) {
        return n;
    }

    const padding = new Array(width).join('0');

    return (padding + n).slice(-width);
  };

  componentDidMount() {
    window.chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {       
      if (message.type === "timeElapsed") {          
        this.setState({
          timeElapsed: message.timeElapsed   
        });
      } 
      if (message.type === "lapTimer") {          
        this.setState({
          lapTimes: lapTimes.concat(message.timeElapsed)
        });
      }
    });
  }

  startTimer() {
    chrome.runtime.sendMessage({ 
      msg: "startTimer"
    });
  }

  stopTimer() {
    chrome.runtime.sendMessage({ 
      msg: "stopTimer"
    });
  }

  resetTimer() {
    chrome.runtime.sendMessage({ 
      msg: "resetTimer"
    });
  }

  lapTimer() {
    chrome.runtime.sendMessage({ 
      msg: "lapTimer"
    });
  }

  render() {
    const {lapTimes, timeElapsed} = this.state;
    return (
      <div>
        <TimeElapsed 
          id="timer" 
          timeElapsed={timeElapsed}
          leftPad = {this.leftPad} />
        <button onClick={this.startTimer}>
          Start
        </button>
        <button onClick={this.stopTimer}>
          Stop
        </button>
        <button onClick={this.resetTimer}>
          Reset
        </button>
        <button onClick={this.lapTimer}>
          Lap
        </button>
        {lapTimes.length > 0 && <LapTimes lapTimes={lapTimes} />}
      </div>
    );
  }
}

class TimeElapsed extends React.Component {
  getUnits() {
    const seconds = this.props.timeElapsed / 1000;
    return {
      min: Math.floor(seconds / 60).toString(),
      sec: Math.floor(seconds % 60).toString(),
      msec: (seconds % 1).toFixed(3).substring(2)
    };
  }
  render() {
    const units = this.getUnits();
    return (
      <div id={this.props.id}>
        <span>{this.props.leftPad(2, units.min)}:</span>
        <span>{this.props.leftPad(2, units.sec)}.</span>
        <span>{units.msec}</span>
      </div>
    );
  }
}

class LapTimes extends React.Component {
  render() {
    const rows = this.props.lapTimes.map((lapTime, index) =>
      <tr key={++index}>
        <td>{index}</td>
        <td><TimeElapsed timeElapsed={lapTime} /></td>
      </tr>
    );
    return (
      <table id="lap-times">
        <thead>
          <th>Lap</th>
          <th>Time</th>
        </thead>
        <tbody>{rows}</tbody>
      </table>
    );
  }
}

export default hot(module)(Stopwatch)

popup.js

import Stopwatch from "./popup/Stopwatch.jsx";
import React from "react";
import { render } from "react-dom";

render(
  <Stopwatch/>,
  window.document.getElementById("app-container")
);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...