diff --git a/js/src/views/Dapps/builtin.json b/js/src/config/dappsBuiltin.json similarity index 100% rename from js/src/views/Dapps/builtin.json rename to js/src/config/dappsBuiltin.json diff --git a/js/src/config/dappsViews.json b/js/src/config/dappsViews.json new file mode 100644 index 000000000..bd88e26ca --- /dev/null +++ b/js/src/config/dappsViews.json @@ -0,0 +1,13 @@ +[ + { + "id": "viewHome", + "url": "viewHome", + "src": "Home", + "name": "Home", + "description": "Display a status of the node, recently accessed applications, accounts and news", + "author": "Parity Team ", + "version": "2.0.0", + "visible": true, + "secure": true + } +] diff --git a/js/src/contracts/contracts.js b/js/src/contracts/contracts.js index 59b3bccfc..4935ce8cf 100644 --- a/js/src/contracts/contracts.js +++ b/js/src/contracts/contracts.js @@ -69,15 +69,11 @@ export default class Contracts { return verification; } - static create (api) { - if (instance) { - return instance; + static get (api) { + if (!instance) { + instance = new Contracts(api); } - return new Contracts(api); - } - - static get () { return instance; } } diff --git a/js/src/dapps/chaindeploy/_dapps.js b/js/src/dapps/chaindeploy/_dapps.js index 4a8da242f..e9eaa83a8 100644 --- a/js/src/dapps/chaindeploy/_dapps.js +++ b/js/src/dapps/chaindeploy/_dapps.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import builtinsJson from '~/views/Dapps/builtin.json'; +import builtinsJson from '~/config/dappsBuiltin.json'; const REGISTER_URLS = { console: 'https://raw.githubusercontent.com/paritytech/console/3ea0dbfefded359ccdbea37bc4cf350c0aa16948/console.jpeg', diff --git a/js/src/dapps/chaindeploy/dapps/console.js b/js/src/dapps/chaindeploy/dapps/console.js index 4e599b2fa..bc9cc7d43 100644 --- a/js/src/dapps/chaindeploy/dapps/console.js +++ b/js/src/dapps/chaindeploy/dapps/console.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import builtins from '~/views/Dapps/builtin.json'; +import builtins from '~/config/dappsBuiltin.json'; const id = 'console'; const app = builtins.find((app) => app.url === id); diff --git a/js/src/dapps/chaindeploy/dapps/dappreg.js b/js/src/dapps/chaindeploy/dapps/dappreg.js index fec35ef76..c3939015a 100644 --- a/js/src/dapps/chaindeploy/dapps/dappreg.js +++ b/js/src/dapps/chaindeploy/dapps/dappreg.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import builtins from '~/views/Dapps/builtin.json'; +import builtins from '~/config/dappsBuiltin.json'; const id = 'dappreg'; const app = builtins.find((app) => app.url === id); diff --git a/js/src/dapps/chaindeploy/dapps/githubhint.js b/js/src/dapps/chaindeploy/dapps/githubhint.js index 49fb4be9c..8a6b75d12 100644 --- a/js/src/dapps/chaindeploy/dapps/githubhint.js +++ b/js/src/dapps/chaindeploy/dapps/githubhint.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import builtins from '~/views/Dapps/builtin.json'; +import builtins from '~/config/dappsBuiltin.json'; const id = 'githubhint'; const app = builtins.find((app) => app.url === id); diff --git a/js/src/dapps/chaindeploy/dapps/localtx.js b/js/src/dapps/chaindeploy/dapps/localtx.js index 6fc275a13..61f1f142d 100644 --- a/js/src/dapps/chaindeploy/dapps/localtx.js +++ b/js/src/dapps/chaindeploy/dapps/localtx.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import builtins from '~/views/Dapps/builtin.json'; +import builtins from '~/config/dappsBuiltin.json'; const id = 'localtx'; const app = builtins.find((app) => app.url === id); diff --git a/js/src/dapps/chaindeploy/dapps/registry.js b/js/src/dapps/chaindeploy/dapps/registry.js index 49ff4757b..5a28e3604 100644 --- a/js/src/dapps/chaindeploy/dapps/registry.js +++ b/js/src/dapps/chaindeploy/dapps/registry.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import builtins from '~/views/Dapps/builtin.json'; +import builtins from '~/config/dappsBuiltin.json'; const id = 'registry'; const app = builtins.find((app) => app.url === id); diff --git a/js/src/dapps/chaindeploy/dapps/signaturereg.js b/js/src/dapps/chaindeploy/dapps/signaturereg.js index 12efcff36..acf939d72 100644 --- a/js/src/dapps/chaindeploy/dapps/signaturereg.js +++ b/js/src/dapps/chaindeploy/dapps/signaturereg.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import builtins from '~/views/Dapps/builtin.json'; +import builtins from '~/config/dappsBuiltin.json'; const id = 'signaturereg'; const app = builtins.find((app) => app.url === id); diff --git a/js/src/dapps/chaindeploy/dapps/tokendeploy.js b/js/src/dapps/chaindeploy/dapps/tokendeploy.js index 43ea8f22b..592e94c2e 100644 --- a/js/src/dapps/chaindeploy/dapps/tokendeploy.js +++ b/js/src/dapps/chaindeploy/dapps/tokendeploy.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import builtins from '~/views/Dapps/builtin.json'; +import builtins from '~/config/dappsBuiltin.json'; const id = 'tokendeploy'; const app = builtins.find((app) => app.url === id); diff --git a/js/src/dapps/chaindeploy/dapps/tokenreg.js b/js/src/dapps/chaindeploy/dapps/tokenreg.js index 784febba0..d8d81cd15 100644 --- a/js/src/dapps/chaindeploy/dapps/tokenreg.js +++ b/js/src/dapps/chaindeploy/dapps/tokenreg.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import builtins from '~/views/Dapps/builtin.json'; +import builtins from '~/config/dappsBuiltin.json'; const id = 'tokenreg'; const app = builtins.find((app) => app.url === id); diff --git a/js/src/dapps/chaindeploy/dapps/web.js b/js/src/dapps/chaindeploy/dapps/web.js index 0726e2bf7..7fb6da5e0 100644 --- a/js/src/dapps/chaindeploy/dapps/web.js +++ b/js/src/dapps/chaindeploy/dapps/web.js @@ -14,7 +14,7 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -import builtins from '~/views/Dapps/builtin.json'; +import builtins from '~/config/dappsBuiltin.json'; const id = 'web'; const app = builtins.find((app) => app.url === id); diff --git a/js/src/dapps/dappreg/dappsStore.js b/js/src/dapps/dappreg/dappsStore.js index c6f45922a..20941e229 100644 --- a/js/src/dapps/dappreg/dappsStore.js +++ b/js/src/dapps/dappreg/dappsStore.js @@ -20,7 +20,7 @@ import { flatten } from 'lodash'; import * as abis from '~/contracts/abi'; import Contracts from '~/contracts'; -import builtinJson from '~/views/Dapps/builtin.json'; +import builtinJson from '~/config/dappsBuiltin.json'; import Dapp from './dappStore.js'; import { deleteDapp, registerDapp, updateDapp } from './utils'; @@ -489,7 +489,7 @@ export default class DappsStore { } _loadRegistry () { - return Contracts.create(api).registry + return Contracts.get(api).registry .fetchContract() .then((contract) => { this._registry = contract.instance; diff --git a/js/src/dapps/registry/actions.js b/js/src/dapps/registry/actions.js index 8c7774397..ddb0b04b1 100644 --- a/js/src/dapps/registry/actions.js +++ b/js/src/dapps/registry/actions.js @@ -44,7 +44,7 @@ export const fetchIsTestnet = () => (dispatch) => export const setContract = (contract) => ({ type: 'set contract', contract }); export const fetchContract = () => (dispatch) => { - return Contracts.create(api).registry + return Contracts.get(api).registry .fetchContract() .then((contract) => { dispatch(setContract(contract)); diff --git a/js/src/embed.js b/js/src/embed.js index 75cb5e45a..4e7f8d6ed 100644 --- a/js/src/embed.js +++ b/js/src/embed.js @@ -92,7 +92,7 @@ class FrameSecureApi extends SecureApi { const api = new FrameSecureApi(window.secureTransport || new FakeTransport()); patchApi(api); -ContractInstances.create(api); +ContractInstances.get(api); const store = initStore(api, null, true); diff --git a/js/src/index.js b/js/src/index.js index 28abe953b..602ccb1bb 100644 --- a/js/src/index.js +++ b/js/src/index.js @@ -66,7 +66,7 @@ if (window.location.hash && window.location.hash.indexOf(AUTH_HASH) === 0) { const api = new SecureApi(`${urlScheme}${parityUrl}`, token); patchApi(api); -ContractInstances.create(api); +ContractInstances.get(api); const store = initStore(api, hashHistory); diff --git a/js/src/modals/Verification/store.js b/js/src/modals/Verification/store.js index a4102cc7d..b3c375dcc 100644 --- a/js/src/modals/Verification/store.js +++ b/js/src/modals/Verification/store.js @@ -51,12 +51,12 @@ export default class VerificationStore { @observable confirmationTx = null; constructor (api, abi, certifierName, account, isTestnet) { - this.api = api; + this._api = api; this.account = account; this.isTestnet = isTestnet; this.step = LOADING; - Contracts.get().badgeReg.fetchCertifierByName(certifierName) + Contracts.get(this._api).badgeReg.fetchCertifierByName(certifierName) .then(({ address }) => { this.contract = new Contract(api, abi).at(address); this.load(); diff --git a/js/src/redux/middleware.js b/js/src/redux/middleware.js index 9cc413dc0..691a8ecd1 100644 --- a/js/src/redux/middleware.js +++ b/js/src/redux/middleware.js @@ -37,7 +37,7 @@ export default function (api, browserHistory, forEmbed = false) { ]; if (!forEmbed) { - const certifications = new CertificationsMiddleware().toMiddleware(); + const certifications = new CertificationsMiddleware().toMiddleware(api); const registry = new RegistryMiddleware(api); middleware.push(certifications, registry); diff --git a/js/src/redux/providers/balances.js b/js/src/redux/providers/balances.js index 34c0bb413..a07385c20 100644 --- a/js/src/redux/providers/balances.js +++ b/js/src/redux/providers/balances.js @@ -270,7 +270,7 @@ export default class Balances { } getTokenRegistry () { - return Contracts.get().tokenReg.getContract(); + return Contracts.get(this._api).tokenReg.getContract(); } _loadTokens (options = {}) { diff --git a/js/src/redux/providers/certifications/middleware.js b/js/src/redux/providers/certifications/middleware.js index bf4729ae7..b494b75d2 100644 --- a/js/src/redux/providers/certifications/middleware.js +++ b/js/src/redux/providers/certifications/middleware.js @@ -59,9 +59,8 @@ const updatableFilter = (api, onFilter) => { }; export default class CertificationsMiddleware { - toMiddleware () { - const api = Contracts.get()._api; - const badgeReg = Contracts.get().badgeReg; + toMiddleware (api) { + const badgeReg = Contracts.get(api).badgeReg; const contract = new Contract(api, CertifierABI); const Confirmed = contract.events.find((e) => e.name === 'Confirmed'); diff --git a/js/src/redux/providers/chainMiddleware.spec.js b/js/src/redux/providers/chainMiddleware.spec.js index 837031c29..fcd4c4744 100644 --- a/js/src/redux/providers/chainMiddleware.spec.js +++ b/js/src/redux/providers/chainMiddleware.spec.js @@ -28,7 +28,7 @@ let clock; const api = createWsApi(); -Contracts.create(api); +Contracts.get(api); function stubGlobals () { clock = sinon.useFakeTimers(); diff --git a/js/src/redux/providers/registry/middleware.js b/js/src/redux/providers/registry/middleware.js index c6c961765..ce1362063 100644 --- a/js/src/redux/providers/registry/middleware.js +++ b/js/src/redux/providers/registry/middleware.js @@ -90,7 +90,7 @@ export default (api) => (store) => { break; case 'startCachingReverses': - const { registry } = Contracts.get(); + const { registry } = Contracts.get(api); const cached = read(store.getState().nodeStatus.netChain); if (cached) { diff --git a/js/src/routes.js b/js/src/routes.js index 72097ae62..abafdef4b 100644 --- a/js/src/routes.js +++ b/js/src/routes.js @@ -17,12 +17,15 @@ import HistoryStore from '~/mobx/historyStore'; import { Accounts, Account, Addresses, Address, Application, - Contract, Contracts, Dapp, Dapps, Home, + Contract, Contracts, Dapp, Dapps, Settings, SettingsBackground, SettingsParity, SettingsProxy, SettingsViews, Signer, Status, Vaults, Wallet, Web, WriteContract } from '~/views'; -import builtinDapps from '~/views/Dapps/builtin.json'; +import builtinDapps from '~/config/dappsBuiltin.json'; +import viewsDapps from '~/config/dappsViews.json'; + +const dapps = [].concat(viewsDapps, builtinDapps); const accountsHistory = HistoryStore.get('accounts'); const dappsHistory = HistoryStore.get('dapps'); @@ -129,13 +132,12 @@ const childRoutes = [ path: 'app/:id', component: Dapp, onEnter: ({ params }) => { - if (!builtinDapps[params.id] || !builtinDapps[params.id].skipHistory) { + if (!dapps[params.id] || !dapps[params.id].skipHistory) { dappsHistory.add(params.id); } } }, { path: 'apps', component: Dapps }, - { path: 'home', component: Home }, { path: 'web', component: Web }, { path: 'web/:url', component: Web }, { path: 'signer', component: Signer } diff --git a/js/src/ui/Form/AddressSelect/addressSelectStore.js b/js/src/ui/Form/AddressSelect/addressSelectStore.js index ecf6a8db7..24cdf7c9f 100644 --- a/js/src/ui/Form/AddressSelect/addressSelectStore.js +++ b/js/src/ui/Form/AddressSelect/addressSelectStore.js @@ -78,7 +78,7 @@ export default class AddressSelectStore { constructor (api) { this.api = api; - const { registry } = Contracts.create(api); + const { registry } = Contracts.get(api); registry .getContract('emailverification') diff --git a/js/src/util/dapps.js b/js/src/util/dapps.js index 75363a4c0..975a4fe2f 100644 --- a/js/src/util/dapps.js +++ b/js/src/util/dapps.js @@ -22,9 +22,10 @@ import { bytesToHex } from '@parity/api/util/format'; import Contracts from '~/contracts'; import { hashToImageUrl } from '~/redux/util'; -import builtinJson from '~/views/Dapps/builtin.json'; +import builtinJson from '~/config/dappsBuiltin.json'; +import viewsJson from '~/config/dappsViews.json'; -const builtinApps = builtinJson.filter((app) => app.id); +const builtinApps = [].concat(viewsJson, builtinJson).filter((app) => app.id); function getHost (api) { const host = process.env.DAPPS_URL || diff --git a/js/src/views/Dapps/dappsStore.js b/js/src/views/Dapps/dappsStore.js index b0570dc8f..cb759d6a8 100644 --- a/js/src/views/Dapps/dappsStore.js +++ b/js/src/views/Dapps/dappsStore.js @@ -66,7 +66,7 @@ export default class DappsStore extends EventEmitter { * apps, else fetch from the node */ loadApp (id) { - const { dappReg } = Contracts.get(); + const { dappReg } = Contracts.get(this._api); return this .loadLocalApps() @@ -94,7 +94,7 @@ export default class DappsStore extends EventEmitter { } loadAllApps () { - const { dappReg } = Contracts.get(); + const { dappReg } = Contracts.get(this._api); return Promise .all([ @@ -105,7 +105,7 @@ export default class DappsStore extends EventEmitter { } subscribeToChanges () { - const { dappReg } = Contracts.get(); + const { dappReg } = Contracts.get(this._api); // Unsubscribe from previous subscriptions, if any if (this._subscriptions.block) { diff --git a/js/src/views/Home/index.js b/js/src/views/Home/index.js index 12e31704a..2b3efbfa7 100644 --- a/js/src/views/Home/index.js +++ b/js/src/views/Home/index.js @@ -14,4 +14,35 @@ // You should have received a copy of the GNU General Public License // along with Parity. If not, see . -export default from './home'; +import ReactDOM from 'react-dom'; +import React from 'react'; +import { hashHistory } from 'react-router'; + +import injectTapEventPlugin from 'react-tap-event-plugin'; +injectTapEventPlugin(); + +import { api } from './parity'; + +import { initStore } from '~/redux'; +import { setApi } from '~/redux/providers/apiActions'; +import ContextProvider from '~/ui/ContextProvider'; +import muiTheme from '~/ui/Theme'; + +import Home from './home'; + +import '~/../assets/fonts/Roboto/font.css'; +import '~/../assets/fonts/RobotoMono/font.css'; + +import './home.css'; + +const store = initStore(api, hashHistory); + +store.dispatch({ type: 'initAll', api }); +store.dispatch(setApi(api)); + +ReactDOM.render( + + + , + document.querySelector('#container') +); diff --git a/js/src/views/Home/parity.js b/js/src/views/Home/parity.js new file mode 100644 index 000000000..7118ce087 --- /dev/null +++ b/js/src/views/Home/parity.js @@ -0,0 +1,21 @@ +// 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 . + +const api = window.parent.secureApi; + +export { + api +}; diff --git a/js/src/views/Settings/Views/defaults.js b/js/src/views/Settings/Views/defaults.js index c7a6bbce8..96afaa177 100644 --- a/js/src/views/Settings/Views/defaults.js +++ b/js/src/views/Settings/Views/defaults.js @@ -16,25 +16,9 @@ import React from 'react'; -import imagesEthcoreBlock from '~/../assets/images/parity-logo-white-no-text.svg'; import { AccountsIcon, AddressesIcon, AppsIcon, ContactsIcon, FingerprintIcon, SettingsIcon, StatusIcon } from '~/ui/Icons'; -import styles from './views.css'; - const defaultViews = { - home: { - active: true, - fixed: true, - icon: ( - - ), - route: '/home', - value: 'home' - }, - accounts: { active: true, fixed: true, diff --git a/js/src/views/index.ejs b/js/src/views/index.ejs new file mode 100644 index 000000000..aab652fa6 --- /dev/null +++ b/js/src/views/index.ejs @@ -0,0 +1,37 @@ + + + + + + + <%= htmlWebpackPlugin.options.title %> + + + +
+
Loading
+
+ + <% if (!htmlWebpackPlugin.options.secure) { %> + + <% } %> + + diff --git a/js/src/views/index.js b/js/src/views/index.js index 7460868ae..c4f524835 100644 --- a/js/src/views/index.js +++ b/js/src/views/index.js @@ -23,7 +23,6 @@ export Contract from './Contract'; export Contracts from './Contracts'; export Dapp from './Dapp'; export Dapps from './Dapps'; -export Home from './Home'; export ParityBar from './ParityBar'; export Settings, { SettingsBackground, SettingsParity, SettingsProxy, SettingsViews } from './Settings'; export Signer from './Signer'; diff --git a/js/webpack/app.js b/js/webpack/app.js index ba8e9a765..5f6a2c481 100644 --- a/js/webpack/app.js +++ b/js/webpack/app.js @@ -28,7 +28,15 @@ const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin'); const rulesEs6 = require('./rules/es6'); const rulesParity = require('./rules/parity'); const Shared = require('./shared'); -const DAPPS = require('../src/views/Dapps/builtin.json'); + +const DAPPS_BUILTIN = require('../src/config/dappsBuiltin.json').map((dapp) => { + dapp.srcPath = './dapps'; + return dapp; +}); +const DAPPS_VIEWS = require('../src/config/dappsViews.json').map((dapp) => { + dapp.srcPath = './views'; + return dapp; +}); const FAVICON = path.resolve(__dirname, '../assets/images/parity-logo-black-no-text.png'); @@ -149,16 +157,19 @@ module.exports = { }, plugins: (function () { - const DappsHTMLInjection = DAPPS.filter((dapp) => !dapp.skipBuild).map((dapp) => { - return new HtmlWebpackPlugin({ - title: dapp.name, - filename: dapp.url + '.html', - template: './dapps/index.ejs', - favicon: FAVICON, - secure: dapp.secure, - chunks: [ isProd ? null : 'commons', dapp.url ] + const DappsHTMLInjection = [] + .concat(DAPPS_BUILTIN, DAPPS_VIEWS) + .filter((dapp) => !dapp.skipBuild) + .map((dapp) => { + return new HtmlWebpackPlugin({ + title: dapp.name, + filename: dapp.url + '.html', + template: dapp.srcPath + '/index.ejs', + favicon: FAVICON, + secure: dapp.secure, + chunks: [ isProd ? null : 'commons', dapp.url ] + }); }); - }); let plugins = Shared.getPlugins().concat( new WebpackErrorNotificationPlugin() diff --git a/js/webpack/shared.js b/js/webpack/shared.js index 3e2eef8f1..ae39d37da 100644 --- a/js/webpack/shared.js +++ b/js/webpack/shared.js @@ -151,12 +151,19 @@ function getPlugins (_isProd = isProd) { } function getDappsEntry () { - const DAPPS = require('../src/views/Dapps/builtin.json'); + const builtins = require('../src/config/dappsBuiltin.json'); + const views = require('../src/config/dappsViews.json'); - return DAPPS.filter((dapp) => !dapp.skipBuild).reduce((_entry, dapp) => { - _entry[dapp.url] = './dapps/' + dapp.url + '.js'; - return _entry; - }, {}); + return Object.assign( + builtins.filter((dapp) => !dapp.skipBuild).reduce((_entry, dapp) => { + _entry[dapp.url] = './dapps/' + dapp.url + '.js'; + return _entry; + }, {}), + views.reduce((_entry, dapp) => { + _entry[dapp.url] = './views/' + dapp.src + '/index.js'; + return _entry; + }, {}) + ); } function addProxies (app) {