Update with latest dapps

This commit is contained in:
Jaco Greeff
2017-08-02 17:16:26 +02:00
parent 45f91facf1
commit 696089c479
54 changed files with 314 additions and 4529 deletions

View File

@@ -1,204 +0,0 @@
// 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 BigNumber from 'bignumber.js';
import sinon from 'sinon';
import localStore from 'store';
import Contracts from '@parity/shared/contracts';
import Store, { LS_KEY_DISPLAY } from './dappsStore';
const APPID_DAPPREG = '0x7bbc4f1a27628781b96213e781a1b8eec6982c1db8fac739af6e4c5a55862c03';
const APPID_GHH = '0x058740ee9a5a3fb9f1cfa10752baec87e09cc45cd7027fd54708271aca300c75';
const APPID_LOCALTX = '0xae74ad174b95cdbd01c88ac5b73a296d33e9088fc2a200e76bcedf3a94a7815d';
const APPID_TOKENDEPLOY = '0xf9f2d620c2e08f83e45555247146c62185e4ab7cf82a4b9002a265a0d020348f';
let globalContractsGet;
function stubGlobals () {
globalContractsGet = Contracts.get;
Contracts.get = () => {
return {
dappReg: {
at: sinon.stub().resolves([[0, 1, 2, 3], 'appOwner']),
count: sinon.stub().resolves(new BigNumber(1)),
getContract: sinon.stub().resolves({}),
getContent: sinon.stub().resolves([0, 1, 2, 3]),
getImage: sinon.stub().resolves([0, 1, 2, 3]),
getManifest: sinon.stub().resolves([0, 1, 2, 3])
}
};
};
}
function restoreGlobals () {
Contracts.get = globalContractsGet;
}
let api;
let store;
function create () {
api = {
parity: {
dappsList: () => Promise.resolve([])
}
};
store = new Store(api);
return store;
}
describe('Dapps/DappStore', () => {
beforeEach(() => {
stubGlobals();
});
afterEach(() => {
restoreGlobals();
});
describe('@action', () => {
const defaultViews = {
[APPID_TOKENDEPLOY]: { visible: false },
[APPID_DAPPREG]: { visible: true }
};
describe('setDisplayApps', () => {
beforeEach(() => {
create();
store.setDisplayApps(defaultViews);
});
it('sets from empty start', () => {
expect(store.displayApps).to.deep.equal(defaultViews);
});
it('overrides single keys, keeping existing', () => {
store.setDisplayApps({ [APPID_TOKENDEPLOY]: { visible: true } });
expect(store.displayApps).to.deep.equal(
Object.assign({}, defaultViews, { [APPID_TOKENDEPLOY]: { visible: true } })
);
});
it('extends with new keys, keeping existing', () => {
store.setDisplayApps({ 'test': { visible: true } });
expect(store.displayApps).to.deep.equal(
Object.assign({}, defaultViews, { 'test': { visible: true } })
);
});
});
describe('hideApp/showApp', () => {
beforeEach(() => {
localStore.set(LS_KEY_DISPLAY, defaultViews);
create().readDisplayApps();
});
afterEach(() => {
localStore.set(LS_KEY_DISPLAY, {});
});
it('disables visibility', () => {
store.hideApp(APPID_DAPPREG);
expect(store.displayApps[APPID_DAPPREG].visible).to.be.false;
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(
Object.assign({}, defaultViews, { [APPID_DAPPREG]: { visible: false } })
);
});
it('enables visibility', () => {
store.showApp(APPID_TOKENDEPLOY);
expect(store.displayApps[APPID_TOKENDEPLOY].visible).to.be.true;
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(
Object.assign({}, defaultViews, { [APPID_TOKENDEPLOY]: { visible: true } })
);
});
it('keeps visibility state', () => {
store.hideApp(APPID_TOKENDEPLOY);
store.showApp(APPID_DAPPREG);
expect(store.displayApps[APPID_TOKENDEPLOY].visible).to.be.false;
expect(store.displayApps[APPID_DAPPREG].visible).to.be.true;
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(defaultViews);
});
});
describe('readDisplayApps/writeDisplayApps', () => {
beforeEach(() => {
localStore.set(LS_KEY_DISPLAY, defaultViews);
create().readDisplayApps();
});
afterEach(() => {
localStore.set(LS_KEY_DISPLAY, {});
});
it('loads visibility from storage', () => {
expect(store.displayApps).to.deep.equal(defaultViews);
});
it('saves visibility to storage', () => {
store.setDisplayApps({ [APPID_TOKENDEPLOY]: { visible: true } });
store.writeDisplayApps();
expect(localStore.get(LS_KEY_DISPLAY)).to.deep.equal(
Object.assign({}, defaultViews, { [APPID_TOKENDEPLOY]: { visible: true } })
);
});
});
});
describe('saved views', () => {
beforeEach(() => {
localStore.set(LS_KEY_DISPLAY, {
[APPID_TOKENDEPLOY]: { visible: false },
[APPID_DAPPREG]: { visible: true }
});
return create().loadAllApps();
});
afterEach(() => {
localStore.set(LS_KEY_DISPLAY, {});
});
it('disables based on saved keys', () => {
expect(store.displayApps[APPID_TOKENDEPLOY].visible).to.be.false;
});
it('enables based on saved keys', () => {
expect(store.displayApps[APPID_DAPPREG].visible).to.be.true;
});
it('keeps non-sepcified disabled keys', () => {
expect(store.displayApps[APPID_GHH].visible).to.be.false;
});
it('keeps non-specified enabled keys', () => {
expect(store.displayApps[APPID_LOCALTX].visible).to.be.true;
});
});
});

View File

@@ -23,7 +23,7 @@ import PropTypes from 'prop-types';
import { Checkbox, DappCard, Page, SectionList } from '@parity/ui';
import DappsStore from './dappsStore';
import DappsStore from '@parity/shared/mobx/dappsStore';
import styles from './dapps.css';

View File

@@ -1,306 +0,0 @@
// 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 EventEmitter from 'eventemitter3';
import { action, computed, observable, transaction } from 'mobx';
import store from 'store';
import Contracts from '@parity/shared/contracts';
import { fetchBuiltinApps, fetchLocalApps, fetchRegistryAppIds, fetchRegistryApp, subscribeToChanges } from '@parity/shared/util/dapps';
const LS_KEY_DISPLAY = 'displayApps';
const LS_KEY_EXTERNAL_ACCEPT = 'acceptExternal';
const BUILTIN_APPS_KEY = 'BUILTIN_APPS_KEY';
let instance = null;
export default class DappsStore extends EventEmitter {
@observable apps = [];
@observable displayApps = {};
@observable modalOpen = false;
@observable externalOverlayVisible = true;
_api = null;
_subscriptions = {};
_cachedApps = {};
_manifests = {};
_registryAppsIds = null;
constructor (api) {
super();
this._api = api;
this.readDisplayApps();
this.loadExternalOverlay();
this.subscribeToChanges();
}
static get (api) {
if (!instance) {
instance = new DappsStore(api);
}
return instance;
}
@computed get allApps () {
return this.apps;
}
@computed get sortedBuiltin () {
return this.apps.filter((app) => app.type === 'builtin');
}
@computed get sortedLocal () {
return this.apps.filter((app) => app.type === 'local');
}
@computed get sortedNetwork () {
return this.apps.filter((app) => app.type === 'network');
}
@computed get visibleApps () {
return this.apps.filter((app) => this.displayApps[app.id] && this.displayApps[app.id].visible);
}
@computed get visibleBuiltin () {
return this.visibleApps.filter((app) => !app.noselect && app.type === 'builtin');
}
@computed get visibleLocal () {
return this.visibleApps.filter((app) => app.type === 'local');
}
@computed get visibleNetwork () {
return this.visibleApps.filter((app) => app.type === 'network');
}
@computed get visibleViews () {
return this.visibleApps.filter((app) => !app.noselect && app.type === 'view');
}
/**
* Try to find the app from the local (local or builtin)
* apps, else fetch from the node
*/
loadApp (id) {
const { dappReg } = Contracts.get(this._api);
return this
.loadLocalApps()
.then(() => {
const app = this.apps.find((app) => app.id === id);
if (app) {
return app;
}
return this.fetchRegistryApp(dappReg, id, true);
})
.then((app) => {
this.emit('loaded', app);
return app;
});
}
loadLocalApps () {
return Promise
.all([
this.fetchBuiltinApps().then((apps) => this.addApps(apps)),
this.fetchLocalApps().then((apps) => this.addApps(apps))
]);
}
loadAllApps () {
const { dappReg } = Contracts.get(this._api);
return Promise
.all([
this.loadLocalApps(),
this.fetchRegistryApps(dappReg).then((apps) => this.addApps(apps))
])
.then(this.writeDisplayApps);
}
subscribeToChanges () {
const { dappReg } = Contracts.get(this._api);
// Unsubscribe from previous subscriptions, if any
if (this._subscriptions.block) {
this._api.unsubscribe(this._subscriptions.block);
}
if (this._subscriptions.filter) {
this._api.eth.uninstallFilter(this._subscriptions.filter);
}
// Subscribe to dapps reg changes
subscribeToChanges(this._api, dappReg, (appIds) => {
const updates = appIds.map((appId) => {
return this.fetchRegistryApp(dappReg, appId, true);
});
Promise
.all(updates)
.then((apps) => {
this.addApps(apps);
});
}).then((subscriptions) => {
this._subscriptions = subscriptions;
});
}
fetchBuiltinApps (force = false) {
if (!force && this._cachedApps[BUILTIN_APPS_KEY] !== undefined) {
return Promise.resolve(this._cachedApps[BUILTIN_APPS_KEY]);
}
this._cachedApps[BUILTIN_APPS_KEY] = fetchBuiltinApps(this._api)
.then((apps) => {
this._cachedApps[BUILTIN_APPS_KEY] = apps;
return apps;
});
return Promise.resolve(this._cachedApps[BUILTIN_APPS_KEY]);
}
fetchLocalApps () {
return fetchLocalApps(this._api);
}
fetchRegistryAppIds (force = false) {
if (!force && this._registryAppsIds) {
return Promise.resolve(this._registryAppsIds);
}
this._registryAppsIds = fetchRegistryAppIds(this._api)
.then((appIds) => {
this._registryAppsIds = appIds;
return this._registryAppsIds;
});
return Promise.resolve(this._registryAppsIds);
}
fetchRegistryApp (dappReg, appId, force = false) {
if (!force && this._cachedApps[appId] !== undefined) {
return Promise.resolve(this._cachedApps[appId]);
}
this._cachedApps[appId] = fetchRegistryApp(this._api, dappReg, appId)
.then((dapp) => {
this._cachedApps[appId] = dapp;
return dapp;
});
return Promise.resolve(this._cachedApps[appId]);
}
fetchRegistryApps (dappReg) {
return this
.fetchRegistryAppIds()
.then((appIds) => {
const promises = appIds.map((appId) => {
// Fetch the Dapp and display it ASAP
return this
.fetchRegistryApp(dappReg, appId)
.then((app) => {
if (app) {
this.addApps([ app ]);
}
return app;
});
});
return Promise.all(promises);
});
}
@action openModal = () => {
this.modalOpen = true;
}
@action closeModal = () => {
this.modalOpen = false;
}
@action closeExternalOverlay = () => {
this.externalOverlayVisible = false;
store.set(LS_KEY_EXTERNAL_ACCEPT, true);
}
@action loadExternalOverlay () {
this.externalOverlayVisible = !(store.get(LS_KEY_EXTERNAL_ACCEPT) || false);
}
@action hideApp = (id) => {
this.setDisplayApps({ [id]: { visible: false } });
this.writeDisplayApps();
}
@action showApp = (id) => {
this.setDisplayApps({ [id]: { visible: true } });
this.writeDisplayApps();
}
@action readDisplayApps = () => {
this.displayApps = store.get(LS_KEY_DISPLAY) || {};
}
@action writeDisplayApps = () => {
store.set(LS_KEY_DISPLAY, this.displayApps);
}
@action setDisplayApps = (displayApps) => {
this.displayApps = Object.assign({}, this.displayApps, displayApps);
};
@action addApps = (_apps = []) => {
transaction(() => {
const apps = _apps.filter((app) => app);
// Get new apps IDs if available
const newAppsIds = apps
.map((app) => app.id)
.filter((id) => id);
this.apps = this.apps
.filter((app) => !app.id || !newAppsIds.includes(app.id))
.concat(apps || [])
.sort((a, b) => a.name.localeCompare(b.name));
const visibility = {};
apps.forEach((app) => {
if (!this.displayApps[app.id]) {
visibility[app.id] = { visible: app.visible };
}
});
this.setDisplayApps(visibility);
});
}
getAppById = (id) => {
return this.apps.find((app) => app.id === id);
}
}
export {
LS_KEY_DISPLAY
};