diff --git a/packages/react-dev-utils/ModuleScopePlugin.js b/packages/react-dev-utils/ModuleScopePlugin.js index 101a30a1fb9..d7aeea3450d 100644 --- a/packages/react-dev-utils/ModuleScopePlugin.js +++ b/packages/react-dev-utils/ModuleScopePlugin.js @@ -50,8 +50,7 @@ class ModuleScopePlugin { // Error if in a parent directory of src/ const requestRelative = path.relative(appSrc, requestFullPath); if ( - requestRelative.startsWith('../') || - requestRelative.startsWith('..\\') + requestRelative.startsWith('../') || requestRelative.startsWith('..\\') ) { callback( new Error( diff --git a/packages/react-scripts/template/src/Toast.css b/packages/react-scripts/template/src/Toast.css new file mode 100644 index 00000000000..31ddd15a7d0 --- /dev/null +++ b/packages/react-scripts/template/src/Toast.css @@ -0,0 +1,39 @@ +.Toast { + position: fixed; + bottom: 0; + left: 0; + right: 0; + padding: 16px; + margin: auto; + transition: 250ms; + background: #222; + color: white; + line-height: 24px; + border-top-left-radius: 2px; + border-top-right-radius: 2px; + display: flex; +} + +.Toast.active { + transform: translateY(0); +} + +.Toast.inactive { + transform: translateY(100%); +} + +.Toast a, +.Toast-button { + padding: 0; + background: transparent; + border: 0; + color: #61dafb; + font-size: inherit; + line-height: inherit; + text-transform: uppercase; + text-decoration: none; +} + +.Toast-text { + flex: 1; +} \ No newline at end of file diff --git a/packages/react-scripts/template/src/Toast.js b/packages/react-scripts/template/src/Toast.js new file mode 100644 index 00000000000..f5eee07f0c2 --- /dev/null +++ b/packages/react-scripts/template/src/Toast.js @@ -0,0 +1,42 @@ +import React from 'react'; +import './Toast.css'; + +export default class Toast extends React.Component { + state = { + active: true, + }; + + close = () => { + clearTimeout(this.timeout); + this.setState({ + active: false, + }); + }; + componentDidMount() { + this.timeout = setTimeout( + () => { + this.setState({ + active: false, + }); + }, + this.props.timeout + ); + } + componentWillUnmount() { + clearTimeout(this.timeout); + } + render() { + return ( +
+ + {this.props.children} + + +
+ ); + } +} + +Toast.defaultProps = { + timeout: 3000, +}; diff --git a/packages/react-scripts/template/src/registerServiceWorker.js b/packages/react-scripts/template/src/registerServiceWorker.js index 4a3ccf02124..d1ac525c36f 100644 --- a/packages/react-scripts/template/src/registerServiceWorker.js +++ b/packages/react-scripts/template/src/registerServiceWorker.js @@ -7,6 +7,32 @@ // To learn more about the benefits of this model, read https://goo.gl/KwvDNy. // This link also includes instructions on opting out of this behavior. +import React from 'react'; +import ReactDOM from 'react-dom'; +import Toast from './Toast'; + +const useToast = true; +const domId = 'toast'; +let dom = document.getElementById(domId); + +if (!dom) { + dom = document.createElement('div'); + dom.id = domId; + document.body.appendChild(dom); +} + +function showMessage(message) { + if (useToast) { + ReactDOM.render( + + {message} + , + dom + ); + } else { + console.log(message); + } +} const isLocalhost = Boolean( window.location.hostname === 'localhost' || @@ -41,6 +67,19 @@ export default function register() { } }); } + + if (process.env.NODE_ENV !== 'production') { + showMessage( + + Development mode started.{' '} + + Read Me + + + ); + } } function registerValidSW(swUrl) { @@ -56,12 +95,12 @@ function registerValidSW(swUrl) { // the fresh content will have been added to the cache. // It's the perfect time to display a "New content is // available; please refresh." message in your web app. - console.log('New content is available; please refresh.'); + showMessage('New content is available; please refresh.'); } else { // At this point, everything has been precached. // It's the perfect time to display a // "Content is cached for offline use." message. - console.log('Content is cached for offline use.'); + showMessage('Content is cached for offline use.'); } } }; @@ -93,7 +132,7 @@ function checkValidServiceWorker(swUrl) { } }) .catch(() => { - console.log( + showMessage( 'No internet connection found. App is running in offline mode.' ); });