Adding PWA install prompt
This commit is contained in:
parent
589b1aa9e0
commit
a2b9808613
@ -10,6 +10,7 @@ import style from './style.css';
|
||||
|
||||
import Form from 'components/Form';
|
||||
import Message from 'components/Message';
|
||||
import InstallPrompt from 'components/InstallPrompt';
|
||||
import { demoImage } from 'devel';
|
||||
|
||||
const syntaxes = {
|
||||
@ -24,11 +25,13 @@ class App extends React.PureComponent {
|
||||
|
||||
componentDidMount() {
|
||||
window.addEventListener('hashchange', this.handleHashChange);
|
||||
window.addEventListener('beforeinstallprompt', this.handleInstallPrompt);
|
||||
this.handleHashChange();
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window.removeEventListener('hashchange', this.handleHashChange);
|
||||
window.removeEventListener('beforeinstallprompt', this.handleInstallPrompt);
|
||||
}
|
||||
|
||||
async setSvgUrl() {
|
||||
@ -97,6 +100,14 @@ class App extends React.PureComponent {
|
||||
}
|
||||
}
|
||||
|
||||
handleInstallPrompt = event => {
|
||||
event.preventDefault();
|
||||
|
||||
this.setState({
|
||||
installPrompt: event
|
||||
});
|
||||
}
|
||||
|
||||
handleSubmit = ({expr, syntax}) => {
|
||||
if (expr) {
|
||||
const params = new URLSearchParams({ syntax, expr });
|
||||
@ -150,8 +161,30 @@ class App extends React.PureComponent {
|
||||
this.handleHashChange();
|
||||
}
|
||||
|
||||
handleInstallReject = () => {
|
||||
this.setState({ installPrompt: null });
|
||||
}
|
||||
|
||||
handleInstallAccept = async () => {
|
||||
const { installPrompt } = this.state;
|
||||
|
||||
this.setState({ installPrompt: null });
|
||||
installPrompt.prompt();
|
||||
}
|
||||
|
||||
render() {
|
||||
const { SVG, loading, loadingFailed, svgUrl, pngUrl, permalinkUrl, syntax, expr, image } = this.state;
|
||||
const {
|
||||
SVG,
|
||||
loading,
|
||||
loadingFailed,
|
||||
svgUrl,
|
||||
pngUrl,
|
||||
permalinkUrl,
|
||||
syntax,
|
||||
expr,
|
||||
image,
|
||||
installPrompt
|
||||
} = this.state;
|
||||
const downloadUrls = [
|
||||
svgUrl,
|
||||
pngUrl
|
||||
@ -181,6 +214,9 @@ class App extends React.PureComponent {
|
||||
<SVG data={ image } ref={ this.image }/>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
installPrompt && <InstallPrompt onAccept={ this.handleInstallAccept } onReject={ this.handleInstallReject } />
|
||||
}
|
||||
</React.Fragment>;
|
||||
}
|
||||
}
|
||||
|
31
src/components/InstallPrompt/__snapshots__/test.js.snap
Normal file
31
src/components/InstallPrompt/__snapshots__/test.js.snap
Normal file
@ -0,0 +1,31 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`InstallPrompt rendering 1`] = `
|
||||
<div
|
||||
className="install"
|
||||
>
|
||||
<p
|
||||
className="cta"
|
||||
>
|
||||
<Trans>
|
||||
Add Regexper to your home screen?
|
||||
</Trans>
|
||||
</p>
|
||||
<div
|
||||
className="actions"
|
||||
>
|
||||
<button
|
||||
className="primary"
|
||||
>
|
||||
<Trans>
|
||||
Add It
|
||||
</Trans>
|
||||
</button>
|
||||
<button>
|
||||
<Trans>
|
||||
No Thanks
|
||||
</Trans>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
23
src/components/InstallPrompt/index.js
Normal file
23
src/components/InstallPrompt/index.js
Normal file
@ -0,0 +1,23 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { translate, Trans } from 'react-i18next';
|
||||
|
||||
import style from './style.css';
|
||||
|
||||
const InstallPrompt = ({ onAccept, onReject }) => (
|
||||
<div className={ style.install }>
|
||||
<p className={ style.cta }><Trans>Add Regexper to your home screen?</Trans></p>
|
||||
<div className={ style.actions }>
|
||||
<button className={ style.primary } onClick={ onAccept }><Trans>Add It</Trans></button>
|
||||
<button onClick={ onReject }><Trans>No Thanks</Trans></button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
InstallPrompt.propTypes = {
|
||||
onAccept: PropTypes.func.isRequired,
|
||||
onReject: PropTypes.func.isRequired
|
||||
};
|
||||
|
||||
export default translate()(InstallPrompt);
|
||||
export { InstallPrompt };
|
38
src/components/InstallPrompt/style.css
Normal file
38
src/components/InstallPrompt/style.css
Normal file
@ -0,0 +1,38 @@
|
||||
@import url('../../globals.css');
|
||||
|
||||
.install {
|
||||
position: fixed;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
background: var(--color-tan);
|
||||
color: var(--color-black);
|
||||
}
|
||||
|
||||
.cta {
|
||||
margin: 0;
|
||||
padding: var(--spacing-margin);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.actions {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: space-evenly;
|
||||
padding: var(--spacing-margin);
|
||||
|
||||
& button {
|
||||
font-size: inherit;
|
||||
line-height: 2.8rem;
|
||||
border: 0 none;
|
||||
background: var(--color-green) var(--gradient-green);
|
||||
color: var(--color-black);
|
||||
cursor: pointer;
|
||||
padding: 0;
|
||||
width: 40vw;
|
||||
|
||||
&.primary {
|
||||
font-weight: bold;
|
||||
}
|
||||
}
|
||||
}
|
14
src/components/InstallPrompt/test.js
Normal file
14
src/components/InstallPrompt/test.js
Normal file
@ -0,0 +1,14 @@
|
||||
import React from 'react';
|
||||
import { shallow } from 'enzyme';
|
||||
|
||||
import { InstallPrompt } from 'components/InstallPrompt';
|
||||
import { translate } from '__mocks__/i18n';
|
||||
|
||||
describe('InstallPrompt', () => {
|
||||
test('rendering', () => {
|
||||
const component = shallow(
|
||||
<InstallPrompt t={ translate }/>
|
||||
);
|
||||
expect(component).toMatchSnapshot();
|
||||
});
|
||||
});
|
@ -1,4 +1,6 @@
|
||||
404 Page Not Found: '404: Page Not Found'
|
||||
Add It: Add It
|
||||
Add Regexper to your home screen?: Add Regexper to your home screen?
|
||||
An error has occurred: An error has occurred
|
||||
Created by <1>Jeff Avallone</1>: Created by <1>Jeff Avallone</1>
|
||||
Display: Display
|
||||
@ -6,6 +8,7 @@ Download PNG: Download PNG
|
||||
Download SVG: Download SVG
|
||||
Enter regular expression to display: Enter regular expression to display
|
||||
Generated images licensed: 'Generated images licensed: <1><0></0></1>'
|
||||
No Thanks: No Thanks
|
||||
Permalink: Permalink
|
||||
Privacy Policy: Privacy Policy
|
||||
Privacy Policy Content: >
|
||||
|
Loading…
Reference in New Issue
Block a user