mirror of
https://github.com/franjsco/tomadoro
synced 2025-03-13 00:40:04 +01:00
1 line
20 KiB
Plaintext
1 line
20 KiB
Plaintext
{"version":3,"sources":["sound.mp3","logo.svg","components/Logo.js","components/Box.js","components/Notification.js","App.js","serviceWorker.js","index.js"],"names":["module","exports","Logo","props","defaultClassName","className","this","isStarted","src","logoSVG","alt","title","onClick","switchMode","Component","Box","state","Row","Col","xs","Button","block","size","color","startTimer","disabled","seconds","stopTimer","resetTimer","Notification","ignore","handlePermissionGranted","bind","handlePermissionDenied","handleNotSupported","sendNotification","handleNotificationOnShow","playSound","send","handleNotification","setState","e","tag","console","log","options","Date","now","body","lang","sound","document","getElementById","play","onPermissionGranted","onPermissionDenied","notSupported","onError","timeout","onShow","id","preload","type","hidden","App","appName","pomodoroSeconds","breakSeconds","startClickNotification","started","break","terminatedTimer","pomodoroMode","breakMode","formatMinute","s","interval","setInterval","tick","clearInterval","flag","Container","sm","offset","md","lg","href","Boolean","window","location","hostname","match","ReactDOM","render","navigator","serviceWorker","ready","then","registration","unregister"],"mappings":"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","file":"static/js/main.07f9db80.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/sound.ec792557.mp3\";","module.exports = __webpack_public_path__ + \"static/media/logo.08ea9508.svg\";","import React, { Component } from 'react';\nimport logoSVG from '../logo.svg';\nimport './Logo.css';\n\nclass Logo extends Component {\n constructor(props) {\n super(props);\n this.defaultClassName = 'App-logo-rotation';\n }\n\n render() {\n return (\n <img\n className={`App-logo ${this.props.isStarted ? this.defaultClassName: ''}`}\n src={logoSVG}\n alt=\"Tomato\"\n title=\"Click on the tomato to change modes\"\n onClick={this.props.switchMode}\n ></img>\n )\n }\n\n}\n\nexport default Logo;","import React, { Component } from 'react';\nimport { Button, Row, Col } from 'reactstrap';\nimport './Box.css';\n\nclass Box extends Component {\n\n constructor(props) {\n super(props);\n this.state = {};\n }\n\n render() {\n return (\n <div className=\"box\">\n <Row>\n <Col xs=\"12\">\n <Button\n className=\"button\"\n block\n size=\"lg\"\n color=\"success\"\n onClick={this.props.startTimer}\n disabled={this.props.isStarted || this.props.seconds===0}\n >\n START\n </Button>\n </Col>\n </Row>\n <Row>\n <Col xs=\"6\">\n <Button\n className=\"button\"\n color=\"danger\"\n size=\"lg\"\n onClick={this.props.stopTimer}\n disabled={!this.props.isStarted}\n >\n STOP\n </Button>\n </Col>\n <Col xs=\"6\">\n <Button\n className=\"button\"\n color=\"secondary\"\n size=\"lg\"\n onClick={this.props.resetTimer}\n disabled={this.props.isStarted}\n >\n RESET\n </Button>\n </Col>\n </Row>\n </div>\n );\n }\n }\n \n export default Box;","import React, { Component } from 'react';\nimport WebNotification from 'react-web-notification';\nimport sound from '../sound.mp3';\n\nclass Notification extends Component {\n constructor(props) {\n super(props);\n\n this.state = {\n ignore: true,\n title: ''\n };\n\n this.handlePermissionGranted = this.handlePermissionGranted.bind(this);\n this.handlePermissionDenied = this.handlePermissionDenied.bind(this);\n this.handleNotSupported = this.handleNotSupported.bind(this);\n this.sendNotification = this.sendNotification.bind(this);\n this.handleNotificationOnShow = this.handleNotificationOnShow.bind(this);\n this.playSound = this.playSound.bind(this);\n }\n\n componentDidUpdate() {\n if(this.props.send) {\n this.sendNotification()\n this.props.handleNotification(false)\n };\n }\n\n handlePermissionGranted() {\n this.setState({\n ignore: false\n });\n }\n\n handlePermissionDenied() {\n this.setState({\n ignore: true\n });\n }\n\n handleNotSupported() {\n this.setState({\n ignore: true\n });\n }\n\n handleNotificationOnError(e, tag) {\n console.log(e, 'Notification error tag:' + tag);\n }\n\n handleNotificationOnShow() {\n this.playSound();\n }\n\n sendNotification() {\n if (this.state.ignore) {\n return;\n }\n\n const title = 'tomadoro';\n const body = 'Time is Up! 🍅';\n const tag = Date.now();\n\n const options = {\n tag: tag,\n body: body,\n lang: 'en',\n sound: { sound }\n };\n\n this.setState({\n title: title,\n options: options\n });\n }\n\n playSound() {\n document.getElementById('sound').play();\n }\n\n render() {\n return(\n <div>\n <WebNotification\n ignore={this.state.ignore}\n onPermissionGranted={this.handlePermissionGranted}\n onPermissionDenied={this.handlePermissionDenied}\n notSupported={this.handleNotSupported}\n onError={this.onError}\n timeout={5000}\n title={this.state.title}\n options={this.state.options}\n onShow={this.handleNotificationOnShow}\n >\n </WebNotification>\n\n <audio id='sound' preload='auto'>\n <source src={sound} type='audio/mpeg' />\n <embed hidden src={sound} />\n </audio>\n </div>\n );\n }\n}\n\nexport default Notification;","import React, { Component } from 'react';\nimport { Container, Row, Col } from 'reactstrap';\nimport Logo from './components/Logo';\nimport Box from './components/Box';\nimport Notification from './components/Notification';\nimport './App.css';\n\nclass App extends Component {\n constructor(props) {\n super(props);\n\n this.appName = 'tomadoro';\n this.pomodoroSeconds = 1500;\n this.breakSeconds = 300;\n\n this.state = {\n startClickNotification: false, // TODO: refactoring identificativo \n seconds: 0,\n started: false,\n break: false,\n sendNotification: false\n };\n\n // binding\n this.startTimer = this.startTimer.bind(this);\n this.stopTimer = this.stopTimer.bind(this);\n this.resetTimer = this.resetTimer.bind(this);\n this.terminatedTimer = this.terminatedTimer.bind(this);\n this.pomodoroMode = this.pomodoroMode.bind(this);\n this.breakMode = this.breakMode.bind(this);\n this.switchMode = this.switchMode.bind(this);\n this.formatMinute = this.formatMinute.bind(this);\n this.handleNotification = this.handleNotification.bind(this);\n }\n\n componentWillMount() {\n this.pomodoroMode();\n }\n\n formatMinute(s) {\n return (s - (s %= 60)) / 60 + (9 < s ? ':' : ':0') + s;\n }\n\n tick() {\n this.setState(state => ({\n seconds: state.seconds - 1\n }));\n\n document.title = `(${this.formatMinute(this.state.seconds)}) ${this.appName}`;\n\n if (this.state.seconds === 0) {\n this.stopTimer();\n this.terminatedTimer();\n }\n }\n\n startTimer() {\n this.setState({\n started: true,\n startClickNotification: true\n });\n\n this.interval = setInterval(() => this.tick(), 1000);\n }\n\n stopTimer() {\n this.setState({\n started: false\n });\n\n clearInterval(this.interval);\n }\n\n resetTimer() {\n if (this.state.break) {\n this.breakMode();\n } else {\n this.pomodoroMode();\n }\n\n document.title = this.appName;\n }\n\n terminatedTimer() {\n this.setState({\n sendNotification: true\n });\n\n this.switchMode();\n }\n\n pomodoroMode() {\n this.setState({\n seconds: this.pomodoroSeconds,\n break: false\n });\n }\n\n breakMode() {\n this.setState({\n seconds: this.breakSeconds,\n break: true\n });\n }\n\n switchMode() { // TODO: refactoring naming\n if (this.state.break && !this.state.started) {\n this.pomodoroMode();\n } else if (!this.state.break && !this.state.started) {\n this.breakMode();\n }\n }\n\n handleNotification(flag) {\n this.setState({\n sendNotification: flag\n });\n }\n\n render() {\n return (\n <div className=\"App\">\n <div className=\"App-header\">\n tomadoro\n </div>\n\n <Container>\n <Row>\n <Col>\n <Logo\n isStarted={this.state.started}\n switchMode={this.switchMode}\n />\n </Col>\n </Row>\n\n <Row>\n <Col>\n <p className=\"timer\">\n {this.formatMinute(this.state.seconds)}\n </p>\n </Col>\n </Row>\n\n <Row>\n <Col\n sm={{ size: 10, offset: 1 }}\n md={{ size: 8, offset: 2 }}\n lg={{ size: 6, offset: 3 }}\n >\n <Box\n startTimer={this.startTimer}\n stopTimer={this.stopTimer}\n isStarted={this.state.started}\n resetTimer={this.resetTimer}\n seconds={this.state.seconds}\n />\n </Col>\n </Row>\n </Container>\n\n { // notification\n this.state.startClickNotification ? (\n <Notification\n send={this.state.sendNotification}\n handleNotification={this.handleNotification} />)\n : ''}\n\n <div className=\"footer\">\n <p>\n <a href=\"https://github.com/frsposito/tomadoro\">tomadoro</a>{` `}\n by <a href=\"https://github.com/frsposito\">Francesco Esposito</a>\n </p>\n </div>\n </div>\n );\n }\n}\n\nexport default App;\n","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.1/8 is considered localhost for IPv4.\n window.location.hostname.match(\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\n )\n);\n\nexport function register(config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' +\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl, config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl, config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl)\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (\n response.status === 404 ||\n (contentType != null && contentType.indexOf('javascript') === -1)\n ) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log(\n 'No internet connection found. App is running in offline mode.'\n );\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport 'bootstrap/dist/css/bootstrap.min.css';\nimport App from './App';\nimport * as serviceWorker from './serviceWorker';\n\nReactDOM.render(<App />, document.getElementById('root'));\n\n// If you want your app to work offline and load faster, you can change\n// unregister() to register() below. Note this comes with some pitfalls.\n// Learn more about service workers: https://bit.ly/CRA-PWA\nserviceWorker.unregister();\n"],"sourceRoot":""} |