Adding install prompt link in the header
This commit is contained in:
parent
a23e72d633
commit
d41dad14a1
@ -39,6 +39,9 @@ exports[`Header rendering 1`] = `
|
|||||||
</WithMergedOptions(TransComponent)>
|
</WithMergedOptions(TransComponent)>
|
||||||
</mockConstructor>
|
</mockConstructor>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<LoadNamespace(InstallPrompt) />
|
||||||
|
</li>
|
||||||
<li
|
<li
|
||||||
data-requires-js={true}
|
data-requires-js={true}
|
||||||
>
|
>
|
||||||
@ -87,6 +90,9 @@ exports[`Header rendering with no banner 1`] = `
|
|||||||
</WithMergedOptions(TransComponent)>
|
</WithMergedOptions(TransComponent)>
|
||||||
</mockConstructor>
|
</mockConstructor>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<LoadNamespace(InstallPrompt) />
|
||||||
|
</li>
|
||||||
<li
|
<li
|
||||||
data-requires-js={true}
|
data-requires-js={true}
|
||||||
>
|
>
|
||||||
|
@ -6,6 +6,7 @@ import { withNamespaces, Trans } from 'react-i18next';
|
|||||||
import GitlabIcon from 'react-feather/dist/icons/gitlab';
|
import GitlabIcon from 'react-feather/dist/icons/gitlab';
|
||||||
|
|
||||||
import LocaleSwitcher from 'components/LocaleSwitcher';
|
import LocaleSwitcher from 'components/LocaleSwitcher';
|
||||||
|
import InstallPrompt from 'components/InstallPrompt';
|
||||||
|
|
||||||
import style from './style.module.css';
|
import style from './style.module.css';
|
||||||
|
|
||||||
@ -31,6 +32,9 @@ export const Header = ({ banner }) => (
|
|||||||
<Trans>Privacy Policy</Trans>
|
<Trans>Privacy Policy</Trans>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
<li>
|
||||||
|
<InstallPrompt />
|
||||||
|
</li>
|
||||||
<li data-requires-js>
|
<li data-requires-js>
|
||||||
<LocaleSwitcher />
|
<LocaleSwitcher />
|
||||||
</li>
|
</li>
|
||||||
|
16
src/components/InstallPrompt/__snapshots__/test.js.snap
Normal file
16
src/components/InstallPrompt/__snapshots__/test.js.snap
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||||
|
|
||||||
|
exports[`InstallPrompt rendering 1`] = `""`;
|
||||||
|
|
||||||
|
exports[`InstallPrompt rendering after an install prompt has been requested 1`] = `""`;
|
||||||
|
|
||||||
|
exports[`InstallPrompt rendering after an install prompt has been requested 2`] = `
|
||||||
|
<a
|
||||||
|
href="#install"
|
||||||
|
onClick={[Function]}
|
||||||
|
>
|
||||||
|
<WithMergedOptions(TransComponent)>
|
||||||
|
Add to Home Screen
|
||||||
|
</WithMergedOptions(TransComponent)>
|
||||||
|
</a>
|
||||||
|
`;
|
53
src/components/InstallPrompt/index.js
Normal file
53
src/components/InstallPrompt/index.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { withNamespaces, Trans } from 'react-i18next';
|
||||||
|
|
||||||
|
class InstallPrompt extends React.PureComponent {
|
||||||
|
state = {
|
||||||
|
installPrompt: null
|
||||||
|
}
|
||||||
|
|
||||||
|
componentDidMount() {
|
||||||
|
window.addEventListener('beforeinstallprompt', this.handleInstallPrompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
componentWillUnmount() {
|
||||||
|
window.removeEventListener('beforeinstallprompt', this.handleInstallPrompt);
|
||||||
|
}
|
||||||
|
|
||||||
|
handleInstallPrompt = event => {
|
||||||
|
this.setState({
|
||||||
|
installPrompt: event
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
handleInstall = async event => {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
const { installPrompt } = this.state;
|
||||||
|
|
||||||
|
try {
|
||||||
|
installPrompt.prompt();
|
||||||
|
await installPrompt.userChoice;
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
// User cancelled install
|
||||||
|
}
|
||||||
|
|
||||||
|
this.setState({ installPrompt: null });
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { installPrompt } = this.state;
|
||||||
|
|
||||||
|
if (!installPrompt) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return <a href="#install" onClick={ this.handleInstall }>
|
||||||
|
<Trans>Add to Home Screen</Trans>
|
||||||
|
</a>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export { InstallPrompt };
|
||||||
|
export default withNamespaces()(InstallPrompt);
|
88
src/components/InstallPrompt/test.js
Normal file
88
src/components/InstallPrompt/test.js
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
|
||||||
|
import { InstallPrompt } from 'components/InstallPrompt';
|
||||||
|
|
||||||
|
describe('InstallPrompt', () => {
|
||||||
|
test('rendering', () => {
|
||||||
|
const component = shallow(
|
||||||
|
<InstallPrompt />
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('rendering after an install prompt has been requested', () => {
|
||||||
|
const component = shallow(
|
||||||
|
<InstallPrompt />
|
||||||
|
);
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
|
||||||
|
component.instance().handleInstallPrompt({
|
||||||
|
prompt: jest.fn()
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(component).toMatchSnapshot();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('adding and removing event listener', () => {
|
||||||
|
jest.spyOn(window, 'addEventListener');
|
||||||
|
jest.spyOn(window, 'removeEventListener');
|
||||||
|
|
||||||
|
const component = shallow(
|
||||||
|
<InstallPrompt />
|
||||||
|
);
|
||||||
|
const handleInstallPrompt = component.instance().handleInstallPrompt;
|
||||||
|
|
||||||
|
expect(window.addEventListener).toHaveBeenCalledWith(
|
||||||
|
'beforeinstallprompt',
|
||||||
|
handleInstallPrompt);
|
||||||
|
|
||||||
|
component.unmount();
|
||||||
|
|
||||||
|
expect(window.removeEventListener).toHaveBeenCalledWith(
|
||||||
|
'beforeinstallprompt',
|
||||||
|
handleInstallPrompt);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('accepting install prompt', async () => {
|
||||||
|
const component = shallow(
|
||||||
|
<InstallPrompt />
|
||||||
|
);
|
||||||
|
const promptObj = {
|
||||||
|
prompt: jest.fn(),
|
||||||
|
userChoice: Promise.resolve()
|
||||||
|
};
|
||||||
|
const eventObj = { preventDefault: jest.fn() };
|
||||||
|
|
||||||
|
component.instance().handleInstallPrompt(promptObj);
|
||||||
|
component.find('a').simulate('click', eventObj);
|
||||||
|
|
||||||
|
// Allow async code to run
|
||||||
|
await new Promise(resolve => setTimeout(resolve));
|
||||||
|
|
||||||
|
expect(eventObj.preventDefault).toHaveBeenCalled();
|
||||||
|
expect(promptObj.prompt).toHaveBeenCalled();
|
||||||
|
expect(component.state('installPrompt')).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('rejecting install prompt', async () => {
|
||||||
|
const component = shallow(
|
||||||
|
<InstallPrompt />
|
||||||
|
);
|
||||||
|
const promptObj = {
|
||||||
|
prompt: jest.fn(),
|
||||||
|
userChoice: Promise.reject()
|
||||||
|
};
|
||||||
|
const eventObj = { preventDefault: jest.fn() };
|
||||||
|
|
||||||
|
component.instance().handleInstallPrompt(promptObj);
|
||||||
|
component.find('a').simulate('click', eventObj);
|
||||||
|
|
||||||
|
// Allow async code to run
|
||||||
|
await new Promise(resolve => setTimeout(resolve));
|
||||||
|
|
||||||
|
expect(eventObj.preventDefault).toHaveBeenCalled();
|
||||||
|
expect(promptObj.prompt).toHaveBeenCalled();
|
||||||
|
expect(component.state('installPrompt')).toBeNull();
|
||||||
|
});
|
||||||
|
});
|
@ -46,6 +46,10 @@
|
|||||||
padding-right: var(--list-separator-width);
|
padding-right: var(--list-separator-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& li:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
& li:before {
|
& li:before {
|
||||||
content: '//';
|
content: '//';
|
||||||
padding: 0 0.5rem;
|
padding: 0 0.5rem;
|
||||||
@ -71,6 +75,10 @@
|
|||||||
padding-left: var(--list-separator-width);
|
padding-left: var(--list-separator-width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
& li:empty {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
& li:after {
|
& li:after {
|
||||||
content: '//';
|
content: '//';
|
||||||
padding: 0 0.5rem;
|
padding: 0 0.5rem;
|
||||||
|
@ -65,3 +65,5 @@
|
|||||||
DOWNLOAD PNG
|
DOWNLOAD PNG
|
||||||
"Loading...": |
|
"Loading...": |
|
||||||
LOADING...
|
LOADING...
|
||||||
|
"Add to Home Screen": |
|
||||||
|
ADD TO HOME SCREEN
|
||||||
|
@ -65,3 +65,5 @@
|
|||||||
Download PNG
|
Download PNG
|
||||||
"Loading...": |
|
"Loading...": |
|
||||||
Loading...
|
Loading...
|
||||||
|
"Add to Home Screen": |
|
||||||
|
Add to Home Screen
|
||||||
|
Loading…
Reference in New Issue
Block a user