Extension installation overlay (#4423)
* Extension installation overlay * Pr gumbles * Spelling * Update Chrome URL
This commit is contained in:
parent
cd4d489b57
commit
f48d8b0ef6
@ -193,6 +193,7 @@
|
||||
"scryptsy": "2.0.0",
|
||||
"solc": "ngotchac/solc-js",
|
||||
"store": "1.3.20",
|
||||
"useragent.js": "0.5.6",
|
||||
"utf8": "2.1.2",
|
||||
"valid-url": "1.0.9",
|
||||
"validator": "6.2.0",
|
||||
|
52
js/src/views/Application/Extension/extension.css
Normal file
52
js/src/views/Application/Extension/extension.css
Normal file
@ -0,0 +1,52 @@
|
||||
/* Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
/* This file is part of Parity.
|
||||
/*
|
||||
/* Parity is free software: you can redistribute it and/or modify
|
||||
/* it under the terms of the GNU General Public License as published by
|
||||
/* the Free Software Foundation, either version 3 of the License, or
|
||||
/* (at your option) any later version.
|
||||
/*
|
||||
/* Parity is distributed in the hope that it will be useful,
|
||||
/* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
/* GNU General Public License for more details.
|
||||
/*
|
||||
/* You should have received a copy of the GNU General Public License
|
||||
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
.body {
|
||||
background: #f80;
|
||||
color: white;
|
||||
opacity: 1;
|
||||
max-width: 500px;
|
||||
padding: 1em 4em 1em 2em;
|
||||
position: fixed;
|
||||
right: 1.5em;
|
||||
top: 1.5em;
|
||||
z-index: 1000;
|
||||
|
||||
.button {
|
||||
background: rgba(0, 0, 0, 0.5);
|
||||
color: white !important;
|
||||
|
||||
svg {
|
||||
fill: white !important;
|
||||
}
|
||||
}
|
||||
|
||||
.buttonrow {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
p {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.close {
|
||||
cursor: pointer;
|
||||
position: absolute;
|
||||
right: 1em;
|
||||
top: 1em;
|
||||
}
|
||||
}
|
74
js/src/views/Application/Extension/extension.js
Normal file
74
js/src/views/Application/Extension/extension.js
Normal file
@ -0,0 +1,74 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import { observer } from 'mobx-react';
|
||||
import React, { Component } from 'react';
|
||||
import { FormattedMessage } from 'react-intl';
|
||||
|
||||
import { Button } from '~/ui';
|
||||
import { CloseIcon, CheckIcon } from '~/ui/Icons';
|
||||
|
||||
import Store from './store';
|
||||
import styles from './extension.css';
|
||||
|
||||
@observer
|
||||
export default class Extension extends Component {
|
||||
store = new Store();
|
||||
|
||||
render () {
|
||||
const { showWarning } = this.store;
|
||||
|
||||
if (!showWarning) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<div className={ styles.body }>
|
||||
<CloseIcon
|
||||
className={ styles.close }
|
||||
onClick={ this.onClose }
|
||||
/>
|
||||
<p>
|
||||
<FormattedMessage
|
||||
id='extension.intro'
|
||||
defaultMessage='Parity now has an extension available for Chrome that allows safe browsing of Ethereum-enabled distributed applications. It is highly recommended that you install this extension to further enhance your Parity experience.'
|
||||
/>
|
||||
</p>
|
||||
<p className={ styles.buttonrow }>
|
||||
<Button
|
||||
className={ styles.button }
|
||||
icon={ <CheckIcon /> }
|
||||
label={
|
||||
<FormattedMessage
|
||||
id='extension.install'
|
||||
defaultMessage='Install the extension now'
|
||||
/>
|
||||
}
|
||||
onClick={ this.onInstallClick }
|
||||
/>
|
||||
</p>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
onClose = () => {
|
||||
this.store.snoozeWarning();
|
||||
}
|
||||
|
||||
onInstallClick = () => {
|
||||
this.store.installExtension();
|
||||
}
|
||||
}
|
17
js/src/views/Application/Extension/index.js
Normal file
17
js/src/views/Application/Extension/index.js
Normal file
@ -0,0 +1,17 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
export default from './extension';
|
89
js/src/views/Application/Extension/store.js
Normal file
89
js/src/views/Application/Extension/store.js
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright 2015-2017 Parity Technologies (UK) Ltd.
|
||||
// This file is part of Parity.
|
||||
|
||||
// Parity is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published by
|
||||
// the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
|
||||
// Parity is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with Parity. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
/* global chrome */
|
||||
|
||||
import { action, computed, observable } from 'mobx';
|
||||
|
||||
import store from 'store';
|
||||
import browser from 'useragent.js/lib/browser';
|
||||
|
||||
const A_DAY = 24 * 60 * 60 * 1000;
|
||||
const NEXT_DISPLAY = '_parity::extensionWarning::nextDisplay';
|
||||
|
||||
// 'https://chrome.google.com/webstore/detail/parity-ethereum-integrati/himekenlppkgeaoeddcliojfddemadig';
|
||||
const EXTENSION_PAGE = 'https://chrome.google.com/webstore/detail/himekenlppkgeaoeddcliojfddemadig';
|
||||
|
||||
export default class Store {
|
||||
@observable isInstalling = false;
|
||||
@observable nextDisplay = 0;
|
||||
@observable shouldInstall = false;
|
||||
|
||||
constructor () {
|
||||
this.nextDisplay = store.get(NEXT_DISPLAY) || 0;
|
||||
this.testInstall();
|
||||
}
|
||||
|
||||
@computed get showWarning () {
|
||||
return !this.isInstalling && this.shouldInstall && (Date.now() > this.nextDisplay);
|
||||
}
|
||||
|
||||
@action setInstalling = (isInstalling) => {
|
||||
this.isInstalling = isInstalling;
|
||||
}
|
||||
|
||||
@action snoozeWarning = (sleep = A_DAY) => {
|
||||
this.nextDisplay = Date.now() + sleep;
|
||||
store.set(NEXT_DISPLAY, this.nextDisplay);
|
||||
}
|
||||
|
||||
@action testInstall = () => {
|
||||
this.shouldInstall = this.readStatus();
|
||||
}
|
||||
|
||||
readStatus = () => {
|
||||
const hasExtension = Symbol.for('parity.extension') in window;
|
||||
const ua = browser.analyze(navigator.userAgent || '');
|
||||
|
||||
if (hasExtension) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (ua || {}).name.toLowerCase() === 'chrome';
|
||||
}
|
||||
|
||||
installExtension = () => {
|
||||
this.setInstalling(true);
|
||||
|
||||
return new Promise((resolve, reject) => {
|
||||
const link = document.createElement('link');
|
||||
|
||||
link.setAttribute('rel', 'chrome-webstore-item');
|
||||
link.setAttribute('href', EXTENSION_PAGE);
|
||||
document.querySelector('head').appendChild(link);
|
||||
|
||||
if (chrome && chrome.webstore && chrome.webstore.install) {
|
||||
chrome.webstore.install(EXTENSION_PAGE, resolve, reject);
|
||||
} else {
|
||||
reject(new Error('Direct installation failed.'));
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
console.warn('Unable to perform direct install', error);
|
||||
window.open(EXTENSION_PAGE, '_blank');
|
||||
});
|
||||
}
|
||||
}
|
@ -26,6 +26,7 @@ import ParityBar from '../ParityBar';
|
||||
import Snackbar from './Snackbar';
|
||||
import Container from './Container';
|
||||
import DappContainer from './DappContainer';
|
||||
import Extension from './Extension';
|
||||
import FrameError from './FrameError';
|
||||
import Status from './Status';
|
||||
import Store from './store';
|
||||
@ -106,6 +107,7 @@ class Application extends Component {
|
||||
? <Status upgradeStore={ this.upgradeStore } />
|
||||
: null
|
||||
}
|
||||
<Extension />
|
||||
<Snackbar />
|
||||
</Container>
|
||||
);
|
||||
|
Loading…
Reference in New Issue
Block a user