Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 26.9k
Toast for Service Worker#2426
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Toast for Service Worker #2426
Changes from all commits
48585db13faa18e2e8f91276763c08d05cf3b60e32873a617File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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; | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe add a | ||
| } | ||
| .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; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 | ||
| ); | ||
| } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe better adding space between functions? | ||
| componentWillUnmount() { | ||
| clearTimeout(this.timeout); | ||
| } | ||
| render() { | ||
| return ( | ||
| <div className={`Toast ${this.state.active ? 'active' : 'inactive'}`}> | ||
| <span className="Toast-text"> | ||
| {this.props.children} | ||
| </span> | ||
| <button className="Toast-button" onClick={this.close}>Dismiss</button> | ||
| </div> | ||
| ); | ||
| } | ||
| } | ||
| Toast.defaultProps = { | ||
| timeout: 3000, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. A 3s timeout is consistent with some of the other implementations that have opted for this pattern in case anyone is wondering: https://github.com/GoogleChrome/voice-memos/blob/bcb225a41d3dfcec5e9805adf33d27995840c9f0/src/scripts/libs/Toaster.js#L41.
| ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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( | ||
| <Toast> | ||
| {message} | ||
| </Toast>, | ||
| 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( | ||
| <span> | ||
| Development mode started.{' '} | ||
| <a | ||
| href="https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md" | ||
| > | ||
| Read Me | ||
| </a> | ||
| </span> | ||
| ); | ||
| } | ||
| } | ||
| 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.'); | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Possible UX improvements:
New content is available, <aonclick="window.location.reload()" >please refresh</a>.
ContributorAuthor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. #2755 closed BTW | ||
| } 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.' | ||
| ); | ||
| }); | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth name spacing this, if there is any expectation the toast will appear in production?
.cra-Toastmaybe ?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The idea is to use this as a template for the user to customize it. So I think it's okay to leave it not namespaced. CMIIW