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",
|
"scryptsy": "2.0.0",
|
||||||
"solc": "ngotchac/solc-js",
|
"solc": "ngotchac/solc-js",
|
||||||
"store": "1.3.20",
|
"store": "1.3.20",
|
||||||
|
"useragent.js": "0.5.6",
|
||||||
"utf8": "2.1.2",
|
"utf8": "2.1.2",
|
||||||
"valid-url": "1.0.9",
|
"valid-url": "1.0.9",
|
||||||
"validator": "6.2.0",
|
"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 Snackbar from './Snackbar';
|
||||||
import Container from './Container';
|
import Container from './Container';
|
||||||
import DappContainer from './DappContainer';
|
import DappContainer from './DappContainer';
|
||||||
|
import Extension from './Extension';
|
||||||
import FrameError from './FrameError';
|
import FrameError from './FrameError';
|
||||||
import Status from './Status';
|
import Status from './Status';
|
||||||
import Store from './store';
|
import Store from './store';
|
||||||
@ -106,6 +107,7 @@ class Application extends Component {
|
|||||||
? <Status upgradeStore={ this.upgradeStore } />
|
? <Status upgradeStore={ this.upgradeStore } />
|
||||||
: null
|
: null
|
||||||
}
|
}
|
||||||
|
<Extension />
|
||||||
<Snackbar />
|
<Snackbar />
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user