Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Commit

Permalink
Default Account selector in Signer overlay (#4375)
Browse files Browse the repository at this point in the history
* Manage default accounts

* Portal

* Portal

* Allow Portal to be used in as both top-level and popover

* modal/popover variable naming

* Move to Portal

* export Portal in ~/ui

* WIP

* Tags handle empty values

* Export AccountCard in ~/ui

* Allow ETH-only & zero display

* Use ui/Balance for balance display

* Add tests for Balance & Tags component availability

* WIP

* Default overlay display to block (not flex)

* Revert block

* WIP

* Add className, optional handlers only

* WIP

* Properly handle optional onKeyDown

* Selection updated

* Align margins

* Remove old code

* Remove debug logging

* TransitionGroup for animations

* No anim

* Cleanups

* Revert addons removal

* Fix tests

* defaultAccount

* Selection actually selects

* WIP tests

* tests WIP

* Expand tests

* Container for scrollbars

* Add parity_defaultAccount RPC (with subscription)

* Add jsonrpc interface
  • Loading branch information
jacogr authored and gavofyork committed Feb 1, 2017
1 parent a414729 commit 3bdd32f
Show file tree
Hide file tree
Showing 6 changed files with 442 additions and 26 deletions.
101 changes: 101 additions & 0 deletions js/src/views/ParityBar/accountStore.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// 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 { action, observable, transaction } from 'mobx';

export default class AccountStore {
@observable accounts = [];
@observable defaultAccount = null;
@observable isLoading = false;

constructor (api) {
this._api = api;

this.loadAccounts();
this.subscribeDefaultAccount();
}

@action setAccounts = (accounts) => {
this.accounts = accounts;
}

@action setDefaultAccount = (defaultAccount) => {
this.defaultAccount = defaultAccount;
}

@action setLoading = (isLoading) => {
this.isLoading = isLoading;
}

makeDefaultAccount = (address) => {
const accounts = [address].concat(
this.accounts
.filter((account) => account.address !== address)
.map((account) => account.address)
);

return this._api.parity
.setNewDappsWhitelist(accounts)
.catch((error) => {
console.warn('makeDefaultAccount', error);
});
}

loadAccounts () {
this.setLoading(true);

return Promise
.all([
this._api.parity.getNewDappsWhitelist(),
this._api.parity.allAccountsInfo()
])
.then(([whitelist, accounts]) => {
transaction(() => {
this.setLoading(false);
this.setAccounts(
Object
.keys(accounts)
.filter((address) => {
const isAccount = accounts[address].uuid;
const isWhitelisted = !whitelist || whitelist.includes(address);

return isAccount && isWhitelisted;
})
.map((address) => {
const account = accounts[address];

account.address = address;
account.default = address === this.defaultAccount;

return account;
})
);
});
})
.catch((error) => {
this.setLoading(false);
console.warn('loadAccounts', error);
});
}

subscribeDefaultAccount () {
return this._api.subscribe('parity_defaultAccount', (error, defaultAccount) => {
if (!error) {
this.setDefaultAccount(defaultAccount);
}
});
}
}
104 changes: 104 additions & 0 deletions js/src/views/ParityBar/accountStore.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// 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 sinon from 'sinon';

import AccountStore from './accountStore';

import { ACCOUNT_DEFAULT, ACCOUNT_FIRST, ACCOUNT_NEW, createApi } from './parityBar.test.js';

let api;
let store;

function create () {
api = createApi();
store = new AccountStore(api);

return store;
}

describe('views/ParityBar/AccountStore', () => {
beforeEach(() => {
create();
});

describe('constructor', () => {
it('subscribes to defaultAccount', () => {
expect(api.subscribe).to.have.been.calledWith('parity_defaultAccount');
});
});

describe('@action', () => {
describe('setAccounts', () => {
it('sets the accounts', () => {
store.setAccounts('testing');
expect(store.accounts).to.equal('testing');
});
});

describe('setDefaultAccount', () => {
it('sets the default account', () => {
store.setDefaultAccount('testing');
expect(store.defaultAccount).to.equal('testing');
});
});

describe('setLoading', () => {
it('sets the loading status', () => {
store.setLoading('testing');
expect(store.isLoading).to.equal('testing');
});
});
});

describe('operations', () => {
describe('loadAccounts', () => {
beforeEach(() => {
sinon.spy(store, 'setAccounts');

return store.loadAccounts();
});

afterEach(() => {
store.setAccounts.restore();
});

it('calls into parity_getNewDappsWhitelist', () => {
expect(api.parity.getNewDappsWhitelist).to.have.been.called;
});

it('calls into parity_allAccountsInfo', () => {
expect(api.parity.allAccountsInfo).to.have.been.called;
});

it('sets the accounts', () => {
expect(store.setAccounts).to.have.been.called;
});
});

describe('makeDefaultAccount', () => {
beforeEach(() => {
return store.makeDefaultAccount(ACCOUNT_NEW);
});

it('calls into parity_setNewDappsWhitelist (with ordering)', () => {
expect(api.parity.setNewDappsWhitelist).to.have.been.calledWith([
ACCOUNT_NEW, ACCOUNT_FIRST, ACCOUNT_DEFAULT
]);
});
});
});
});
59 changes: 55 additions & 4 deletions js/src/views/ParityBar/parityBar.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,44 @@
/* along with Parity. If not, see <http://www.gnu.org/licenses/>.
*/

.account {
display: flex;
flex: 1;
position: relative;

.accountOverlay {
position: absolute;
right: 0.5em;
top: 0.5em;
}

.iconDisabled {
opacity: 0.15;
}

.selected,
.unselected {
margin: 0.125em 0;

&:focus {
outline: none;
}
}

.unselected {
background: rgba(0, 0, 0, 0.4) !important;
}

.selected {
background: rgba(255, 255, 255, 0.35) !important;
}
}

.container {
display: flex;
flex-direction: column;
}

.overlay {
position: fixed;
top: 0;
Expand All @@ -26,7 +64,8 @@
user-select: none;
}

.bar, .expanded {
.bar,
.expanded {
position: fixed;
font-size: 16px;
font-family: 'Roboto', sans-serif;
Expand Down Expand Up @@ -110,7 +149,9 @@
margin-left: 1em;
}

.button, .parityButton {
.button,
.iconButton,
.parityButton {
overflow: visible !important;
}

Expand All @@ -123,6 +164,14 @@
fill: white !important;
}

.iconButton {
min-width: 2em !important;

img {
margin: 6px 0.5em 0 0.5em;
}
}

.label {
position: relative;
display: inline-block;
Expand Down Expand Up @@ -151,7 +200,8 @@
}
}

.header, .corner {
.header,
.corner {
button {
color: white !important;
}
Expand Down Expand Up @@ -180,7 +230,8 @@
}
}

.parityIcon, .signerIcon {
.parityIcon,
.signerIcon {
width: 24px;
height: 24px;
vertical-align: middle;
Expand Down
Loading

0 comments on commit 3bdd32f

Please sign in to comment.