Compare commits

...

36 Commits

Author SHA1 Message Date
basti fe4af46852 1.10.0 2019-09-10 17:01:23 +02:00
basti 7b9659e22f Update deps
Fixes security vulns
2019-09-10 16:59:20 +02:00
basti 8be18fc27c Merge pull request #155 from 67P/feature/resubmit_vetoed_contribution
Re-submit vetoed contributions
2019-09-10 16:53:36 +02:00
basti 7e518780c5 Merge pull request #154 from 67P/feature/sign_in
Improve account connect/loading, check network
2019-09-10 16:48:55 +02:00
basti 89391c1543 Update details of pending contribution when mined
Fetches complete details of new contributions and replaces any potential
pending, incomplete objects in the collection.
2019-09-10 15:21:50 +02:00
basti 05e3118a0c Re-submit vetoed contributions 2019-09-10 11:47:07 +02:00
basti 494b5d9bdd Use configured IPFS gateway URL for button 2019-09-05 11:53:20 +02:00
basti f8f1ad644c WIP: vetoed contribution details
Adds a blurb and resubmit button to the detail view for vetoed
contributions.
2019-09-05 11:36:50 +02:00
basti 5a5051bac6 Check required network before using user provider
closes #82
2019-09-04 18:51:49 +02:00
basti 304c0ac8d0 Only use user wallet if it's already open/connected 2019-09-04 18:29:25 +02:00
basti cae13ed662 Sign in button to connect account 2019-09-04 18:22:48 +02:00
basti 729110f8d1 Remove obsolete APM domains 2019-09-04 17:04:18 +02:00
basti 11f66de6e6 1.9.0 2019-09-03 13:43:17 +02:00
basti 9bf2ae2d7f Merge pull request #151 from 67P/feature/layout_sizing
Improve sizing of entire layout
2019-09-03 13:40:38 +02:00
basti 2a384f3eed Improve sizing of entire layout 2019-09-01 18:06:56 +02:00
basti 6b3666def9 1.8.0 2019-09-01 16:04:21 +02:00
basti 74c8e32cc6 Merge pull request #142 from 67P/feature/signup
Sign up via GitHub
2019-08-29 12:52:04 +02:00
basti 5dde978499 Merge branch 'master' into feature/signup 2019-08-29 12:46:00 +02:00
galfert 0625ee9d79 Handle undefined Github access token 2019-08-28 12:53:21 +02:00
basti dc5dfe19f2 Add success page to GitHub signup 2019-08-27 18:19:46 +02:00
galfert c518b7f565 Merge pull request #149 from 67P/chore/dao_address
Rename kernel address to DAO address
2019-08-27 15:12:45 +02:00
basti d13242b210 Rename kernel address to DAO address
We're making the naming consistent everwhere.
2019-08-27 15:00:18 +02:00
basti ada029586a Merge pull request #148 from 67P/doc/dev_network
Documentation for IPFS and Metamask
2019-08-26 18:53:24 +02:00
galfert 7bf5fa444a Add notice about Metamask when using local devchain 2019-08-26 18:09:38 +02:00
galfert d08d5f9e8d Add IPFS Gateway config to readme 2019-08-26 18:00:17 +02:00
galfert 60ba019139 Fix HAL8000 URL
Wrong port number.
2019-07-26 19:02:41 +02:00
galfert 413bcddb1e Wire up signup via Github 2019-07-26 03:38:18 +02:00
basti c2273d1778 Merge pull request #144 from 67P/feature/validate_eth_addresses
Validate Ethereum addresses in input fields
2019-07-24 17:30:51 +02:00
basti 780afc9bc6 Fix wrong property name 2019-07-24 11:56:51 +02:00
basti a8ae2b0156 Validate Ethereum addresses in input fields 2019-07-22 17:29:31 +02:00
basti d6d2b1a61c Add signup completion page 2019-07-21 17:03:50 +02:00
basti 4c70c0d233 Basic signup view 2019-07-21 16:04:00 +02:00
basti 725d36bed6 Add signup button for unknown users 2019-07-18 19:43:39 +02:00
basti 0a71d7ad91 Add signup route 2019-07-18 19:31:03 +02:00
basti 6a176b5904 Fix empty name in account info
When the user brings Ethereum accounts, but none of them is known as
contributor, instead of "Anonymous" it just shows nothing. This fixes
the if condition in the template to eliminate the faulty case.
2019-07-18 19:27:53 +02:00
basti c7d046aa46 Move topbar account info to component, add tests
Adds a failing test for users with wallet, but no known contributor
account, where it currently shows no name at all.
2019-07-18 19:26:16 +02:00
53 changed files with 4489 additions and 2619 deletions
+10 -5
View File
@@ -71,10 +71,10 @@ These are the basic steps to get up and running:
#### 1. IPFS
Run a local IPFS deamon in offline mode.
Run a local IPFS deamon.
* Make sure CORS headers are configured. See [IPFS](#ipfs) for more info.
* `ipfs daemon --offline`
* `ipfs daemon`
#### 2. kredits-contracts
@@ -94,11 +94,15 @@ With IPFS and Ethereum/ganache running, you can now start this Ember app.
* `npm link kredits-contracts` - link the local `kredits-contracts` package
* `npm run start:local` - WEB3_PROVIDER_URL=http://localhost:7545 must be set for local settings
If you restart the devchain your network ID changes. So kredits-contracts does not find the correct DAO Kernel address.
If that is the case the DAO address must be provided as `KREDITS_KERNEL_ADDRESS` environment variable.
If you restart the devchain your network ID changes. So kredits-contracts does not find the correct DAO address.
If that is the case the DAO address must be provided as `KREDITS_DAO_ADDRESS` environment variable.
* `npm run dao:address` in the kredits-contracts repo to find your address
* `KREDITS_KERNEL_ADDRESS=<0xYOURADDRESS> npm run start:local`
* `KREDITS_DAO_ADDRESS=<0xYOURADDRESS> npm run start:local`
#### 4. Metamask network
Switch the network in Metamask to "Custom RPC" with the RPC URL `http://localhost:7545`.
#### IPFS
@@ -108,6 +112,7 @@ Install IPFS with your favorite package manager and run
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Origin '["localhost:4200"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Methods '["PUT", "GET", "POST"]'
ipfs config --json API.HTTPHeaders.Access-Control-Allow-Credentials '["true"]'
ipfs config Addresses.Gateway /ip4/127.0.0.1/tcp/8080
## Further Reading / Useful Links
+12 -9
View File
@@ -1,6 +1,7 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { and, notEmpty } from '@ember/object/computed';
import { isEmpty } from '@ember/utils';
import moment from 'moment';
export default Component.extend({
@@ -25,14 +26,17 @@ export default Component.extend({
this.set('defaultDate', moment().startOf('hour').toDate());
// Default attributes used by reset
this.set('attributes', {
contributorId: null,
kind: null,
date: this.defaultDate,
amount: null,
description: null,
url: null,
});
if (isEmpty(this.attributes)) {
this.set('attributes', {
contributorId: null,
kind: null,
date: this.defaultDate,
amount: null,
description: null,
url: null,
details: null
});
}
this.reset();
},
@@ -67,7 +71,6 @@ export default Component.extend({
window.alert('Something went wrong. Check the browser console for details.');
})
.finally(() => this.set('inProgress', false));
}
}
@@ -63,6 +63,17 @@
</p>
</label>
{{#if details}}
<label>
<p class="label">Details:</p>
<p>
<pre>
{{details}}
</pre>
</p>
</label>
{{/if}}
<p class="actions">
{{input type="submit"
disabled=inProgress
+7 -2
View File
@@ -1,7 +1,9 @@
import Component from '@ember/component';
import { computed } from '@ember/object';
import { and, notEmpty } from '@ember/object/computed';
import { inject as service } from '@ember/service';
import { isPresent } from '@ember/utils';
import { isAddress } from 'web3-utils';
export default Component.extend({
@@ -9,14 +11,17 @@ export default Component.extend({
attributes: null,
// TODO: add proper address validation
isValidAccount: notEmpty('account'),
isValidAccount: computed('account', function() {
return isAddress(this.account);
}),
isValidName: notEmpty('name'),
isValidURL: notEmpty('url'),
isValidGithubUID: notEmpty('github_uid'),
isValidGithubUsername: notEmpty('github_username'),
isValidGiteaUsername: notEmpty('gitea_username'),
isValidWikiUsername: notEmpty('wiki_username'),
isValid: and(
'isValidAccount',
'isValidName',
+5
View File
@@ -0,0 +1,5 @@
import Component from '@ember/component';
export default Component.extend({
tagName: ""
});
+15
View File
@@ -0,0 +1,15 @@
<svg width="60px" height="60px" version="1.1" viewBox="0 0 60 60" xmlns="http://www.w3.org/2000/svg" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
<g fill="none" fill-rule="evenodd">
<g transform="translate(-479,-238)" stroke="#fbe468" stroke-linecap="round" stroke-linejoin="round" stroke-width="1">
<g transform="translate(482,244)">
<a transform="translate(0,2)">
<polygon id="Triangle-58" points="0.15321 44 27 0 53.847 44"/>
</a>
<rect x="25" y="13" width="4" height="21"/>
<a transform="translate(0,2)">
<circle cx="27" cy="38" r="2"/>
</a>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 750 B

@@ -0,0 +1,46 @@
import Component from '@ember/component';
import { inject as service } from '@ember/service';
import { computed } from '@ember/object';
import { isPresent } from '@ember/utils';
export default Component.extend({
tagName: '',
kredits: service(),
router: service(),
setupInProgress: false,
userHasEthereumWallet: computed(function() {
return isPresent(window.ethereum);
}).volatile(),
showConnectButton: computed('userHasEthereumWallet',
'kredits.hasAccounts', function() {
return this.userHasEthereumWallet &&
!this.kredits.hasAccounts;
}),
actions: {
signup() {
this.router.transitionTo('signup');
},
async connectAccount() {
try {
await window.ethereum.enable();
this.set('setupInProgress', true);
await this.kredits.setup();
this.set('setupInProgress', false);
this.router.transitionTo('dashboard');
} catch (error) {
this.set('setupInProgress', false);
console.log('Opening Ethereum wallet failed:', error);
}
}
}
});
@@ -0,0 +1,18 @@
<section id="user-account">
{{#if setupInProgress}}
Connecting account...
{{else}}
{{#if (and kredits.hasAccounts kredits.currentUser)}}
{{kredits.currentUser.name}}
{{#if kredits.currentUserIsCore}}
<span class="core-flag">(core)</span>
{{/if}}
{{else}}
Anonymous
<button {{action "signup"}} class="small">Sign up</button>
{{#if showConnectButton}}
<button {{action "connectAccount"}} class="small green">Connect account</button>
{{/if}}
{{/if}}
{{/if}}
</section>
@@ -0,0 +1,7 @@
import ContributionsNewController from 'kredits-web/controllers/contributions/new';
export default ContributionsNewController.extend({
attributes: null,
});
@@ -0,0 +1,12 @@
import Controller from '@ember/controller';
import { computed } from '@ember/object';
import config from 'kredits-web/config/environment';
export default Controller.extend({
ipfsGatewayUrl: computed(function() {
return config.ipfs.gatewayUrl;
}).volatile()
});
+49
View File
@@ -0,0 +1,49 @@
import Controller from '@ember/controller';
import { computed } from '@ember/object';
import { alias, not } from '@ember/object/computed';
import { isAddress } from 'web3-utils';
import { inject as service } from '@ember/service';
import config from 'kredits-web/config/environment';
export default Controller.extend({
kredits: service(),
ethAddress: null,
githubAccessToken: alias('kredits.githubAccessToken'),
isValidEthAccount: computed('ethAddress', function() {
return isAddress(this.ethAddress);
}),
signupButtonDisabled: not('isValidEthAccount'),
actions: {
completeSignup () {
const payload = {
accessToken: this.githubAccessToken,
account: this.ethAddress
}
fetch(config.githubSignupUrl, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
})
.then(res => res.json())
.then(data => {
console.log('Created contributor:', data);
this.setProperties({
githubAccessToken: null,
ethAddress: null
});
this.transitionToRoute('signup.complete');
});
}
}
});
+14
View File
@@ -0,0 +1,14 @@
import Controller from '@ember/controller';
import config from 'kredits-web/config/environment';
export default Controller.extend({
actions: {
connectGithub () {
window.location = config.githubConnectUrl;
}
}
});
+7 -1
View File
@@ -1,5 +1,7 @@
import EmberObject, { computed } from '@ember/object';
import { isEmpty } from '@ember/utils';
import bignumber from 'kredits-web/utils/cps/bignumber';
import moment from 'moment';
export default EmberObject.extend({
@@ -24,11 +26,15 @@ export default EmberObject.extend({
init () {
this._super(...arguments);
this.set('details', {});
if (isEmpty(this.details)) this.set('details', {});
},
iso8601Date: computed('date', 'time', function() {
return this.time ? `${this.date}T${this.time}` : this.date;
}),
jsDate: computed('iso8601Date', function() {
return moment(this.iso8601Date).toDate();
})
});
+6
View File
@@ -21,11 +21,17 @@ Router.map(function() {
});
this.route('contributions', function() {
this.route('new');
this.route('resubmit', { path: ':id/resubmit' });
});
this.route('contributors', function() {
this.route('new');
this.route('edit', { path: ':id/edit' });
});
this.route('signup', function() {
this.route('github');
this.route('eth-account');
this.route('complete');
});
});
export default Router;
+1 -6
View File
@@ -4,7 +4,7 @@ import Route from '@ember/routing/route';
export default Route.extend({
kredits: service(),
beforeModel(transition) {
beforeModel(/* transition */) {
const kredits = this.kredits;
return kredits.setup().then(() => {
@@ -12,11 +12,6 @@ export default Route.extend({
console.error('Kredits preflight check failed!');
console.error(error);
});
if (kredits.get('accountNeedsUnlock')) {
if (confirm('It looks like you have an Ethereum wallet available. Please unlock your account.')) {
transition.retry();
}
}
}).catch((error) => {
console.log('Error initializing Kredits', error);
});
+25
View File
@@ -0,0 +1,25 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
export default Route.extend({
kredits: service(),
model(params) {
const contribution = this.kredits.contributions.findBy('id', parseInt(params.id));
contribution.contributorId = contribution.contributorId.toString();
return contribution;
},
setupController (controller, model) {
this._super(controller, model);
controller.set('attributes', model.getProperties([
'kind', 'amount', 'description', 'url', 'details'
]));
controller.set('attributes.contributorId', model.contributorId.toString());
controller.set('attributes.date', model.jsDate);
}
});
+4
View File
@@ -0,0 +1,4 @@
import Route from '@ember/routing/route';
export default Route.extend({
});
+4
View File
@@ -0,0 +1,4 @@
import Route from '@ember/routing/route';
export default Route.extend({
});
+17
View File
@@ -0,0 +1,17 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { isEmpty } from '@ember/utils';
export default Route.extend({
kredits: service(),
redirect () {
this._super(...arguments);
if (isEmpty(this.kredits.githubAccessToken)) {
this.transitionTo('signup.index');
}
}
});
+29
View File
@@ -0,0 +1,29 @@
import Route from '@ember/routing/route';
import { inject as service } from '@ember/service';
import { isEmpty } from '@ember/utils';
export default Route.extend({
kredits: service(),
redirect () {
this._super(...arguments);
let accessToken;
try {
accessToken = window.location.hash.match(/access_token=(.+)/)[1];
} catch (error) { /* ignore */ }
if (isEmpty(accessToken) || accessToken === 'undefined') {
console.error('No GitHub access token found.');
this.transitionTo('signup');
return;
}
this.kredits.set('githubAccessToken', accessToken);
this.transitionTo('signup.eth-account');
}
});
+53 -30
View File
@@ -6,7 +6,7 @@ import Service from '@ember/service';
import EmberObject from '@ember/object';
import { computed } from '@ember/object';
import { alias, notEmpty } from '@ember/object/computed';
import { isEmpty } from '@ember/utils';
import { isEmpty, isPresent } from '@ember/utils';
import groupBy from 'kredits-web/utils/group-by';
import formatKredits from 'kredits-web/utils/format-kredits';
@@ -24,15 +24,12 @@ export default Service.extend({
contributors: null,
contributions: null,
proposals: null,
githubAccessToken: null,
currentUserIsContributor: notEmpty('currentUser'),
currentUserIsCore: alias('currentUser.isCore'),
hasAccounts: notEmpty('currentUserAccounts'),
accountNeedsUnlock: computed('currentUserAccounts', function() {
return this.currentUserAccounts && isEmpty(this.currentUserAccounts);
}),
contributionsUnconfirmed: computed('contributions.[]', 'currentBlock', function() {
return this.contributions.filter(contribution => {
return contribution.confirmedAt > this.currentBlock;
@@ -104,7 +101,14 @@ export default Service.extend({
async function instantiateWithAccount (web3Provider, context) {
console.debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
ethProvider = new ethers.providers.Web3Provider(web3Provider);
// const network = await ethProvider.getNetwork();
const network = await ethProvider.getNetwork();
if (isPresent(config.web3RequiredNetwork) &&
network.name !== config.web3RequiredNetwork) {
window.alert(`Please switch your Ethereum wallet to the "${config.web3RequiredNetwork}" network before connecting your account.`);
return instantiateWithoutAccount();
}
ethProvider.listAccounts().then(accounts => {
context.set('currentUserAccounts', accounts);
const ethSigner = accounts.length === 0 ? null : ethProvider.getSigner();
@@ -116,12 +120,9 @@ export default Service.extend({
}
if (window.ethereum) {
try {
// Request account access if needed
await window.ethereum.enable();
// Acccounts now exposed
if (window.ethereum.isConnected()) {
instantiateWithAccount(window.ethereum, this);
} catch (error) {
} else {
instantiateWithoutAccount();
}
}
@@ -224,33 +225,36 @@ export default Service.extend({
console.debug('[kredits] add contribution response', data);
attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
const contribution = Contribution.create(attributes);
// TODO receive from wrapper
contribution.set('confirmedAtBlock', data.blockNumber + 40320);
this.contributions.pushObject(contribution);
return contribution;
});
},
addProposal (attributes) {
console.debug('[kredits] add proposal', attributes);
//
// TODO Implement proposals with voting
//
return this.kredits.Proposal.addProposal(attributes)
.then((data) => {
console.debug('[kredits] add proposal response', data);
attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
return Proposal.create(attributes);
});
},
// addProposal (attributes) {
// console.debug('[kredits] add proposal', attributes);
//
// return this.kredits.Proposal.addProposal(attributes)
// .then((data) => {
// console.debug('[kredits] add proposal response', data);
// attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
// return Proposal.create(attributes);
// });
// },
getProposals () {
return this.kredits.Proposal.all()
.then((proposals) => {
return proposals.map((proposal) => {
proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
return Proposal.create(proposal);
});
});
},
// getProposals () {
// return this.kredits.Proposal.all()
// .then(proposals => {
// return proposals.map(proposal => {
// proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
// return Proposal.create(proposal);
// });
// });
// },
getContributions () {
return this.kredits.Contribution.all({page: {size: 200}})
@@ -310,6 +314,7 @@ export default Service.extend({
.on('ContributorAdded', this.handleContributorChange.bind(this))
this.kredits.Contribution
.on('ContributionAdded', this.handleContributionAdded.bind(this))
.on('ContributionVetoed', this.handleContributionVetoed.bind(this))
this.kredits.Proposal
@@ -337,6 +342,24 @@ export default Service.extend({
this.contributors.pushObject(newContributor);
},
async handleContributionAdded (id, contributorId, amount) {
console.debug('[kredits] ContributionAdded event received', { id, contributorId, amount });
const pendingContribution = this.contributions.find(c => {
return (c.id === null) &&
(c.contributorId.toString() === contributorId.toString()) &&
(c.amount.toString() === amount.toString());
});
if (pendingContribution) {
const attributes = await this.kredits.Contribution.getById(id);
attributes.contributor = this.contributors.findBy('id', attributes.contributorId.toString());
const newContribution = Contribution.create(attributes);
this.contributions.addObject(newContribution);
this.contributions.removeObject(pendingContribution);
}
},
handleContributionVetoed (contributionId) {
console.debug('[kredits] ContributionVetoed event received for ', contributionId);
const contribution = this.contributions.findBy('id', contributionId);
+18 -1
View File
@@ -23,8 +23,12 @@ button, input[type=submit], .button {
border-color: $primary-color;
}
&[disabled] {
color: rgba(255,255,255,0.5);
}
&.small {
font-size: 0.8rem;
font-size: 0.86rem;
padding: 0.2rem 0.8rem;
}
@@ -53,4 +57,17 @@ button, input[type=submit], .button {
border-color: $green;
}
}
&.icon {
svg {
width: 2rem;
height: 2rem;
vertical-align: middle;
margin-right: 1rem;
.fg {
fill: $primary-color;
}
}
}
}
+6 -1
View File
@@ -1,12 +1,17 @@
section#add-contributor,
section#add-contribution,
section#add-proposal {
section#add-proposal,
section#signup {
form {
p {
margin-bottom: 1.5rem;
&.mg-bottom-md {
margin-bottom: 2rem;
}
&.label {
margin-bottom: .5rem;
}
+31
View File
@@ -28,6 +28,37 @@ main {
}
}
}
section {
.content {
a {
font-size: inherit;
}
&.text-lg {
p {
font-size: 1.2rem;
margin-bottom: 1em;
line-height: 1.5em;
}
}
&.text-center {
text-align: center;
}
p {
&.mg-bottom-md {
margin-bottom: 2rem;
}
&.actions {
text-align: center;
padding-top: 2rem;
}
}
}
}
}
@media (min-width: 550px) {
+11 -3
View File
@@ -2,7 +2,6 @@
margin: 0;
padding: 0;
box-sizing: border-box;
font-size: 14px;
}
*:hover, *:active, *:focus {
@@ -17,13 +16,17 @@
$font-family-sans: 'Open Sans', sans-serif;
body {
html, body {
font-family: $font-family-sans;
font-weight: 300;
font-size: 12px;
color: $body-text-color;
}
body {
background-image: linear-gradient(to bottom, rgba(22, 21, 40, .4), rgba(0, 0, 0, .75)), url('/img/bg.jpg');
background-repeat: none;
background-attachment: fixed;
color: $body-text-color;
}
@media screen and (min-width: 900px) {
@@ -38,6 +41,10 @@ h1, h2, h3, h4, h5, input, button {
font-weight: 300;
}
a {
color: $primary-color;
}
section {
h2 {
font-size: 1.4rem;
@@ -106,4 +113,5 @@ section {
@import "components/loading-spinner";
@import "components/proposal-list";
@import "components/topbar";
@import "components/topbar-account-panel";
@import "components/user-avatar";
@@ -29,7 +29,6 @@ section#contribution-details {
margin-bottom: 2rem;
span {
font-size: inherit;
}
&.who-what-when {
@@ -42,12 +41,11 @@ section#contribution-details {
}
}
a {
a:not(.button) {
color: $primary-color;
text-decoration: none;
font-size: inherit;
&:hover {
&:not(.button):hover {
text-decoration: underline;
}
}
@@ -56,4 +54,35 @@ section#contribution-details {
.actions {
text-align: center;
}
&.vetoed {
.content {
h3 {
text-decoration: line-through;
}
}
}
.hint.vetoed {
overflow: auto;
margin-top: 2rem;
padding-top: 2rem;
border-top: 1px solid rgba(255,255,255,0.2);
font-size: 1.2rem;
.icon {
display: inline-block;
width: 40px;
height: 40px;
float: left;
margin-right: 1rem;
margin-bottom: 1rem;
svg {
width: 100%;
height: auto;
}
}
}
}
@@ -11,13 +11,10 @@ main section {
margin-bottom: 2rem;
p {
font-size: inherit;
padding: 0.2rem 0 0;
}
label {
font-size: inherit;
&+ label {
margin-left: 3.6rem;
}
@@ -60,7 +57,6 @@ ul.contribution-list {
p {
align-self: center;
margin: 0;
font-size: inherit;
line-height: 2rem;
overflow: hidden;
text-overflow: ellipsis;
@@ -72,11 +68,8 @@ ul.contribution-list {
}
span {
font-size: inherit;
&.title {
a {
font-size: inherit;
text-decoration: none;
color: $body-text-color;
}
@@ -151,9 +144,7 @@ ul.contribution-list {
}
}
.description {
font-size: inherit;
}
}
}
@@ -19,7 +19,6 @@ ul.proposal-list {
p {
align-self: center;
margin: 0;
font-size: inherit;
line-height: 2rem;
&.kredits-amount, &.voting {
@@ -36,7 +35,6 @@ ul.proposal-list {
}
span {
font-size: inherit;
}
.description {
@@ -107,7 +105,6 @@ ul.proposal-list {
.description {
font-size: inherit;
}
}
}
@@ -0,0 +1,11 @@
header#topbar section#user-account {
button {
margin-left: 1.5rem;
}
button + button {
margin-left: 0.6rem;
}
}
+1 -11
View File
@@ -1,16 +1,6 @@
<header id="topbar">
<h1>{{link-to "Kosmos Kredits" "dashboard"}}</h1>
<section id="user-account">
{{#if kredits.hasAccounts }}
{{#if kredits.currentUser}}
{{kredits.currentUser.name}}
{{#if kredits.currentUserIsCore}}(core){{/if}}
{{/if}}
{{else}}
Anonymous
{{/if}}
</section>
{{topbar-account-panel}}
</header>
{{outlet}}
+13
View File
@@ -0,0 +1,13 @@
<main class="center-column">
<section id="add-contribution">
<header>
<h2>Re-submit contribution #{{model.id}}</h2>
</header>
<div class="content">
{{add-contribution attributes=attributes contributors=sortedContributors save=(action "save")}}
</div>
</section>
</main>
+16 -2
View File
@@ -1,4 +1,4 @@
<section id="contribution-details">
<section id="contribution-details" class={{if model.vetoed "vetoed"}}>
<header class="with-nav">
<h2>Contribution #{{model.id}}</h2>
<nav>
@@ -32,12 +32,26 @@
</a>
</p>
{{/if}}
{{#if model.vetoed}}
<div class="hint vetoed">
<div class="icon">
{{icon-warning}}
</div>
<p>
This contribution has been vetoed, meaning no
kredits will be issued.
</p>
<p>
{{link-to "Re-submit contribution …" "contributions.resubmit" model class="button small green"}}.
</p>
</div>
{{/if}}
</div>
<div class="actions">
<p>
{{#if model.ipfsHash}}
<a href="https://ipfs.io/ipfs/{{model.ipfsHash}}"
<a href="{{ipfsGatewayUrl}}/{{model.ipfsHash}}"
class="button small" target="_blank" rel="noopener">
Inspect IPFS data
</a>
+5
View File
@@ -0,0 +1,5 @@
<main class="center-column">
<section id="signup">
{{outlet}}
</section>
</main>
+15
View File
@@ -0,0 +1,15 @@
<header>
<h2>Welcome aboard!</h2>
</header>
<div class="content text-lg text-center">
<p>
Congratulations. Your initial profile is now complete.
</p>
<p>
Why not say hi to your fellow contributors
<a href="https://wiki.kosmos.org/Main_Page#Community_.2F_Getting_in_touch_.2F_Getting_involved">in one of our chat rooms</a>?.
</p>
<p class="actions">
{{#link-to "dashboard" class="button small"}}Return to dashboard{{/link-to}}
</p>
</div>
+25
View File
@@ -0,0 +1,25 @@
<header>
<h2>Complete your contributor profile</h2>
</header>
<div class="content text-lg">
<p class="mg-bottom-md">
Kredits allow you to take part in project governance, and to earn rewards for
your contributions. For both, you will need an Ethereum wallet/account.
</p>
<form {{action "submit" on="submit"}}>
<p>
<label>
Ethereum account:<br>
{{input type="text" value=ethAddress
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
class=(if isValidEthAccount "valid" "")}}
</label>
</p>
</form>
<p class="actions">
<button disabled={{signupButtonDisabled}}
{{action "completeSignup"}}>
Complete my profile
</button>
</p>
</div>
+20
View File
@@ -0,0 +1,20 @@
<header>
<h2>Create your contributor profile</h2>
</header>
<div class="content text-lg">
<p>
You have already contributed to a Kosmos project, or you are interested
in contributing in the near future? Fantastic!
</p>
<p>
In order to earn kredits for your contributions, you will need a
registered contributor profile. The quickest way to register is by
connecting one of the following accounts:
</p>
<p class="actions">
<button {{action "connectGithub"}} class="icon">
{{icon-account-github-com}}
Connect GitHub
</button>
</p>
</div>
+10 -7
View File
@@ -36,6 +36,10 @@ module.exports = function(environment) {
},
web3ProviderUrl: 'https://rinkeby.infura.io/v3/d4f788b7a6584f7db2fc3c268d4d09e9',
web3RequiredNetwork: 'rinkeby',
githubConnectUrl: 'https://hal8000.chat.kosmos.org/kredits/signup/connect/github',
githubSignupUrl: 'https://hal8000.chat.kosmos.org/kredits/signup/github',
ipfs: {
host: 'ipfs.kosmos.org',
@@ -53,6 +57,9 @@ module.exports = function(environment) {
// ENV.APP.LOG_VIEW_LOOKUPS = true;
ENV.web3ProviderUrl = 'https://rinkeby.infura.io/v3/d4f788b7a6584f7db2fc3c268d4d09e9';
ENV.githubConnectUrl = 'http://localhost:8888/kredits/signup/connect/github';
ENV.githubSignupUrl = 'http://localhost:8888/kredits/signup/github';
ENV.ipfs = {
host: 'localhost',
port: '5001',
@@ -73,16 +80,12 @@ module.exports = function(environment) {
ENV.APP.autoboot = false;
}
if (environment === 'production') {
// here you can enable a production-specific feature
ENV.kreditsApmDomain = process.env.KREDITS_APM_DOMAIN || 'open.aragonpm.eth';
}
if (process.env.WEB3_PROVIDER_URL) {
ENV.web3ProviderUrl = process.env.WEB3_PROVIDER_URL;
ENV.web3RequiredNetwork = null;
}
if (process.env.KREDITS_KERNEL_ADDRESS) {
ENV.kreditsKernelAddress = process.env.KREDITS_KERNEL_ADDRESS;
if (process.env.KREDITS_DAO_ADDRESS) {
ENV.kreditsKernelAddress = process.env.KREDITS_DAO_ADDRESS;
}
if (process.env.KREDITS_APM_DOMAIN) {
ENV.kreditsApmDomain = process.env.KREDITS_APM_DOMAIN;
+239 -16
View File
@@ -1,6 +1,6 @@
{
"name": "kredits-web",
"version": "1.7.0",
"version": "1.10.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -4241,6 +4241,12 @@
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
"dev": true
},
"buffer-to-arraybuffer": {
"version": "0.0.5",
"resolved": "https://registry.npmjs.org/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz",
"integrity": "sha1-YGSkD6dutDxyOrqe+PbhIW0QURo=",
"dev": true
},
"buffer-xor": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
@@ -5636,6 +5642,12 @@
"esutils": "^2.0.2"
}
},
"dom-walk": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/dom-walk/-/dom-walk-0.1.1.tgz",
"integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg=",
"dev": true
},
"domain-browser": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
@@ -8327,9 +8339,9 @@
}
},
"eslint-utils": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.0.tgz",
"integrity": "sha512-7ehnzPaP5IIEh1r1tkjuIrxqhNkzUJa9z3R92tLJdZIVdWaczEhr3EbhGtsMrVxi1KeR8qA7Off6SWc5WNQqyQ==",
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.2.tgz",
"integrity": "sha512-eAZS2sEUMlIeCjBeubdj45dmBHQwPHWyBcT1VSYB7o9x9WRRqKxyUoiXlRjyAwzN7YEzHJlYg0NmzDRWx6GP4Q==",
"dev": true,
"requires": {
"eslint-visitor-keys": "^1.0.0"
@@ -8414,6 +8426,17 @@
"integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
"dev": true
},
"eth-lib": {
"version": "0.2.7",
"resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz",
"integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=",
"dev": true,
"requires": {
"bn.js": "^4.11.6",
"elliptic": "^6.4.0",
"xhr-request-promise": "^0.1.2"
}
},
"ethers": {
"version": "4.0.27",
"resolved": "https://registry.npmjs.org/ethers/-/ethers-4.0.27.tgz",
@@ -8468,6 +8491,24 @@
}
}
},
"ethjs-unit": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/ethjs-unit/-/ethjs-unit-0.1.6.tgz",
"integrity": "sha1-xmWSHkduh7ziqdWIpv4EBbLEFpk=",
"dev": true,
"requires": {
"bn.js": "4.11.6",
"number-to-bn": "1.7.0"
},
"dependencies": {
"bn.js": {
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
"dev": true
}
}
},
"event-emitter": {
"version": "0.3.5",
"resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
@@ -9245,6 +9286,15 @@
}
}
},
"for-each": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
"integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
"dev": true,
"requires": {
"is-callable": "^1.1.3"
}
},
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -10073,6 +10123,24 @@
"integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
"dev": true
},
"global": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
"integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
"dev": true,
"requires": {
"min-document": "^2.19.0",
"process": "~0.5.1"
},
"dependencies": {
"process": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
"integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8=",
"dev": true
}
}
},
"global-modules": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
@@ -11111,6 +11179,12 @@
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
},
"is-function": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz",
"integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=",
"dev": true
},
"is-git-url": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-git-url/-/is-git-url-1.0.0.tgz",
@@ -11126,6 +11200,12 @@
"is-extglob": "^2.1.0"
}
},
"is-hex-prefixed": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz",
"integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=",
"dev": true
},
"is-ip": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-ip/-/is-ip-2.0.0.tgz",
@@ -11874,9 +11954,9 @@
}
},
"lodash": {
"version": "4.17.11",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
"integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==",
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==",
"dev": true
},
"lodash._baseassign": {
@@ -12151,9 +12231,9 @@
}
},
"lodash.defaultsdeep": {
"version": "4.6.0",
"resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.0.tgz",
"integrity": "sha1-vsECT4WxvZbL6kBbI8FK1kQ6b4E=",
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/lodash.defaultsdeep/-/lodash.defaultsdeep-4.6.1.tgz",
"integrity": "sha512-3j8wdDzYuWO3lM3Reg03MuQR957t287Rpcxp1njpEa8oDrikb+FwGdW3n+FELh/A6qib6yPit0j/pv9G/yeAqA==",
"dev": true
},
"lodash.escape": {
@@ -12249,15 +12329,15 @@
}
},
"lodash.merge": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz",
"integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==",
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
"dev": true
},
"lodash.mergewith": {
"version": "4.6.1",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
"integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==",
"version": "4.6.2",
"resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
"integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
"dev": true
},
"lodash.noop": {
@@ -12765,6 +12845,15 @@
"integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==",
"dev": true
},
"min-document": {
"version": "2.19.0",
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
"dev": true,
"requires": {
"dom-walk": "^0.1.0"
}
},
"minimalistic-assert": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
@@ -13433,6 +13522,24 @@
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=",
"dev": true
},
"number-to-bn": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/number-to-bn/-/number-to-bn-1.7.0.tgz",
"integrity": "sha1-uzYjWS9+X54AMLGXe9QaDFP+HqA=",
"dev": true,
"requires": {
"bn.js": "4.11.6",
"strip-hex-prefix": "1.0.0"
},
"dependencies": {
"bn.js": {
"version": "4.11.6",
"resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz",
"integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=",
"dev": true
}
}
},
"nwsapi": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz",
@@ -13781,6 +13888,16 @@
"safe-buffer": "^5.1.1"
}
},
"parse-headers": {
"version": "2.0.2",
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.2.tgz",
"integrity": "sha512-/LypJhzFmyBIDYP9aDVgeyEb5sQfbfY5mnDq4hVhlQ69js87wXfmEI5V3xI6vvXasqebp0oCytYFLxsBVfCzSg==",
"dev": true,
"requires": {
"for-each": "^0.3.3",
"string.prototype.trim": "^1.1.2"
}
},
"parse-json": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
@@ -14500,6 +14617,12 @@
"safe-buffer": "^5.1.0"
}
},
"randomhex": {
"version": "0.1.5",
"resolved": "https://registry.npmjs.org/randomhex/-/randomhex-0.1.5.tgz",
"integrity": "sha1-us7vmCMpCRQA8qKRLGzQLxCU9YU=",
"dev": true
},
"range-parser": {
"version": "1.2.1",
"resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
@@ -15430,6 +15553,23 @@
"debug": "^2.2.0"
}
},
"simple-concat": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz",
"integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=",
"dev": true
},
"simple-get": {
"version": "2.8.1",
"resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
"integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
"dev": true,
"requires": {
"decompress-response": "^3.3.0",
"once": "^1.3.1",
"simple-concat": "^1.0.0"
}
},
"simple-html-tokenizer": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/simple-html-tokenizer/-/simple-html-tokenizer-0.5.7.tgz",
@@ -16118,6 +16258,17 @@
}
}
},
"string.prototype.trim": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz",
"integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=",
"dev": true,
"requires": {
"define-properties": "^1.1.2",
"es-abstract": "^1.5.0",
"function-bind": "^1.0.2"
}
},
"string_decoder": {
"version": "0.10.31",
"resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
@@ -16148,6 +16299,15 @@
"integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
"dev": true
},
"strip-hex-prefix": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz",
"integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=",
"dev": true,
"requires": {
"is-hex-prefixed": "1.0.0"
}
},
"strip-indent": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
@@ -17039,6 +17199,12 @@
"prepend-http": "^2.0.0"
}
},
"url-set-query": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/url-set-query/-/url-set-query-1.0.0.tgz",
"integrity": "sha1-AW6M/Xwg7gXK/neV6JK9BwL6ozk=",
"dev": true
},
"url-to-options": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz",
@@ -17067,6 +17233,12 @@
"integrity": "sha512-ayNkOJdoNSGNDBE46Nkc+l6IXmeugbzahZLSMkwvgRWv5y5ZqNY2IrzcgmkR4z32sj1W3tM3TuTUMqkqBzO+RA==",
"dev": true
},
"utf8": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz",
"integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==",
"dev": true
},
"util-deprecate": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
@@ -17212,6 +17384,21 @@
"defaults": "^1.0.3"
}
},
"web3-utils": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0.tgz",
"integrity": "sha512-zm0gdLXLk54ldwxxBMNPS62EuqHI2PaJohEGijTowacNS0BS2vEXdriNA8gp1+EplP2WgoHE0uRVmQIfpAyV+Q==",
"dev": true,
"requires": {
"bn.js": "4.11.8",
"eth-lib": "0.2.7",
"ethjs-unit": "0.1.6",
"number-to-bn": "1.7.0",
"randomhex": "0.1.5",
"underscore": "1.9.1",
"utf8": "3.0.0"
}
},
"webidl-conversions": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
@@ -17483,6 +17670,42 @@
"integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
"dev": true
},
"xhr": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
"integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
"dev": true,
"requires": {
"global": "~4.3.0",
"is-function": "^1.0.1",
"parse-headers": "^2.0.0",
"xtend": "^4.0.0"
}
},
"xhr-request": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/xhr-request/-/xhr-request-1.1.0.tgz",
"integrity": "sha512-Y7qzEaR3FDtL3fP30k9wO/e+FBnBByZeybKOhASsGP30NIkRAAkKD/sCnLvgEfAIEC1rcmK7YG8f4oEnIrrWzA==",
"dev": true,
"requires": {
"buffer-to-arraybuffer": "^0.0.5",
"object-assign": "^4.1.1",
"query-string": "^5.0.1",
"simple-get": "^2.7.0",
"timed-out": "^4.0.1",
"url-set-query": "^1.0.0",
"xhr": "^2.0.4"
}
},
"xhr-request-promise": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/xhr-request-promise/-/xhr-request-promise-0.1.2.tgz",
"integrity": "sha1-NDxE0e53JrhkgGloLQ+EDIO0Jh0=",
"dev": true,
"requires": {
"xhr-request": "^1.0.1"
}
},
"xml-name-validator": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+5 -4
View File
@@ -1,6 +1,6 @@
{
"name": "kredits-web",
"version": "1.7.0",
"version": "1.10.0",
"private": true,
"description": "Contribution dashboard of the Kosmos project",
"repository": "https://github.com/67P/kredits-web",
@@ -14,8 +14,8 @@
"lint:hbs": "ember-template-lint .",
"lint:js": "eslint .",
"test": "ember test",
"start": "KREDITS_APM_DOMAIN=open.aragonpm.eth ember serve",
"start:local": "WEB3_PROVIDER_URL=http://localhost:7545 ember s",
"start": "ember serve",
"start:local": "WEB3_PROVIDER_URL=http://localhost:7545 ember serve",
"build": "ember build",
"build-prod": "rm -rf release/* && ember build -prod --output-path release",
"preversion": "npm test",
@@ -67,7 +67,8 @@
"ndjson": "github:hugomrdias/ndjson#feat/readable-stream3",
"qunit-dom": "^0.8.4",
"transform-loader": "^0.2.4",
"tv4": "^1.3.0"
"tv4": "^1.3.0",
"web3-utils": "^1.0.0"
},
"engines": {
"node": "8.* || >= 10.*"
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+4 -4
View File
@@ -8,10 +8,10 @@
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<meta name="kredits-web/config/environment" content="%7B%22modulePrefix%22%3A%22kredits-web%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22auto%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%2C%22_JQUERY_INTEGRATION%22%3Atrue%7D%2C%22APP%22%3A%7B%22name%22%3A%22kredits-web%22%2C%22version%22%3A%221.7.0%2Ba4ca37d8%22%7D%2C%22browserify%22%3A%7B%22tests%22%3Atrue%2C%22transform%22%3A%5B%5B%22babelify%22%2C%7B%22presets%22%3A%5B%22es2015%22%5D%2C%22global%22%3Atrue%7D%5D%5D%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frinkeby.infura.io%2Fv3%2Fd4f788b7a6584f7db2fc3c268d4d09e9%22%2C%22ipfs%22%3A%7B%22host%22%3A%22ipfs.kosmos.org%22%2C%22port%22%3A%225444%22%2C%22protocol%22%3A%22https%22%2C%22gatewayUrl%22%3A%22https%3A%2F%2Fipfs.kosmos.org%2Fipfs%22%7D%2C%22kreditsApmDomain%22%3A%22open.aragonpm.eth%22%2C%22exportApplicationGlobal%22%3Afalse%7D" />
<meta name="kredits-web/config/environment" content="%7B%22modulePrefix%22%3A%22kredits-web%22%2C%22environment%22%3A%22production%22%2C%22rootURL%22%3A%22%2F%22%2C%22locationType%22%3A%22auto%22%2C%22EmberENV%22%3A%7B%22FEATURES%22%3A%7B%7D%2C%22EXTEND_PROTOTYPES%22%3A%7B%22Date%22%3Afalse%7D%2C%22_JQUERY_INTEGRATION%22%3Atrue%7D%2C%22APP%22%3A%7B%22name%22%3A%22kredits-web%22%2C%22version%22%3A%221.10.0%2B7b9659e2%22%7D%2C%22browserify%22%3A%7B%22tests%22%3Atrue%2C%22transform%22%3A%5B%5B%22babelify%22%2C%7B%22presets%22%3A%5B%22es2015%22%5D%2C%22global%22%3Atrue%7D%5D%5D%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frinkeby.infura.io%2Fv3%2Fd4f788b7a6584f7db2fc3c268d4d09e9%22%2C%22web3RequiredNetwork%22%3A%22rinkeby%22%2C%22githubConnectUrl%22%3A%22https%3A%2F%2Fhal8000.chat.kosmos.org%2Fkredits%2Fsignup%2Fconnect%2Fgithub%22%2C%22githubSignupUrl%22%3A%22https%3A%2F%2Fhal8000.chat.kosmos.org%2Fkredits%2Fsignup%2Fgithub%22%2C%22ipfs%22%3A%7B%22host%22%3A%22ipfs.kosmos.org%22%2C%22port%22%3A%225444%22%2C%22protocol%22%3A%22https%22%2C%22gatewayUrl%22%3A%22https%3A%2F%2Fipfs.kosmos.org%2Fipfs%22%7D%2C%22exportApplicationGlobal%22%3Afalse%7D" />
<link integrity="" rel="stylesheet" href="/assets/vendor-179cf27a97ea5bbb0ce72403a401cc8c.css">
<link integrity="" rel="stylesheet" href="/assets/kredits-web-e95be4cbe614c5aa4c7a891c6eedb028.css">
<link integrity="" rel="stylesheet" href="/assets/kredits-web-bf8cdb5aeca9f819317b56a053af9a07.css">
@@ -24,8 +24,8 @@
<body>
<script src="/assets/vendor-d84a577c9f0624a0b15861936fe740f2.js" integrity="sha256-o5SitqUpXKccldebvatDY/WvXTbEnAu/IA/TyvBxU0U= sha512-gDMabciAMuF89anreuu39lAYDOf6tXMMHxVRUxtqGpmhJdSAUQGFQ2MWTgE8mt+8GvGvPxw9QvnHuBJDK34YVw==" ></script>
<script src="/assets/kredits-web-abcf1575c8eb056a923a583efdc2d00f.js" integrity="sha256-IEH1g/CviSkQ/8acQOgUqB1iPBlXgsJlGJqsAzs9iqg= sha512-znuWeezXPnfkekpebFEC/4uVT0DjHS52ORURS11H7+kCtgyMjLqvSS8it/GzLxSsameIUaoMsvctqhL8f+atMg==" ></script>
<script src="/assets/vendor-13d8e4e4e82dd7bac91d821b2e30d995.js" integrity="sha256-7W4pPHJA775yfzH5yRprMaeGsW0iuMwhw2JwjXc2+Pk= sha512-fQfK5OmWIdSpGamuq7f3/EpCbVQnGSgR1VPXwxWRCu8JFeXdrUDmK67J4lHuC5cHc8yxD9WFymXKugeH7+NNgA==" ></script>
<script src="/assets/kredits-web-f1054baf811714b6865ab8c77c69fb4c.js" integrity="sha256-hrHVjH6k8rdA8LxWsKWsd300dN0+m/osbECl2U0ntZ8= sha512-L2xrymtmnW49TvaECYHqQ5Ql4lkEDERWveK1i66UbA3DddwdaFTjqPSLdj7kq6doX6TTlBdzfEDdsuwUjLyxeg==" ></script>
</body>
@@ -0,0 +1,39 @@
import { module, test } from 'qunit';
import { setupRenderingTest } from 'ember-qunit';
import { render } from '@ember/test-helpers';
import hbs from 'htmlbars-inline-precompile';
module('Integration | Component | topbar-account-panel', function(hooks) {
setupRenderingTest(hooks);
test('unknown user without wallet (or no permission to get wallet/account info)', async function(assert) {
await render(hbs`<TopbarAccountPanel />`);
assert.ok(this.element.textContent.trim().match(/^Anonymous/));
});
test('unknown user with Ethereum wallet', async function(assert) {
let service = this.owner.lookup('service:kredits');
service.set('currentUserAccounts', [{ foo: 'bar' }]);
await render(hbs`<TopbarAccountPanel />`);
assert.ok(this.element.textContent.trim().match(/^Anonymous/));
});
test('known contributor', async function(assert) {
let service = this.owner.lookup('service:kredits');
service.set('currentUserAccounts', [{ foo: 'bar' }]);
service.set('currentUser', {
name: 'Dorian Nakamoto',
isCore: false
});
await render(hbs`<TopbarAccountPanel />`);
assert.equal(this.element.textContent.trim(), 'Dorian Nakamoto');
service.set('currentUser.isCore', true);
await render(hbs`<TopbarAccountPanel />`);
assert.equal(this.element.querySelectorAll('span.core-flag').length, 1);
});
});
+27
View File
@@ -0,0 +1,27 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
import Contribution from 'kredits-web/models/contribution';
module('Unit | Model | contribution', function(hooks) {
setupTest(hooks);
test('iso8601Date', function(assert) {
const model = Contribution.create({
date: '2019-09-10'
});
assert.equal(model.iso8601Date, '2019-09-10');
model.set('time', '09:33:00.141Z');
assert.equal(model.iso8601Date, '2019-09-10T09:33:00.141Z');
});
test('jsDate', function(assert) {
const model = Contribution.create({
date: '2019-09-10',
time: '09:33:00.141Z'
});
assert.ok(model.jsDate instanceof Date);
assert.equal(model.jsDate.toISOString(), '2019-09-10T09:33:00.141Z');
});
});
@@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Route | contributions/resubmit', function(hooks) {
setupTest(hooks);
test('it exists', function(assert) {
let route = this.owner.lookup('route:contributions/resubmit');
assert.ok(route);
});
});
+11
View File
@@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Route | signup', function(hooks) {
setupTest(hooks);
test('it exists', function(assert) {
let route = this.owner.lookup('route:signup');
assert.ok(route);
});
});
+11
View File
@@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Route | signup/complete', function(hooks) {
setupTest(hooks);
test('it exists', function(assert) {
let route = this.owner.lookup('route:signup/complete');
assert.ok(route);
});
});
@@ -0,0 +1,11 @@
import { module, test } from 'qunit';
import { setupTest } from 'ember-qunit';
module('Unit | Route | signup/eth-account', function(hooks) {
setupTest(hooks);
test('it exists', function(assert) {
let route = this.owner.lookup('route:signup/eth-account');
assert.ok(route);
});
});
+71
View File
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:sketch="http://www.bohemiancoding.com/sketch/ns"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
id="svg15"
version="1.1"
viewBox="0 0 60 60"
height="60px"
width="60px">
<metadata
id="metadata19">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title>Warning</dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
<!-- Generator: Sketch 3.2.2 (9983) - http://www.bohemiancoding.com/sketch -->
<title
id="title2">Warning</title>
<desc
id="desc4">Created with Sketch.</desc>
<defs
id="defs6" />
<g
style="fill:none;fill-rule:evenodd;stroke:none;stroke-width:1"
sketch:type="MSPage"
id="stroked">
<g
style="stroke:#535353;stroke-width:2;stroke-linecap:round;stroke-linejoin:round"
transform="translate(-479,-238)"
sketch:type="MSLayerGroup"
id="Transport">
<g
sketch:type="MSShapeGroup"
transform="translate(482,244)"
id="Warning">
<a
transform="translate(0,2)"
id="a4529">
<polygon
id="Triangle-58"
points="0.15321248,44 27,0 53.846787,44 " />
</a>
<rect
height="21"
width="4"
y="13"
x="25"
id="Rectangle-1700" />
<a
transform="translate(0,2)"
id="a4532">
<circle
id="Oval-1484"
cx="27"
cy="38"
r="2" />
</a>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB