<commit_before>import React, { Component } from 'react';
import { func, shape, string } from 'prop-types';

import { zeroPad } from 'services/string';
import { Button, Counter, TaskName } from './Timer.style';

class Timer extends Component {
  constructor(props) {
    super(props);

    const { task: { duration, name } } = props;
    const [hours, minutes] = duration.split(':');
    this.state = {
      seconds: Number(hours) * 3600 + Number(minutes) * 60,
      name,
    };
  }

  componentDidMount() {
    this.startTick();
  }

  componentWillUnmount() {
    clearInterval(this.state.timerID);
  }

  tick() {
    this.setState(({ seconds }) => {
      if (seconds === 0) {
        clearInterval(this.state.timerID);
      }

      return {
        seconds: seconds > 0 ? seconds - 1 : 0,
      };
    });
  }

  startTick = () => {
    this.setState({
      timerID: setInterval(
        () => this.tick(),
        1000
      ),
    });
  };

  stopTick = () => {
    clearInterval(this.state.timerID);
    this.setState({ timerID: null });
  }

  formatCount() {
    const totalSec = this.state.seconds;
    const hours = Math.floor(totalSec / 3600);
    const minutes = Math.floor((totalSec - hours * 3600) / 60);
    const seconds = totalSec - (hours * 3600 + minutes * 60);
    return `${zeroPad(hours)}:${zeroPad(minutes)}:${zeroPad(seconds)}`;
  }

  render() {
    return (
      <div>
        <TaskName>{this.state.name}</TaskName>
        <Counter>{this.formatCount()}</Counter><commit_msg>Fixes #1: Added desktop Notification<commit_after>import React, { Component } from 'react';
import { func, shape, string } from 'prop-types';

import { zeroPad } from 'services/string';
import { Button, Counter, TaskName } from './Timer.style';

class Timer extends Component {
  constructor(props) {
    super(props);

    const { task: { duration, name } } = props;
    const [hours, minutes] = duration.split(':');
    this.state = {
      seconds: Number(hours) * 3600 + Number(minutes) * 60,
      name,
    };
  }

  componentDidMount() {
    this.startTick();
  }

  componentWillUnmount() {
    clearInterval(this.state.timerID);
  }

  tick() {
    this.setState(({ seconds, name }) => {
      if (seconds === 0) {
        clearInterval(this.state.timerID);
        this.showNotification(name);
      }

      return {
        seconds: seconds > 0 ? seconds - 1 : 0,
      };
    });
  }

  showNotification(taskName) {
    if (!("Notification" in window)) {
      return null;
    }

    if (Notification.permission === 'granted') {
      new Notification(`${taskName} is over!`);
    } else if (Notification.permission !== 'denied') {
      Notification.requestPermission((permission) => {
        if(!('permission' in Notification)) {
          Notification.permission = permission;
        }

        if (permission === 'granted') {
          new Notification(`${taskName} is over!`);
        }
      });
    }
  }

  startTick = () => {
    this.setState({
      timerID: setInterval(
        () => this.tick(),
        1000
      ),
    });
  };

  stopTick = () => {
    clearInterval(this.state.timerID);
    this.setState({ timerID: null });
  }

  formatCount() {
    const totalSec = this.state.seconds;
    const hours = Math.floor(totalSec / 3600);
    const minutes = Math.floor((totalSec - hours * 3600) / 60);
    const seconds = totalSec - (hours * 3600 + minutes * 60);
    return `${zeroPad(hours)}:${zeroPad(minutes)}:${zeroPad(seconds)}`;
  }

  render() {
    return (
      <div>
        <TaskName>{this.state.name}</TaskName>
        <Counter>{this.formatCount()}</Counter>
{'fraction_non_alphanumeric': 0.16376210235131397, 'fraction_numerical': 0.016874135546334715, 'mean_word_length': 2.548577036310108, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 24, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2987717', 'n_tokens_mistral': 1194, 'n_tokens_neox': 1109, 'n_words': 236}