Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 970b390509 | |||
| b8f4040def | |||
| 8fbecd928b |
+1
-1
@@ -5,5 +5,5 @@
|
|||||||
|
|
||||||
Setting `disableAnalytics` to true will prevent any data from being sent.
|
Setting `disableAnalytics` to true will prevent any data from being sent.
|
||||||
*/
|
*/
|
||||||
"disableAnalytics": true
|
"disableAnalytics": false
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,21 +0,0 @@
|
|||||||
# unconventional js
|
|
||||||
/blueprints/*/files/
|
|
||||||
/vendor/
|
|
||||||
|
|
||||||
# compiled output
|
|
||||||
/dist/
|
|
||||||
/tmp/
|
|
||||||
/release/
|
|
||||||
|
|
||||||
# dependencies
|
|
||||||
/bower_components/
|
|
||||||
/node_modules/
|
|
||||||
|
|
||||||
# misc
|
|
||||||
/coverage/
|
|
||||||
!.*
|
|
||||||
|
|
||||||
# ember-try
|
|
||||||
/.node_modules.ember-try/
|
|
||||||
/bower.json.ember-try
|
|
||||||
/package.json.ember-try
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
module.exports = {
|
|
||||||
root: true,
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 2017,
|
|
||||||
sourceType: 'module'
|
|
||||||
},
|
|
||||||
globals: {
|
|
||||||
console: true
|
|
||||||
},
|
|
||||||
plugins: [
|
|
||||||
'ember'
|
|
||||||
],
|
|
||||||
extends: [
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:ember/recommended'
|
|
||||||
],
|
|
||||||
env: {
|
|
||||||
browser: true
|
|
||||||
},
|
|
||||||
rules: {
|
|
||||||
'ember/avoid-leaking-state-in-ember-objects': 'warn',
|
|
||||||
'no-console': 'off'
|
|
||||||
},
|
|
||||||
overrides: [
|
|
||||||
// node files
|
|
||||||
{
|
|
||||||
files: [
|
|
||||||
'.eslintrc.js',
|
|
||||||
'.template-lintrc.js',
|
|
||||||
'ember-cli-build.js',
|
|
||||||
'testem.js',
|
|
||||||
'blueprints/*/index.js',
|
|
||||||
'config/**/*.js',
|
|
||||||
'lib/*/index.js',
|
|
||||||
'server/**/*.js'
|
|
||||||
],
|
|
||||||
parserOptions: {
|
|
||||||
sourceType: 'script',
|
|
||||||
ecmaVersion: 2015
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
browser: false,
|
|
||||||
node: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
};
|
|
||||||
+7
-16
@@ -1,26 +1,17 @@
|
|||||||
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
# See https://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
# compiled output
|
# compiled output
|
||||||
/dist/
|
/dist
|
||||||
/tmp/
|
/tmp
|
||||||
|
|
||||||
# dependencies
|
# dependencies
|
||||||
/bower_components/
|
/node_modules
|
||||||
/node_modules/
|
/bower_components
|
||||||
|
|
||||||
# misc
|
# misc
|
||||||
/.env*
|
|
||||||
/.pnp*
|
|
||||||
/.sass-cache
|
/.sass-cache
|
||||||
/connect.lock
|
/connect.lock
|
||||||
/coverage/
|
/coverage/*
|
||||||
/libpeerconnection.log
|
/libpeerconnection.log
|
||||||
/npm-debug.log*
|
npm-debug.log*
|
||||||
/testem.log
|
testem.log
|
||||||
/yarn-error.log
|
|
||||||
.tm_properties
|
|
||||||
|
|
||||||
# ember-try
|
|
||||||
/.node_modules.ember-try/
|
|
||||||
/bower.json.ember-try
|
|
||||||
/package.json.ember-try
|
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
{
|
||||||
|
"predef": [
|
||||||
|
"document",
|
||||||
|
"window",
|
||||||
|
"-Promise"
|
||||||
|
],
|
||||||
|
"browser": true,
|
||||||
|
"boss": true,
|
||||||
|
"curly": true,
|
||||||
|
"debug": false,
|
||||||
|
"devel": true,
|
||||||
|
"eqeqeq": true,
|
||||||
|
"evil": true,
|
||||||
|
"forin": false,
|
||||||
|
"immed": false,
|
||||||
|
"laxbreak": false,
|
||||||
|
"newcap": true,
|
||||||
|
"noarg": true,
|
||||||
|
"noempty": false,
|
||||||
|
"nonew": false,
|
||||||
|
"nomen": false,
|
||||||
|
"onevar": false,
|
||||||
|
"plusplus": false,
|
||||||
|
"regexp": false,
|
||||||
|
"undef": true,
|
||||||
|
"sub": true,
|
||||||
|
"strict": false,
|
||||||
|
"white": false,
|
||||||
|
"eqnull": true,
|
||||||
|
"esversion": 6,
|
||||||
|
"unused": true
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
extends: 'recommended',
|
|
||||||
|
|
||||||
rules: {
|
|
||||||
'simple-unless': false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
+10
-17
@@ -1,32 +1,25 @@
|
|||||||
---
|
---
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "10"
|
- "6"
|
||||||
|
|
||||||
sudo: false
|
sudo: false
|
||||||
dist: xenial
|
|
||||||
|
|
||||||
notifications:
|
|
||||||
email:
|
|
||||||
on_success: never
|
|
||||||
on_failure: always
|
|
||||||
|
|
||||||
addons:
|
|
||||||
chrome: stable
|
|
||||||
|
|
||||||
cache:
|
cache:
|
||||||
directories:
|
directories:
|
||||||
- $HOME/.npm
|
- $HOME/.npm
|
||||||
|
- $HOME/.cache # includes bowers cache
|
||||||
env:
|
|
||||||
global:
|
|
||||||
# See https://git.io/vdao3 for details.
|
|
||||||
- JOBS=1
|
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- npm config set spin false
|
- npm config set spin false
|
||||||
|
- npm install -g bower
|
||||||
|
- bower --version
|
||||||
|
- npm install phantomjs-prebuilt
|
||||||
|
- node_modules/phantomjs-prebuilt/bin/phantomjs --version
|
||||||
|
|
||||||
|
install:
|
||||||
|
- npm install
|
||||||
|
- bower install
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- npm run lint:hbs
|
|
||||||
- npm run lint:js
|
|
||||||
- npm test
|
- npm test
|
||||||
|
|||||||
@@ -10,24 +10,22 @@ A short introduction of this app could easily go here.
|
|||||||
You will need the following things properly installed on your computer.
|
You will need the following things properly installed on your computer.
|
||||||
|
|
||||||
* [Git](https://git-scm.com/)
|
* [Git](https://git-scm.com/)
|
||||||
* [Node.js](https://nodejs.org/) (with npm)
|
* [Node.js](https://nodejs.org/) (with NPM)
|
||||||
|
* [Bower](https://bower.io/)
|
||||||
* [Ember CLI](https://ember-cli.com/)
|
* [Ember CLI](https://ember-cli.com/)
|
||||||
* [Google Chrome](https://google.com/chrome/)
|
* [PhantomJS](http://phantomjs.org/)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
* `git clone git@github.com:67P/kredits-web.git` this repository
|
* `git clone <repository-url>` this repository
|
||||||
* `cd kredits-web`
|
* `cd kredits-web`
|
||||||
* `npm install`
|
* `npm install`
|
||||||
|
* `bower install`
|
||||||
|
|
||||||
## Running / Development
|
## Running / Development
|
||||||
|
|
||||||
|
* `ember serve`
|
||||||
* `ember serve` - by default kredits-web connects to the Ethreum Kovan network
|
|
||||||
* Visit your app at [http://localhost:4200](http://localhost:4200).
|
* Visit your app at [http://localhost:4200](http://localhost:4200).
|
||||||
* Visit your tests at [http://localhost:4200/tests](http://localhost:4200/tests).
|
|
||||||
|
|
||||||
See [working with locally deployed contracts](https://github.com/67P/kredits-web#working-with-locally-deployed-contracts) for details on how to develop with locally deployed contracts.
|
|
||||||
|
|
||||||
### Code Generators
|
### Code Generators
|
||||||
|
|
||||||
@@ -38,12 +36,6 @@ Make use of the many generators for code, try `ember help generate` for more det
|
|||||||
* `ember test`
|
* `ember test`
|
||||||
* `ember test --server`
|
* `ember test --server`
|
||||||
|
|
||||||
### Linting
|
|
||||||
|
|
||||||
* `npm run lint:hbs`
|
|
||||||
* `npm run lint:js`
|
|
||||||
* `npm run lint:js -- --fix`
|
|
||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
* `ember build` (development)
|
* `ember build` (development)
|
||||||
@@ -51,66 +43,35 @@ Make use of the many generators for code, try `ember help generate` for more det
|
|||||||
|
|
||||||
### Deploying
|
### Deploying
|
||||||
|
|
||||||
_(You need collaborator permissions on the 5apps Deploy project.)_
|
Specify what it takes to deploy your app.
|
||||||
|
|
||||||
`npm run deploy`
|
|
||||||
|
|
||||||
## Working with locally deployed contracts
|
## Working with locally deployed contracts
|
||||||
|
|
||||||
The smart contracts and their JavaScript wrapper library are developed in the
|
For development you might want to run your own development chain with your own development contracts.
|
||||||
[kredits-contracts](https://github.com/67P/kredits-contracts) repo/package.
|
The kredits-contracts helper scripts are available in kredits-web. See [kredits-contracts](https://github.com/67P/kredits-contracts) for more information.
|
||||||
|
|
||||||
You can run `kredits-web` on your machine, against a local, simulated Ethereum
|
Start your parity node with a KreditsChain:
|
||||||
network, provided e.g. by [ganache](http://truffleframework.com/ganache/).
|
|
||||||
|
npm run kredits-parity
|
||||||
|
|
||||||
[kredits-contracts](https://github.com/67P/kredits-contracts) holds all the tools
|
Deploy the contracts to your local chain:
|
||||||
to start and set up such a simulated network, as well as to deploy smart
|
|
||||||
contracts to it.
|
|
||||||
|
|
||||||
These are the basic steps to get up and running:
|
npm run kredits-deploy
|
||||||
|
|
||||||
#### 1. IPFS
|
Run kredits-web with your localy deployed contracts:
|
||||||
|
|
||||||
Run a local IPFS deamon in offline mode.
|
KREDITS_CONTRACT_ADDR=`kredits-inspect -c Kredits -r -w address` \
|
||||||
|
TOKEN_CONTRACT_ADDR=`kredits-inspect -c Token -r -w address` \
|
||||||
|
npm start
|
||||||
|
|
||||||
* Make sure CORS headers are configured. See [IPFS](#ipfs) for more info.
|
You need to have `./node_modules/.bin` in your path for this to work. Otherwise simply copy the contract addresses and set the environment variables manually.
|
||||||
* `ipfs daemon --offline`
|
|
||||||
|
|
||||||
#### 2. kredits-contracts
|
|
||||||
|
|
||||||
Get your local Ethereum development node running. (See [kredits-contracts README](https://github.com/67P/kredits-contracts)
|
|
||||||
for details.
|
|
||||||
|
|
||||||
* Clone [kredits-contracts](https://github.com/67P/kredits-contracts)
|
|
||||||
* `npm install`
|
|
||||||
* `npm run devchain` - runs a local development chain
|
|
||||||
* `npm run bootstrap` - bootstrap runs deploys all the contracts
|
|
||||||
* `npm link` - make the `kredits-contracts` module linkable as `kredits-contracts` on your machine (currently broken :( )
|
|
||||||
|
|
||||||
#### 3. kredits-web
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
* `KREDITS_KERNEL_ADDRESS=<0xYOURADDRESS> npm run start:local` - find your address with the `npm run dao:address` command in the kredits-contracts repo.
|
|
||||||
|
|
||||||
#### IPFS
|
|
||||||
|
|
||||||
Install IPFS with your favorite package manager and run
|
|
||||||
|
|
||||||
ipfs init (on initial installation)
|
|
||||||
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"]'
|
|
||||||
|
|
||||||
## Further Reading / Useful Links
|
## Further Reading / Useful Links
|
||||||
|
|
||||||
* [ember.js](https://emberjs.com/)
|
* [ember.js](http://emberjs.com/)
|
||||||
* [ember-cli](https://ember-cli.com/)
|
* [ember-cli](https://ember-cli.com/)
|
||||||
* Development Browser Extensions
|
* Development Browser Extensions
|
||||||
* [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
|
* [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
|
||||||
|
|||||||
+6
-2
@@ -1,9 +1,13 @@
|
|||||||
import Application from '@ember/application';
|
import Ember from 'ember';
|
||||||
import Resolver from './resolver';
|
import Resolver from './resolver';
|
||||||
import loadInitializers from 'ember-load-initializers';
|
import loadInitializers from 'ember-load-initializers';
|
||||||
import config from './config/environment';
|
import config from './config/environment';
|
||||||
|
|
||||||
const App = Application.extend({
|
let App;
|
||||||
|
|
||||||
|
Ember.MODEL_FACTORY_INJECTIONS = true;
|
||||||
|
|
||||||
|
App = Ember.Application.extend({
|
||||||
modulePrefix: config.modulePrefix,
|
modulePrefix: config.modulePrefix,
|
||||||
podModulePrefix: config.podModulePrefix,
|
podModulePrefix: config.podModulePrefix,
|
||||||
Resolver
|
Resolver
|
||||||
|
|||||||
@@ -1,70 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
import { computed } from '@ember/object';
|
|
||||||
import { and, notEmpty } from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
|
|
||||||
attributes: null,
|
|
||||||
contributors: Object.freeze([]),
|
|
||||||
|
|
||||||
isValidContributor: notEmpty('contributorId'),
|
|
||||||
isValidKind: notEmpty('kind'),
|
|
||||||
isValidAmount: computed('amount', function() {
|
|
||||||
return parseInt(this.amount, 10) > 0;
|
|
||||||
}),
|
|
||||||
isValidDescription: notEmpty('description'),
|
|
||||||
isValidUrl: notEmpty('url'),
|
|
||||||
isValid: and('isValidContributor',
|
|
||||||
'isValidKind',
|
|
||||||
'isValidAmount',
|
|
||||||
'isValidDescription'),
|
|
||||||
|
|
||||||
init () {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.set('defaultDate', new Date());
|
|
||||||
|
|
||||||
// Default attributes used by reset
|
|
||||||
this.set('attributes', {
|
|
||||||
contributorId: null,
|
|
||||||
kind: null,
|
|
||||||
date: [new Date()],
|
|
||||||
amount: null,
|
|
||||||
description: null,
|
|
||||||
url: null,
|
|
||||||
});
|
|
||||||
|
|
||||||
this.reset();
|
|
||||||
},
|
|
||||||
|
|
||||||
reset () {
|
|
||||||
this.setProperties(this.attributes);
|
|
||||||
},
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
submit () {
|
|
||||||
if (!this.isValid) {
|
|
||||||
alert('Invalid data. Please review and try again.');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const attributes = this.getProperties(Object.keys(this.attributes));
|
|
||||||
const [ date/* , time */ ] = attributes.date[0].toISOString().split('T');
|
|
||||||
attributes.date = date;
|
|
||||||
|
|
||||||
this.set('inProgress', true);
|
|
||||||
|
|
||||||
this.save(attributes)
|
|
||||||
.then((/*contribution*/) => {
|
|
||||||
this.reset();
|
|
||||||
}, err => {
|
|
||||||
console.warn(err);
|
|
||||||
window.alert('Something went wrong. Check the browser console for details.');
|
|
||||||
})
|
|
||||||
.finally(() => this.set('inProgress', false));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
<form {{action "submit" on="submit"}}>
|
|
||||||
<p>
|
|
||||||
<select required onchange={{action (mut contributorId) value="target.value"}}>
|
|
||||||
<option value="" selected disabled hidden>Contributor</option>
|
|
||||||
{{#each contributors as |contributor|}}
|
|
||||||
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.name}}</option>
|
|
||||||
{{/each}}
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<select required onchange={{action (mut kind) value="target.value"}}>
|
|
||||||
<option value="" selected disabled hidden>Kind</option>
|
|
||||||
<option value="community" selected={{eq kind "community"}}>Community</option>
|
|
||||||
<option value="design" selected={{eq kind "design"}}>Design</option>
|
|
||||||
<option value="dev" selected={{eq kind "dev"}}>Development</option>
|
|
||||||
<option value="docs" selected={{eq kind "docs"}}>Documentation</option>
|
|
||||||
<option value="ops" selected={{eq kind "ops"}}>IT Operations</option>
|
|
||||||
<option value="special" selected={{eq kind "special"}}>Special</option>
|
|
||||||
</select>
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{ember-flatpickr
|
|
||||||
allowInput=false
|
|
||||||
altFormat="F j, Y"
|
|
||||||
altInput=true
|
|
||||||
altInputClass="date-alt"
|
|
||||||
date=date
|
|
||||||
dateFormat="Y-m-d"
|
|
||||||
defaultDate=defaultDate
|
|
||||||
maxDate=defaultDate
|
|
||||||
onChange=(action (mut date))
|
|
||||||
}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{input type="text"
|
|
||||||
placeholder="500"
|
|
||||||
value=amount
|
|
||||||
class=(if isValidAmount "valid" "")}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{input type="text"
|
|
||||||
placeholder="Description"
|
|
||||||
value=description
|
|
||||||
class=(if isValidDescription "valid" "")}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{input type="text"
|
|
||||||
placeholder="URL (optional)"
|
|
||||||
value=url
|
|
||||||
class=(if isValidUrl "valid" "")}}
|
|
||||||
</p>
|
|
||||||
<p class="actions">
|
|
||||||
{{input type="submit"
|
|
||||||
disabled=inProgress
|
|
||||||
value=(if inProgress "Processing" "Save")}}
|
|
||||||
</p>
|
|
||||||
</form>
|
|
||||||
|
|
||||||
@@ -1,76 +1,79 @@
|
|||||||
import Component from '@ember/component';
|
import Ember from 'ember';
|
||||||
import { and, notEmpty } from '@ember/object/computed';
|
import Contributor from 'kredits-web/models/contributor';
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import { isPresent } from '@ember/utils';
|
const {
|
||||||
|
Component,
|
||||||
|
isPresent,
|
||||||
|
inject: {
|
||||||
|
service
|
||||||
|
},
|
||||||
|
computed
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
|
||||||
kredits: service(),
|
kredits: service(),
|
||||||
|
|
||||||
attributes: null,
|
newContributor: null,
|
||||||
|
inProgress: false,
|
||||||
|
|
||||||
// TODO: add proper address validation
|
isValidAddress: function() {
|
||||||
isValidAccount: notEmpty('account'),
|
return this.get('kredits.web3')
|
||||||
isValidName: notEmpty('name'),
|
.isAddress(this.get('newContributor.address'));
|
||||||
isValidURL: notEmpty('url'),
|
}.property('kredits.web3', 'newContributor.address'),
|
||||||
isValidGithubUID: notEmpty('github_uid'),
|
|
||||||
isValidGithubUsername: notEmpty('github_username'),
|
isValidName: function() {
|
||||||
isValidGiteaUsername: notEmpty('gitea_username'),
|
return isPresent(this.get('newContributor.name'));
|
||||||
isValidWikiUsername: notEmpty('wiki_username'),
|
}.property('newContributor.name'),
|
||||||
isValid: and(
|
|
||||||
'isValidAccount',
|
isValidURL: function() {
|
||||||
|
return isPresent(this.get('newContributor.url'));
|
||||||
|
}.property('newContributor.url'),
|
||||||
|
|
||||||
|
isValidGithubUID: function() {
|
||||||
|
return isPresent(this.get('newContributor.github_uid'));
|
||||||
|
}.property('newContributor.github_uid'),
|
||||||
|
|
||||||
|
isValidGithubUsername: function() {
|
||||||
|
return isPresent(this.get('newContributor.github_username'));
|
||||||
|
}.property('newContributor.github_username'),
|
||||||
|
|
||||||
|
isValidWikiUsername: function() {
|
||||||
|
return isPresent(this.get('newContributor.wiki_username'));
|
||||||
|
}.property('newContributor.wiki_username'),
|
||||||
|
|
||||||
|
isValid: computed.and(
|
||||||
|
'isValidAddress',
|
||||||
'isValidName',
|
'isValidName',
|
||||||
'isValidGithubUID'
|
'isValidGithubUID'
|
||||||
),
|
),
|
||||||
|
|
||||||
inProgress: false,
|
|
||||||
|
|
||||||
init () {
|
|
||||||
this._super(...arguments);
|
|
||||||
this.setDefaultAttributes();
|
|
||||||
this.reset();
|
|
||||||
},
|
|
||||||
|
|
||||||
setDefaultAttributes () {
|
|
||||||
if (isPresent(this.attributes)) { return; }
|
|
||||||
|
|
||||||
this.set('attributes', {
|
|
||||||
account: null,
|
|
||||||
name: null,
|
|
||||||
kind: 'person',
|
|
||||||
url: null,
|
|
||||||
github_username: null,
|
|
||||||
github_uid: null,
|
|
||||||
gitea_username: null,
|
|
||||||
wiki_username: null
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
reset: function() {
|
reset: function() {
|
||||||
this.setProperties(this.attributes);
|
this.setProperties({
|
||||||
|
newContributor: Contributor.create({ kind: 'person' }),
|
||||||
|
inProgress: false
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
submit () {
|
save() {
|
||||||
if (!this.isValid) {
|
if (!this.get('contractInteractionEnabled')) {
|
||||||
alert('Invalid data. Please review and try again.');
|
alert('Only core team members can add new contributors. Please ask someone to set you up.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const attributes = Object.keys(this.attributes);
|
if (this.get('isValid')) {
|
||||||
const contributor = this.getProperties(attributes);
|
this.set('inProgress', true);
|
||||||
|
|
||||||
this.set('inProgress', true);
|
this.get('kredits').addContributor(this.get('newContributor')).then(contributor => {
|
||||||
|
this.reset();
|
||||||
this.save(contributor).then(() => {
|
this.get('contributors').pushObject(contributor);
|
||||||
this.reset();
|
window.scroll(0,0);
|
||||||
}).catch(err => {
|
});
|
||||||
console.warn(err);
|
} else {
|
||||||
window.alert('Something went wrong. Please check the browser console.');
|
alert('Invalid data. Please review and try again.');
|
||||||
}).finally(() => {
|
}
|
||||||
this.set('inProgress', false);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,50 +1,59 @@
|
|||||||
<form {{action "submit" on="submit"}}>
|
<form {{action "save" on="submit"}}>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-account">Ethereum account</label>
|
{{input type="checkbox" name="is-core" id="is-core" checked=newContributor.isCore}}
|
||||||
{{input name="account" id="c-account"
|
<label for="is-core" class="checkbox">
|
||||||
type="text" value=account
|
Core team member (can add contributors)
|
||||||
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
|
</label>
|
||||||
class=(if isValidAccount "valid" "")}}
|
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-kind">Kind</label>
|
{{input name="address"
|
||||||
<select required onchange={{action (mut kind) value="target.value"}} id="c-kind">
|
type="text"
|
||||||
<option value="person" selected={{eq kind "person"}}>Person</option>
|
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
|
||||||
<option value="organization" selected={{eq kind "organization"}}>Organization</option>
|
value=newContributor.address
|
||||||
|
class=(if isValidAddress 'valid' '')}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<select required onchange={{action (mut newContributor.kind) value="target.value"}}>
|
||||||
|
<option value="person" selected={{eq newContributor.kind "person"}}>Person</option>
|
||||||
|
<option value="organization" selected={{eq newContributor.kind "organization"}}>Organization</option>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-name">Name</label>
|
{{input name="name"
|
||||||
{{input name="name" type="text" value=name placeholder="Zero Cool"
|
type="text"
|
||||||
class=(if isValidName "valid" "") id="c-name"}}
|
placeholder="Name"
|
||||||
|
value=newContributor.name
|
||||||
|
class=(if isValidName 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-url">URL</label>
|
{{input name="url"
|
||||||
{{input name="url" type="text" value=url placeholder="http://zerocool.bit"
|
type="text"
|
||||||
class=(if isValidURL "valid" "") id="c-url"}}
|
placeholder="URL"
|
||||||
|
value=newContributor.url
|
||||||
|
class=(if isValidURL 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-github-uid">GitHub UID</label>
|
{{input name="github_uid"
|
||||||
{{input name="github_uid" type="text" value=github_uid placeholder="2342"
|
type="text"
|
||||||
class=(if isValidGithubUID "valid" "") id="c-github-uid"}}
|
placeholder="GitHub UID (123)"
|
||||||
|
value=newContributor.github_uid
|
||||||
|
class=(if isValidGithubUID 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-github-username">GitHub username</label>
|
{{input name="github_username"
|
||||||
{{input name="github_username" type="text" value=github_username placeholder="zerocool"
|
type="text"
|
||||||
class=(if isValidGithubUsername "valid" "") id="c-github-username"}}
|
placeholder="GitHub username"
|
||||||
|
value=newContributor.github_username
|
||||||
|
class=(if isValidGithubUsername 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<label for="c-gitea-username">Gitea username</label>
|
{{input name="wiki_username"
|
||||||
{{input name="gitea_username" type="text" value=gitea_username placeholder="zerocool"
|
type="text"
|
||||||
class=(if isValidGiteaUsername "valid" "") id="c-gitea-username"}}
|
placeholder="Wiki Username"
|
||||||
</p>
|
value=newContributor.wiki_username
|
||||||
<p>
|
class=(if isValidWikiUsername 'valid' '')}}
|
||||||
<label for="c-wiki-username">Wiki username</label>
|
|
||||||
{{input name="wiki_username" type="text" value=wiki_username placeholder="ZeroCool"
|
|
||||||
class=(if isValidWikiUsername "valid" "") id="c-wiki-username"}}
|
|
||||||
</p>
|
</p>
|
||||||
<p class="actions">
|
<p class="actions">
|
||||||
{{input type="submit" disabled=inProgress
|
{{input type="submit" value=(if inProgress 'Processing' 'Save') disabled=inProgress}}
|
||||||
value=(if inProgress "Processing" "Save")}}
|
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -1,63 +1,65 @@
|
|||||||
import Component from '@ember/component';
|
import Ember from 'ember';
|
||||||
import { computed } from '@ember/object';
|
|
||||||
import { and, notEmpty } from '@ember/object/computed';
|
const {
|
||||||
|
Component,
|
||||||
|
isPresent,
|
||||||
|
inject: {
|
||||||
|
service
|
||||||
|
},
|
||||||
|
computed
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
export default Component.extend({
|
export default Component.extend({
|
||||||
|
|
||||||
attributes: null,
|
kredits: service(),
|
||||||
contributors: Object.freeze([]),
|
|
||||||
|
|
||||||
isValidContributor: notEmpty('contributorId'),
|
proposal: null,
|
||||||
isValidAmount: computed('amount', function() {
|
contributors: null,
|
||||||
return parseInt(this.amount, 10) > 0;
|
inProgress: false,
|
||||||
|
|
||||||
|
isValidRecipient: computed('proposal.recipientAddress', function() {
|
||||||
|
return this.get('kredits.web3').isAddress(this.get('proposal.recipientAddress'));
|
||||||
}),
|
}),
|
||||||
isValidDescription: notEmpty('description'),
|
|
||||||
isValidUrl: notEmpty('url'),
|
|
||||||
isValid: and('isValidContributor',
|
|
||||||
'isValidAmount',
|
|
||||||
'isValidDescription'),
|
|
||||||
|
|
||||||
init () {
|
isValidAmount: computed('proposal.amount', function() {
|
||||||
this._super(...arguments);
|
return parseInt(this.get('proposal.amount'), 10) > 0;
|
||||||
|
}),
|
||||||
|
|
||||||
// Default attributes used by reset
|
isValidUrl: computed('proposal.url', function() {
|
||||||
this.set('attributes', {
|
return isPresent(this.get('proposal.url'));
|
||||||
contributorId: null,
|
}),
|
||||||
kind: 'community',
|
|
||||||
amount: null,
|
|
||||||
description: null,
|
|
||||||
url: null,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
didInsertElement() {
|
isValidDescription: computed('proposal.description', function() {
|
||||||
this._super(...arguments);
|
return isPresent(this.get('proposal.description'));
|
||||||
this.reset();
|
}),
|
||||||
},
|
|
||||||
|
|
||||||
reset: function() {
|
isValid: computed.and('isValidRecipient',
|
||||||
this.setProperties(this.attributes);
|
'isValidAmount',
|
||||||
},
|
'isValidDescription'),
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
submit() {
|
save() {
|
||||||
if (!this.isValid) {
|
if (! this.get('isValid')) {
|
||||||
alert('Invalid data. Please review and try again.');
|
alert('Invalid data. Please review and try again.');
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
this.set('inProgress', true);
|
||||||
|
let proposal = this.get('proposal');
|
||||||
|
|
||||||
let attributes = Object.keys(this.attributes);
|
// Set the recipient's IPFS profile hash so it can be used in the
|
||||||
let proposal = this.getProperties(attributes);
|
// contribution object (which is to be stored in IPFS as well)
|
||||||
let saved = this.save(proposal);
|
let contributor = this.get('contributors').findBy('address', proposal.get('recipientAddress'));
|
||||||
|
proposal.set('recipientProfile', contributor.get('ipfsHash'));
|
||||||
|
|
||||||
// The promise handles inProgress
|
this.get('kredits').addProposal(proposal)
|
||||||
this.set('inProgress', saved);
|
.then(() => {
|
||||||
|
this.attrs.onSave();
|
||||||
saved.then(() => {
|
}).catch((error) => {
|
||||||
this.reset();
|
Ember.Logger.error('[add-proposal] error creating the proposal', error);
|
||||||
window.scroll(0,0);
|
alert('Something went wrong.');
|
||||||
window.alert('Proposal added.');
|
}).finally(() => {
|
||||||
});
|
this.set('inProgress', false);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,44 +1,42 @@
|
|||||||
<form {{action "submit" on="submit"}}>
|
<form {{action "save" on="submit"}}>
|
||||||
<p>
|
<p>
|
||||||
<select required onchange={{action (mut contributorId) value="target.value"}}>
|
<select required onchange={{action (mut proposal.recipientAddress) value="target.value"}}>
|
||||||
<option value="" selected disabled hidden>Contributor</option>
|
<option value="" selected disabled hidden>Contributor</option>
|
||||||
{{#each contributors as |contributor|}}
|
{{#each contributors as |contributor|}}
|
||||||
<option value={{contributor.id}} selected={{eq contributorId contributor.id}}>{{contributor.github_username}}</option>
|
<option value={{contributor.address}} selected={{eq proposal.recipientAddress contributor.address}}>{{contributor.github_username}}</option>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<select required onchange={{action (mut kind) value="target.value"}}>
|
<select required onchange={{action (mut proposal.kind) value="target.value"}}>
|
||||||
<option value="community" selected={{eq kind "community"}}>Community</option>
|
<option value="community" selected={{eq proposal.kind "community"}}>Community</option>
|
||||||
<option value="design" selected={{eq kind "design"}}>Design</option>
|
<option value="design" selected={{eq proposal.kind "design"}}>Design</option>
|
||||||
<option value="dev" selected={{eq kind "dev"}}>Development</option>
|
<option value="dev" selected={{eq proposal.kind "dev"}}>Development</option>
|
||||||
<option value="docs" selected={{eq kind "docs"}}>Documentation</option>
|
<option value="docs" selected={{eq proposal.kind "docs"}}>Documentation</option>
|
||||||
<option value="ops" selected={{eq kind "ops"}}>IT Operations</option>
|
<option value="ops" selected={{eq proposal.kind "ops"}}>IT Operations</option>
|
||||||
</select>
|
</select>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{{input type="text"
|
{{input type="text"
|
||||||
placeholder="100"
|
placeholder="100"
|
||||||
value=amount
|
value=proposal.amount
|
||||||
class=(if isValidAmount "valid" "")}}
|
class=(if isValidAmount 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{{input type="text"
|
{{input type="text"
|
||||||
placeholder="Description"
|
placeholder="Description"
|
||||||
value=description
|
value=proposal.description
|
||||||
class=(if isValidDescription "valid" "")}}
|
class=(if isValidDescription 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{{input type="text"
|
{{input type="text"
|
||||||
placeholder="URL (optional)"
|
placeholder="URL (optional)"
|
||||||
value=url
|
value=proposal.url
|
||||||
class=(if isValidUrl "valid" "")}}
|
class=(if isValidUrl 'valid' '')}}
|
||||||
</p>
|
</p>
|
||||||
<p class="actions">
|
<p class="actions">
|
||||||
{{input type="submit"
|
{{input type="submit" value=(if inProgress 'Processing' 'Save') disabled=inProgress}}
|
||||||
disabled=(is-pending inProgress)
|
{{#link-to 'index'}}Back{{/link-to}}
|
||||||
value=(if (is-pending inProgress) "Processing" "Save")}}
|
|
||||||
{{#link-to "index"}}Back{{/link-to}}
|
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|||||||
@@ -1,64 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
import { computed } from '@ember/object';
|
|
||||||
|
|
||||||
let categoryColors = {
|
|
||||||
community: "#fb6868",
|
|
||||||
design: "#fbe468",
|
|
||||||
dev: "#e068fb",
|
|
||||||
docs: "#97fb68",
|
|
||||||
ops: "#8f68fb",
|
|
||||||
}
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
|
|
||||||
contributions: null,
|
|
||||||
chartOptions: Object.freeze({
|
|
||||||
legend: {
|
|
||||||
display: false
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
|
|
||||||
chartData: computed('contributions', function() {
|
|
||||||
let kredits = this.contributions
|
|
||||||
.filterBy('vetoed', false)
|
|
||||||
.map(c => {
|
|
||||||
return { kind: c.kind, amount: c.amount }
|
|
||||||
})
|
|
||||||
.reduce(function (kinds, c) {
|
|
||||||
if (c.kind in kinds) {
|
|
||||||
kinds[c.kind] = kinds[c.kind] + c.amount
|
|
||||||
} else {
|
|
||||||
kinds[c.kind] = c.amount;
|
|
||||||
}
|
|
||||||
return kinds;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
return {
|
|
||||||
datasets: [{
|
|
||||||
data: [
|
|
||||||
kredits['community'],
|
|
||||||
kredits['design'],
|
|
||||||
kredits['dev'],
|
|
||||||
kredits['ops'],
|
|
||||||
kredits['docs'],
|
|
||||||
],
|
|
||||||
borderColor: [
|
|
||||||
categoryColors.community,
|
|
||||||
categoryColors.design,
|
|
||||||
categoryColors.dev,
|
|
||||||
categoryColors.ops,
|
|
||||||
categoryColors.docs,
|
|
||||||
],
|
|
||||||
borderWidth: 1
|
|
||||||
}],
|
|
||||||
labels: [
|
|
||||||
'Community',
|
|
||||||
'Design',
|
|
||||||
'Development',
|
|
||||||
'Operations & Infrastructure',
|
|
||||||
'Documentation'
|
|
||||||
],
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
<div class="chart">
|
|
||||||
{{ember-chart type="doughnut"
|
|
||||||
data=chartData
|
|
||||||
options=chartOptions
|
|
||||||
width=200
|
|
||||||
height=200}}
|
|
||||||
</div>
|
|
||||||
@@ -1,20 +1,16 @@
|
|||||||
import Component from '@ember/component';
|
import Ember from 'ember';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Ember.Component.extend({
|
||||||
|
|
||||||
tagName: 'ul',
|
tagName: 'ul',
|
||||||
classNames: ['contribution-list'],
|
classNames: ['contribution-list'],
|
||||||
|
|
||||||
actions: {
|
contributionsWithContributors: function() {
|
||||||
|
return this.get('contributions').map((c) => {
|
||||||
veto (contributionId) {
|
c.set('contributor', this.get('contributors')
|
||||||
if (this.contractInteractionEnabled) {
|
.findBy('address', c.get('recipientAddress')));
|
||||||
this.vetoContribution(contributionId);
|
return c;
|
||||||
} else {
|
});
|
||||||
window.alert('Only members can veto contributions. Please ask someone to set you up.');
|
}.property('contributions.@each')
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,25 +1,7 @@
|
|||||||
{{#each contributions as |contribution|}}
|
{{#each contributionsWithContributors as |contribution|}}
|
||||||
<li data-contribution-id={{contribution.id}} class="{{contribution-status contribution}} {{if contribution.vetoed "vetoed"}}">
|
<li title="({{contribution.kind}}) {{contribution.description}}">
|
||||||
<p class="meta">
|
<span class="category {{contribution.kind}}">♥</span>
|
||||||
<span class="recipient">{{user-avatar contributor=contribution.contributor}}</span>
|
<span class="amount">{{contribution.amount}}</span><span class="symbol">₭S</span>
|
||||||
<span class="category {{contribution.kind}}">({{contribution.kind}})</span>
|
for <span class="recipient">{{contribution.contributor.name}}</span>
|
||||||
<span class="title">
|
|
||||||
{{#if contribution.url}}
|
|
||||||
<a href={{contribution.url}} target="_blank" rel="noopener">{{contribution.description}}</a>
|
|
||||||
{{else}}
|
|
||||||
{{contribution.description}}
|
|
||||||
{{/if}}
|
|
||||||
</span>
|
|
||||||
</p>
|
|
||||||
<p class="kredits-amount">
|
|
||||||
<span class="amount">{{contribution.amount}}</span><span class="symbol">₭S</span>
|
|
||||||
</p>
|
|
||||||
{{#unless contribution.vetoed}}
|
|
||||||
{{#unless (is-confirmed-contribution contribution)}}
|
|
||||||
<p class="voting">
|
|
||||||
<button {{action "veto" contribution.id}} class="small danger">veto</button>
|
|
||||||
</p>
|
|
||||||
{{/unless}}
|
|
||||||
{{/unless}}
|
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Component from '@ember/component';
|
import Ember from 'ember';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Ember.Component.extend({
|
||||||
|
|
||||||
tagName: 'table',
|
tagName: 'table',
|
||||||
classNames: 'contributor-list',
|
classNames: 'contributor-list',
|
||||||
@@ -9,10 +9,10 @@ export default Component.extend({
|
|||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
toggleContributorInfo(contributor) {
|
toggleContributorInfo(contributor) {
|
||||||
if (contributor.showMetadata) {
|
if (contributor.get('showMetadata')) {
|
||||||
contributor.set('showMetadata', false);
|
contributor.set('showMetadata', false);
|
||||||
} else {
|
} else {
|
||||||
this.contributorList.setEach('showMetadata', false);
|
this.get('contributors').setEach('showMetadata', false);
|
||||||
contributor.set('showMetadata', true);
|
contributor.set('showMetadata', true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,38 +1,23 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{{#each contributorList as |c|}}
|
{{#each contributors as |contributor|}}
|
||||||
<tr role="button" class={{if (is-current-user c.contributor) "current-user"}} {{action "toggleContributorInfo" c}}>
|
<tr class="{{if contributor.isCurrentUser 'current-user'}}" {{action "toggleContributorInfo" contributor}}>
|
||||||
<td class="person">
|
<td class="person">
|
||||||
{{user-avatar contributor=c.contributor}} {{c.contributor.name}}
|
<img class="avatar" src={{contributor.avatarURL}}>
|
||||||
|
{{contributor.name}}
|
||||||
</td>
|
</td>
|
||||||
<td class="kredits">
|
<td class="kredits">
|
||||||
<span class="amount">
|
<span class="amount">{{contributor.kredits}}</span>
|
||||||
{{#if showUnconfirmedKredits}}
|
|
||||||
{{c.amountTotal}}
|
|
||||||
{{else}}
|
|
||||||
{{c.amountConfirmed}}
|
|
||||||
{{/if}}
|
|
||||||
</span>
|
|
||||||
<span class="symbol">₭S</span>
|
<span class="symbol">₭S</span>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<tr class="metadata {{if (is-current-user c.contributor) "current-user"}} {{if c.showMetadata "visible"}}">
|
<tr class="metadata {{if contributor.isCurrentUser 'current-user'}} {{if contributor.showMetadata 'visible'}}">
|
||||||
<td colspan="2">
|
<td colspan="2">
|
||||||
<ul>
|
<ul>
|
||||||
<li>
|
<li><a href="https://testnet.etherscan.io/address/{{contributor.address}}">Inspect Ethereum transactions</a></li>
|
||||||
<a href="https://rinkeby.etherscan.io/address/{{c.contributor.account}}" target="_blank" rel="noopener">Inspect Ethereum transactions</a>
|
{{#if contributor.ipfsHash}}
|
||||||
</li>
|
<li><a href="https://ipfs.io/ipfs/{{contributor.ipfsHash}}">Inspect IPFS profile</a></li>
|
||||||
{{#if c.contributor.ipfsHash}}
|
|
||||||
<li>
|
|
||||||
<a href="https://ipfs.io/ipfs/{{c.contributor.ipfsHash}}" target="_blank" rel="noopener">Inspect IPFS profile</a>
|
|
||||||
</li>
|
|
||||||
{{/if}}
|
{{/if}}
|
||||||
<li>
|
|
||||||
{{link-to "Edit profile" "contributors.edit" c.contributor.id}}
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
{{#if c.showMetadata}}
|
|
||||||
<pre>{{c.contributor.ipfsData}}</pre>
|
|
||||||
{{/if}}
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Component from '@ember/component';
|
import Ember from 'ember';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Ember.Component.extend({
|
||||||
|
|
||||||
classNames: ['loading-spinner']
|
classNames: ['loading-spinner']
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
version="1.1" x="0px" y="0px" viewBox="0 0 132 100"
|
version="1.1" x="0px" y="0px" viewBox="0 0 132 100"
|
||||||
enable-background="new 0 0 100 100" xml:space="preserve">
|
enable-background="new 0 0 100 100" xml:space="preserve">
|
||||||
<path id="path-comet"
|
<path id="path-comet"
|
||||||
d="M79.062,24.173L79.062,24.173l-0.021-0.011c-0.068-0.03-0.137-0.062-0.204-0.093L42.392,7.337
|
d="M79.062,24.173L79.062,24.173l-0.021-0.011c-0.068-0.03-0.137-0.062-0.204-0.093L42.392,7.337
|
||||||
c0,0,3.065,14.104,4.458,18.019l0,0c0,0-41.754-12.481-46.85-13.67c1.67,6.52,30.607,62.492,30.607,62.492
|
c0,0,3.065,14.104,4.458,18.019l0,0c0,0-41.754-12.481-46.85-13.67c1.67,6.52,30.607,62.492,30.607,62.492
|
||||||
c5.848,11.873,19.394,18.485,33.522,18.485c19.811,0,35.87-16.059,35.87-35.869C100,42.313,91.418,29.837,79.062,24.173z">
|
c5.848,11.873,19.394,18.485,33.522,18.485c19.811,0,35.87-16.059,35.87-35.869C100,42.313,91.418,29.837,79.062,24.173z">
|
||||||
@@ -10,5 +10,5 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Loading data...
|
Loading data from Ethereum...
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Component from '@ember/component';
|
import Ember from 'ember';
|
||||||
|
|
||||||
export default Component.extend({
|
export default Ember.Component.extend({
|
||||||
|
|
||||||
tagName: 'ul',
|
tagName: 'ul',
|
||||||
classNames: ['proposal-list'],
|
classNames: ['proposal-list'],
|
||||||
@@ -8,8 +8,8 @@ export default Component.extend({
|
|||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
confirm(proposalId) {
|
confirm(proposalId) {
|
||||||
if (this.contractInteractionEnabled) {
|
if (this.get('contractInteractionEnabled')) {
|
||||||
this.confirmProposal(proposalId);
|
this.sendAction('confirmAction', proposalId);
|
||||||
} else {
|
} else {
|
||||||
window.alert('Only members can vote on proposals. Please ask someone to set you up.');
|
window.alert('Only members can vote on proposals. Please ask someone to set you up.');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,20 +1,10 @@
|
|||||||
{{#each proposals as |proposal|}}
|
{{#each proposals as |proposal|}}
|
||||||
<li data-proposal-id={{proposal.id}} class={{if proposal.isExecuted "confirmed" "unconfirmed"}}>
|
<li data-proposal-id={{proposal.id}} title="({{proposal.kind}}) {{proposal.description}}">
|
||||||
<p class="meta">
|
<span class="category {{proposal.kind}}">♥</span>
|
||||||
<span class="category {{proposal.kind}}">♥ ({{proposal.kind}})</span>
|
<span class="amount">{{proposal.amount}}</span><span class="symbol">₭S</span>
|
||||||
<span class="recipient">{{proposal.contributor.name}}:</span>
|
for <span class="recipient">{{proposal.recipientName}}</span>
|
||||||
</p>
|
<span class="votes">({{proposal.votesCount}}/{{proposal.votesNeeded}} votes)</span>
|
||||||
<p class="kredits-amount">
|
|
||||||
<span class="amount">{{proposal.amount}}</span><span class="symbol">₭S</span>
|
{{#unless proposal.executed}}<button {{action "confirm" proposal.id}}>+1</button>{{/unless}}
|
||||||
</p>
|
|
||||||
<p class="description">
|
|
||||||
<span class="description">{{proposal.description}}</span>
|
|
||||||
</p>
|
|
||||||
<p class="voting">
|
|
||||||
{{#unless proposal.isExecuted}}
|
|
||||||
<span class="votes">({{proposal.votesCount}}/{{proposal.votesNeeded}} votes)</span>
|
|
||||||
<button {{action "confirm" proposal.id}}>+1</button>
|
|
||||||
{{/unless}}
|
|
||||||
</p>
|
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|||||||
@@ -1,11 +0,0 @@
|
|||||||
import Component from '@ember/component';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Component.extend({
|
|
||||||
contributor: null,
|
|
||||||
tagName: 'img',
|
|
||||||
classNames: ['avatar'],
|
|
||||||
attributeBindings: ['src', 'title'],
|
|
||||||
src: alias('contributor.avatarURL'),
|
|
||||||
title: alias('contributor.name')
|
|
||||||
});
|
|
||||||
@@ -1,6 +1,4 @@
|
|||||||
import Controller from '@ember/controller';
|
import Ember from 'ember';
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
export default Ember.Controller.extend({
|
||||||
kredits: service(),
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,30 +0,0 @@
|
|||||||
import Controller from '@ember/controller';
|
|
||||||
import { alias, filterBy, sort } from '@ember/object/computed';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
contributors: alias('kredits.contributors'),
|
|
||||||
minedContributors: filterBy('contributors', 'id'),
|
|
||||||
|
|
||||||
contributorsSorting: Object.freeze(['name:asc']),
|
|
||||||
sortedContributors: sort('minedContributors', 'contributorsSorting'),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
save (contribution) {
|
|
||||||
const contributor = this.contributors.findBy('id', contribution.contributorId);
|
|
||||||
contribution.contributorIpfsHash = contributor.ipfsHash;
|
|
||||||
|
|
||||||
return this.kredits.addContribution(contribution)
|
|
||||||
.then(contribution => {
|
|
||||||
this.transitionToRoute('index');
|
|
||||||
return contribution;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import Controller from '@ember/controller';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
save (attributes) {
|
|
||||||
return this.kredits
|
|
||||||
.updateContributor(this.model.id, attributes)
|
|
||||||
.then(() => this.transitionToRoute('index'))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import Controller from '@ember/controller';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
actions: {
|
|
||||||
|
|
||||||
save (contributor) {
|
|
||||||
return this.kredits
|
|
||||||
.addContributor(contributor)
|
|
||||||
.then(() => this.transitionToRoute('index'))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
+133
-28
@@ -1,43 +1,148 @@
|
|||||||
import Controller from '@ember/controller';
|
import Ember from 'ember';
|
||||||
import { computed } from '@ember/object';
|
import Proposal from 'kredits-web/models/proposal';
|
||||||
import { alias, not, sort } from '@ember/object/computed';
|
|
||||||
import { inject as service } from '@ember/service';
|
const {
|
||||||
|
computed,
|
||||||
|
inject: {
|
||||||
|
service
|
||||||
|
}
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
|
export default Ember.Controller.extend({
|
||||||
|
|
||||||
export default Controller.extend({
|
|
||||||
kredits: service(),
|
kredits: service(),
|
||||||
currentBlock: alias('kredits.currentBlock'),
|
|
||||||
|
|
||||||
contributions: alias('kredits.contributions'),
|
contractInteractionEnabled: computed.alias('kredits.web3Provided'),
|
||||||
contributionsConfirmed: alias('kredits.contributionsConfirmed'),
|
|
||||||
contributionsUnconfirmed: alias('kredits.contributionsUnconfirmed'),
|
|
||||||
|
|
||||||
contributionsSorting: Object.freeze(['date:desc', 'time:desc', 'id:desc']),
|
findContributorByAddress(address) {
|
||||||
contributionsUnconfirmedSorted: sort('contributionsUnconfirmed', 'contributionsSorting'),
|
return this.get('model.contributors')
|
||||||
contributionsConfirmedSorted: sort('contributionsConfirmed', 'contributionsSorting'),
|
.findBy('address', address);
|
||||||
|
},
|
||||||
|
|
||||||
kreditsByContributor: alias('kredits.kreditsByContributor'),
|
proposalsOpen: function() {
|
||||||
|
let proposals = this.get('model.proposals')
|
||||||
|
.filterBy('executed', false)
|
||||||
|
.map(p => {
|
||||||
|
p.set('recipientName', this.findContributorByAddress(p.get('recipientAddress')).name);
|
||||||
|
return p;
|
||||||
|
});
|
||||||
|
return proposals;
|
||||||
|
}.property('model.proposals.[]', 'model.proposals.@each.executed', 'model.contributors.[]'),
|
||||||
|
|
||||||
kreditsToplistSorting: computed('showUnconfirmedKredits', function(){
|
proposalsClosed: function() {
|
||||||
return this.showUnconfirmedKredits ? ['amountTotal:desc'] : ['amountConfirmed:desc'];
|
let proposals = this.get('model.proposals')
|
||||||
}),
|
.filterBy('executed', true)
|
||||||
kreditsToplist: sort('kreditsByContributor', 'kreditsToplistSorting'),
|
.map(p => {
|
||||||
|
p.set('recipientName', this.findContributorByAddress(p.get('recipientAddress')).name);
|
||||||
|
return p;
|
||||||
|
});
|
||||||
|
return proposals;
|
||||||
|
}.property('model.proposals.[]', 'model.proposals.@each.executed', 'model.contributors.[]'),
|
||||||
|
|
||||||
|
proposalsSorting: ['id:desc'],
|
||||||
|
proposalsClosedSorted: Ember.computed.sort('proposalsClosed', 'proposalsSorting'),
|
||||||
|
proposalsOpenSorted: Ember.computed.sort('proposalsOpen', 'proposalsSorting'),
|
||||||
|
|
||||||
|
contributorsWithKredits: function() {
|
||||||
|
return this.get('model.contributors').filter(c => {
|
||||||
|
return c.get('kredits') !== 0;
|
||||||
|
});
|
||||||
|
}.property('model.contributors.@each.kredits'),
|
||||||
|
|
||||||
|
contributorsSorting: ['kredits:desc'],
|
||||||
|
contributorsSorted: Ember.computed.sort('contributorsWithKredits', 'contributorsSorting'),
|
||||||
|
|
||||||
|
watchContractEvents: function() {
|
||||||
|
let events = this.get('kredits.kreditsContract')
|
||||||
|
.allEvents(/* [additionalFilterObject], */);
|
||||||
|
|
||||||
|
events.watch((error, data) => {
|
||||||
|
Ember.Logger.debug('[index] Received contract event', data);
|
||||||
|
|
||||||
|
switch (data.event) {
|
||||||
|
case 'ProposalCreated':
|
||||||
|
this._handleProposalCreated(data);
|
||||||
|
break;
|
||||||
|
case 'ProposalExecuted':
|
||||||
|
this._handleProposalExecuted(data);
|
||||||
|
break;
|
||||||
|
case 'ProposalVoted':
|
||||||
|
this._handleProposalVoted(data);
|
||||||
|
break;
|
||||||
|
case 'Transfer':
|
||||||
|
this._handleTransfer(data);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}.on('init'),
|
||||||
|
|
||||||
|
_handleProposalCreated(data) {
|
||||||
|
if (Ember.isPresent(this.get('model.proposals')
|
||||||
|
.findBy('id', data.args.id.toNumber()))) {
|
||||||
|
Ember.Logger.debug('[index] proposal exists, not adding from event');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let proposal = Proposal.create({
|
||||||
|
id: data.args.id.toNumber(),
|
||||||
|
creatorAddress: data.args.creator,
|
||||||
|
recipientAddress: data.args.recipient,
|
||||||
|
recipientName: null,
|
||||||
|
votesCount: 0,
|
||||||
|
votesNeeded: 2,
|
||||||
|
amount: data.args.amount.toNumber(),
|
||||||
|
executed: false,
|
||||||
|
url: data.args.url,
|
||||||
|
ipfsHash: data.args.ipfsHash
|
||||||
|
});
|
||||||
|
|
||||||
|
this.get('model.proposals').pushObject(proposal);
|
||||||
|
},
|
||||||
|
|
||||||
|
_handleProposalExecuted(data) {
|
||||||
|
if (this.get('model.proposals')
|
||||||
|
.findBy('id', data.args.id.toNumber())
|
||||||
|
.get('executed')) {
|
||||||
|
Ember.Logger.debug('[index] proposal already executed, not adding from event');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.get('model.proposals')
|
||||||
|
.findBy('id', data.args.id.toNumber())
|
||||||
|
.setProperties({
|
||||||
|
'executed': true,
|
||||||
|
'votesCount': 2 // TODO use real count
|
||||||
|
});
|
||||||
|
|
||||||
|
this.get('model.contributors')
|
||||||
|
.findBy('address', data.args.recipient)
|
||||||
|
.incrementProperty('kredits', data.args.amount.toNumber());
|
||||||
|
},
|
||||||
|
|
||||||
|
_handleProposalVoted(data) {
|
||||||
|
this.get('model.proposals')
|
||||||
|
.findBy('id', data.args.id.toNumber())
|
||||||
|
.incrementProperty('votesCount', 1);
|
||||||
|
},
|
||||||
|
|
||||||
|
_handleTransfer(data) {
|
||||||
|
this.get('model.contributors')
|
||||||
|
.findBy('address', data.args.from)
|
||||||
|
.incrementProperty('kredits', - data.args.value.toNumber());
|
||||||
|
this.get('model.contributors')
|
||||||
|
.findBy('address', data.args.to)
|
||||||
|
.incrementProperty('kredits', data.args.value.toNumber());
|
||||||
|
},
|
||||||
|
|
||||||
showUnconfirmedKredits: true,
|
|
||||||
hideUnconfirmedKredits: not('showUnconfirmedKredits'),
|
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
vetoContribution (contributionId) {
|
confirmProposal(proposalId) {
|
||||||
this.kredits.veto(contributionId).then(transaction => {
|
this.get('kredits').vote(proposalId).then(transactionId => {
|
||||||
console.debug('[controllers:index] Veto submitted to Ethereum blockhain: '+transaction.hash);
|
window.confirm('Vote submitted to Ethereum blockhain: '+transactionId);
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
confirmProposal (proposalId) {
|
|
||||||
this.kredits.vote(proposalId).then(transaction => {
|
|
||||||
console.debug('[controllers:index] Vote submitted to Ethereum blockhain: '+transaction.hash);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,24 +1,29 @@
|
|||||||
import Controller from '@ember/controller';
|
import Ember from 'ember';
|
||||||
import { alias, filterBy } from '@ember/object/computed';
|
import QueryParams from 'ember-parachute';
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
|
|
||||||
export default Controller.extend({
|
export const queryParams = new QueryParams({
|
||||||
kredits: service(),
|
recipient: {
|
||||||
|
defaultValue: ''
|
||||||
contributors: alias('kredits.contributors'),
|
},
|
||||||
minedContributors: filterBy('contributors', 'id'),
|
amount: {
|
||||||
|
defaultValue: ''
|
||||||
actions: {
|
},
|
||||||
save(proposal) {
|
url: {
|
||||||
// contributorIpfsHash is needed for the proposal ipfs data. I'm not happy to do this here but I think to load all the contributors in addProposal again is a bit too much. I hope we can refactor it later.
|
defaultValue: ''
|
||||||
let contributor = this.contributors.findBy('id', proposal.contributorId);
|
},
|
||||||
proposal.contributorIpfsHash = contributor.get('ipfsHash');
|
ipfsHash: {
|
||||||
|
defaultValue: ''
|
||||||
return this.kredits.addProposal(proposal)
|
|
||||||
.then((proposal) => {
|
|
||||||
this.transitionToRoute('index');
|
|
||||||
return proposal;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export default Ember.Controller.extend(queryParams.Mixin, {
|
||||||
|
|
||||||
|
contributors: null,
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
onSave() {
|
||||||
|
this.transitionToRoute('index');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|||||||
@@ -1,20 +0,0 @@
|
|||||||
import Helper from '@ember/component/helper';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Helper.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
currentBlock: alias('kredits.currentBlock'),
|
|
||||||
|
|
||||||
compute([contribution]) {
|
|
||||||
if (contribution.vetoed) {
|
|
||||||
return 'vetoed';
|
|
||||||
} else if (contribution.confirmedAt > this.currentBlock) {
|
|
||||||
return 'unconfirmed';
|
|
||||||
} else {
|
|
||||||
return 'confirmed'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
import Helper from '@ember/component/helper';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Helper.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
currentBlock: alias('kredits.currentBlock'),
|
|
||||||
|
|
||||||
compute([contribution]) {
|
|
||||||
return !contribution.vetoed &&
|
|
||||||
(contribution.confirmedAt <= this.currentBlock);
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
import Helper from '@ember/component/helper';
|
|
||||||
import { inject as service } from '@ember/service';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
import { isPresent } from '@ember/utils';
|
|
||||||
|
|
||||||
export default Helper.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
currentUser: alias('kredits.currentUser'),
|
|
||||||
|
|
||||||
compute([contributor]) {
|
|
||||||
return isPresent(contributor) && isPresent(this.currentUser) &&
|
|
||||||
contributor.account === this.currentUser.account;
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
+2
-2
@@ -9,8 +9,8 @@
|
|||||||
|
|
||||||
{{content-for "head"}}
|
{{content-for "head"}}
|
||||||
|
|
||||||
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
|
<link rel="stylesheet" href="{{rootURL}}assets/vendor.css">
|
||||||
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/kredits-web.css">
|
<link rel="stylesheet" href="{{rootURL}}assets/kredits-web.css">
|
||||||
|
|
||||||
{{content-for "head-footer"}}
|
{{content-for "head-footer"}}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
/**
|
||||||
|
* This pauses the app's boot process until the window load event is fired.
|
||||||
|
* It allows the user provided Web3 instance (e.g. Metamask, Mist Browser)
|
||||||
|
* to be inserted before we try to use it.
|
||||||
|
*/
|
||||||
|
export default {
|
||||||
|
name: 'defer-loading',
|
||||||
|
initialize: function(application) {
|
||||||
|
// Load event already fired, so web3 should be loaded if available
|
||||||
|
if (window.windowLoadComplete) { return true; }
|
||||||
|
|
||||||
|
// Pause app loading
|
||||||
|
application.deferReadiness();
|
||||||
|
|
||||||
|
window.addEventListener('load', function() {
|
||||||
|
// Continue app loading
|
||||||
|
application.advanceReadiness();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
+42
-17
@@ -1,28 +1,53 @@
|
|||||||
import EmberObject from '@ember/object';
|
import Ember from 'ember';
|
||||||
import bignumber from 'kredits-web/utils/cps/bignumber';
|
|
||||||
|
|
||||||
export default EmberObject.extend({
|
export default Ember.Object.extend({
|
||||||
|
|
||||||
// Contract
|
// blockNumber: null,
|
||||||
id: null,
|
// blockHash: null,
|
||||||
|
// transactionHash: null,
|
||||||
|
recipientAddress: null,
|
||||||
contributorId: null,
|
contributorId: null,
|
||||||
amount: null,
|
|
||||||
confirmedAt: bignumber('confirmedAtBlock', 'toNumber'),
|
|
||||||
vetoed: null,
|
|
||||||
ipfsHash: null,
|
ipfsHash: null,
|
||||||
|
amount: null,
|
||||||
|
|
||||||
creatorAccount: null,
|
contributor: null,
|
||||||
|
contribution: null,
|
||||||
// IPFS
|
|
||||||
kind: null,
|
kind: null,
|
||||||
description: null,
|
description: null,
|
||||||
details: null,
|
|
||||||
url: null,
|
url: null,
|
||||||
ipfsData: '',
|
details: null,
|
||||||
|
|
||||||
init () {
|
/**
|
||||||
this._super(...arguments);
|
* Loads the contribution details from IPFS and sets local instance
|
||||||
this.set('details', {});
|
* properties from it
|
||||||
}
|
*
|
||||||
|
* @method
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
loadDetails(ipfs) {
|
||||||
|
let promise = new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
|
ipfs.getFile(this.get('ipfsHash')).then(content => {
|
||||||
|
let contributionJSON = JSON.parse(content);
|
||||||
|
let contribution = Ember.Object.create(contributionJSON);
|
||||||
|
|
||||||
|
this.setProperties({
|
||||||
|
kind: contribution.get('kind'),
|
||||||
|
description: contribution.get('description'),
|
||||||
|
url: contribution.get('url')
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO load details
|
||||||
|
// let details = profile.get('accounts');
|
||||||
|
|
||||||
|
Ember.Logger.debug('[proposal] loaded contribution details', contributionJSON);
|
||||||
|
resolve();
|
||||||
|
}).catch((err) => {
|
||||||
|
Ember.Logger.error('[proposal] error trying to load contribution details', this.get('ipfsHash'), err);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
+109
-21
@@ -1,31 +1,119 @@
|
|||||||
import { computed } from '@ember/object';
|
import Ember from 'ember';
|
||||||
import EmberObject from '@ember/object';
|
|
||||||
import bignumber from 'kredits-web/utils/cps/bignumber';
|
|
||||||
import kreditsValue from 'kredits-web/utils/cps/kredits';
|
|
||||||
|
|
||||||
export default EmberObject.extend({
|
const {
|
||||||
// Contract
|
isPresent,
|
||||||
id: bignumber('idRaw', 'toString'),
|
} = Ember;
|
||||||
account: null,
|
|
||||||
balance: kreditsValue('balanceRaw'),
|
|
||||||
totalKreditsEarned: bignumber('totalKreditsEarnedRaw', 'toNumber'),
|
|
||||||
contributionsCount: bignumber('contributionsCountRaw', 'toNumber'),
|
|
||||||
isCore: false,
|
|
||||||
ipfsHash: null,
|
|
||||||
|
|
||||||
// IPFS
|
export default Ember.Object.extend({
|
||||||
kind: null,
|
|
||||||
|
address: null,
|
||||||
name: null,
|
name: null,
|
||||||
|
kind: null,
|
||||||
url: null,
|
url: null,
|
||||||
github_username: null,
|
github_username: null,
|
||||||
github_uid: null,
|
github_uid: null,
|
||||||
wiki_username: null,
|
wiki_username: null,
|
||||||
ipfsData: '',
|
ipfsHash: null,
|
||||||
|
kredits: null,
|
||||||
|
isCore: false,
|
||||||
|
isCurrentUser: false,
|
||||||
|
|
||||||
avatarURL: computed('github_uid', function() {
|
avatarURL: function() {
|
||||||
let github_uid = this.github_uid;
|
return `https\:\/\/avatars2.githubusercontent.com/u/${this.get('github_uid')}?v=3&s=128`;
|
||||||
if (github_uid) {
|
}.property('github_uid'),
|
||||||
return `https://avatars2.githubusercontent.com/u/${github_uid}?v=3&s=128`;
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the contributor's profile data from IPFS and sets local instance
|
||||||
|
* properties from it
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
loadProfile(ipfs) {
|
||||||
|
let promise = new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
|
ipfs.getFile(this.get('ipfsHash')).then(content => {
|
||||||
|
let profileJSON = JSON.parse(content);
|
||||||
|
let profile = Ember.Object.create(profileJSON);
|
||||||
|
|
||||||
|
this.setProperties({
|
||||||
|
name: profile.get('name'),
|
||||||
|
kind: profile.get('kind')
|
||||||
|
});
|
||||||
|
|
||||||
|
let accounts = profile.get('accounts');
|
||||||
|
let github = accounts.findBy('site', 'github.com');
|
||||||
|
let wiki = accounts.findBy('site', 'wiki.kosmos.org');
|
||||||
|
|
||||||
|
if (isPresent(github)) {
|
||||||
|
this.setProperties({
|
||||||
|
github_username: github.username,
|
||||||
|
github_uid: github.uid,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (isPresent(wiki)) {
|
||||||
|
this.setProperties({
|
||||||
|
wiki_username: wiki.username
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Ember.Logger.debug('[contributor] loaded contributor profile', profile);
|
||||||
|
resolve();
|
||||||
|
}).catch((err) => {
|
||||||
|
Ember.Logger.error('[contributor] error trying to load contributor profile', this.get('ipfsHash'), err);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JSON-LD object of the contributor, according to
|
||||||
|
* https://github.com/67P/kosmos-schemas/blob/master/schemas/contributor.json
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
toJSON() {
|
||||||
|
let contributor = {
|
||||||
|
"@context": "https://schema.kosmos.org",
|
||||||
|
"@type": "Contributor",
|
||||||
|
"kind": this.get('kind'),
|
||||||
|
"name": this.get('name'),
|
||||||
|
"accounts": []
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Ember.isPresent(this.get('url'))) {
|
||||||
|
contributor["url"] = this.get('url');
|
||||||
}
|
}
|
||||||
}),
|
if (Ember.isPresent(this.get('github_uid'))) {
|
||||||
|
contributor.accounts.push({
|
||||||
|
"site": "github.com",
|
||||||
|
"uid": this.get('github_uid'),
|
||||||
|
"username": this.get('github_username'),
|
||||||
|
"url": `https://github.com/${this.get('github_username')}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (Ember.isPresent(this.get('wiki_username'))) {
|
||||||
|
contributor.accounts.push({
|
||||||
|
"site": "wiki.kosmos.org",
|
||||||
|
"username": this.get('wiki_username'),
|
||||||
|
"url": `https://wiki.kosmos.org/User:${this.get('wiki_username')}`
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return contributor;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the JSON-LD representation of the model as a string
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
serialize() {
|
||||||
|
return JSON.stringify(this.toJSON());
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
+92
-22
@@ -1,32 +1,102 @@
|
|||||||
import EmberObject from '@ember/object';
|
import Ember from 'ember';
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
import bignumber from 'kredits-web/utils/cps/bignumber';
|
|
||||||
|
|
||||||
export default EmberObject.extend({
|
const {
|
||||||
|
isPresent,
|
||||||
|
isEmpty,
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
// Contract
|
export default Ember.Object.extend({
|
||||||
id: bignumber('idRaw', 'toString'),
|
|
||||||
creatorAccount: null,
|
id: null,
|
||||||
contributorId: bignumber('contributorIdRaw', 'toString'),
|
creatorAddress: null,
|
||||||
amount: bignumber('amountRaw', 'toNumber'),
|
recipientAddress: null,
|
||||||
votesCount: bignumber('votesCountRaw', 'toNumber'),
|
recipientName: null,
|
||||||
votesNeeded: bignumber('votesNeededRaw', 'toNumber'),
|
recipientProfile: null,
|
||||||
|
votesCount: null,
|
||||||
|
votesNeeded: null,
|
||||||
|
amount: null,
|
||||||
executed: null,
|
executed: null,
|
||||||
ipfsHash: null,
|
contribution: null,
|
||||||
|
|
||||||
// Shortcuts
|
|
||||||
isExecuted: alias('executed'),
|
|
||||||
|
|
||||||
// IPFS
|
|
||||||
kind: null,
|
kind: null,
|
||||||
description: null,
|
description: null,
|
||||||
details: null,
|
|
||||||
url: null,
|
url: null,
|
||||||
ipfsData: '',
|
details: null,
|
||||||
|
ipfsHash: null,
|
||||||
|
|
||||||
init () {
|
/**
|
||||||
this._super(...arguments);
|
* Loads the contribution details from IPFS and sets local instance
|
||||||
this.set('details', {});
|
* properties from it
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
loadContribution(ipfs) {
|
||||||
|
let promise = new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
|
ipfs.getFile(this.get('ipfsHash')).then(content => {
|
||||||
|
let contributionJSON = JSON.parse(content);
|
||||||
|
let contribution = Ember.Object.create(contributionJSON);
|
||||||
|
|
||||||
|
this.setProperties({
|
||||||
|
kind: contribution.get('kind'),
|
||||||
|
description: contribution.get('description'),
|
||||||
|
url: contribution.get('url')
|
||||||
|
});
|
||||||
|
|
||||||
|
// TODO load details
|
||||||
|
// let details = profile.get('accounts');
|
||||||
|
|
||||||
|
Ember.Logger.debug('[proposal] loaded contribution details', contributionJSON);
|
||||||
|
resolve();
|
||||||
|
}).catch((err) => {
|
||||||
|
Ember.Logger.error('[proposal] error trying to load contribution details', this.get('ipfsHash'), err);
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a JSON-LD object of the contribution, according to
|
||||||
|
* https://github.com/67P/kosmos-schemas/blob/master/schemas/contribution.json
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
contributionToJSON() {
|
||||||
|
if (isEmpty(this.get('recipientProfile'))) {
|
||||||
|
throw new Error('IPFS hash for recipient profile missing from proposal object');
|
||||||
|
}
|
||||||
|
if (isEmpty(this.get('kind')) || isEmpty(this.get('description'))) {
|
||||||
|
throw new Error('Missing one or more required properties: kind, description');
|
||||||
|
}
|
||||||
|
|
||||||
|
let contribution = {
|
||||||
|
"@context": "https://schema.kosmos.org",
|
||||||
|
"@type": "Contribution",
|
||||||
|
"contributor": {
|
||||||
|
"ipfs": this.get('recipientProfile')
|
||||||
|
},
|
||||||
|
"kind": this.get('kind'),
|
||||||
|
"description": this.get('description'),
|
||||||
|
"details": {}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isPresent(this.get('url'))) {
|
||||||
|
contribution["url"] = this.get('url');
|
||||||
|
}
|
||||||
|
|
||||||
|
return contribution;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the JSON-LD representation of the contribution as a string
|
||||||
|
*
|
||||||
|
* @method
|
||||||
|
* @public
|
||||||
|
*/
|
||||||
|
serializeContribution() {
|
||||||
|
return JSON.stringify(this.contributionToJSON());
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
+3
-9
@@ -1,22 +1,16 @@
|
|||||||
import EmberRouter from '@ember/routing/router';
|
import Ember from 'ember';
|
||||||
import config from './config/environment';
|
import config from './config/environment';
|
||||||
|
|
||||||
const Router = EmberRouter.extend({
|
const Router = Ember.Router.extend({
|
||||||
location: config.locationType,
|
location: config.locationType,
|
||||||
rootURL: config.rootURL
|
rootURL: config.rootURL
|
||||||
});
|
});
|
||||||
|
|
||||||
Router.map(function() {
|
Router.map(function() {
|
||||||
|
this.route('spinner');
|
||||||
this.route('proposals', function() {
|
this.route('proposals', function() {
|
||||||
this.route('new');
|
this.route('new');
|
||||||
});
|
});
|
||||||
this.route('contributions', function() {
|
|
||||||
this.route('new');
|
|
||||||
});
|
|
||||||
this.route('contributors', function() {
|
|
||||||
this.route('new');
|
|
||||||
this.route('edit', { path: ':id/edit' });
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
export default Router;
|
export default Router;
|
||||||
|
|||||||
@@ -1,31 +1,4 @@
|
|||||||
import { inject as service } from '@ember/service';
|
import Ember from 'ember';
|
||||||
import Route from '@ember/routing/route';
|
|
||||||
|
|
||||||
export default Route.extend({
|
export default Ember.Route.extend({
|
||||||
kredits: service(),
|
|
||||||
|
|
||||||
beforeModel(transition) {
|
|
||||||
const kredits = this.kredits;
|
|
||||||
|
|
||||||
return kredits.setup().then(() => {
|
|
||||||
kredits.get('kredits').preflightChecks().catch((error) => {
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
afterModel() {
|
|
||||||
return this.kredits.loadInitialData()
|
|
||||||
.then(() => {
|
|
||||||
this.kredits.addContractEventHandlers();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
import { inject as service } from '@ember/service';
|
|
||||||
import Route from '@ember/routing/route';
|
|
||||||
import { alias } from '@ember/object/computed';
|
|
||||||
|
|
||||||
export default Route.extend({
|
|
||||||
|
|
||||||
kredits: service(),
|
|
||||||
contributors: alias('kredits.contributors'),
|
|
||||||
|
|
||||||
model(params) {
|
|
||||||
return this.kredits.contributors.findBy('id', params.id);
|
|
||||||
},
|
|
||||||
|
|
||||||
setupController (controller, model) {
|
|
||||||
this._super(controller, model);
|
|
||||||
|
|
||||||
controller.set('attributes', {
|
|
||||||
account: model.account,
|
|
||||||
name: model.name,
|
|
||||||
kind: model.kind,
|
|
||||||
url: model.url,
|
|
||||||
github_username: model.github_username,
|
|
||||||
github_uid: model.github_uid,
|
|
||||||
gitea_username: model.gitea_username,
|
|
||||||
wiki_username: model.wiki_username
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
import Ember from 'ember';
|
||||||
|
import Contributor from 'kredits-web/models/contributor';
|
||||||
|
|
||||||
|
export default Ember.Route.extend({
|
||||||
|
|
||||||
|
kredits: Ember.inject.service(),
|
||||||
|
|
||||||
|
beforeModel(transition) {
|
||||||
|
const kredits = this.get('kredits');
|
||||||
|
|
||||||
|
if (kredits.get('web3') && kredits.get('web3Provided')) {
|
||||||
|
kredits.get('web3').eth.getAccounts((error, accounts) => {
|
||||||
|
if (error || accounts.length === 0) {
|
||||||
|
if (confirm('It looks like you have an Ethereum wallet available. Please unlock your account.')) {
|
||||||
|
transition.retry();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
model() {
|
||||||
|
let kredits = this.get('kredits');
|
||||||
|
|
||||||
|
return Ember.RSVP.hash({
|
||||||
|
contributors: kredits.getContributors(),
|
||||||
|
totalSupply: kredits.getValueFromContract('tokenContract', 'totalSupply'),
|
||||||
|
proposals: kredits.getProposals(),
|
||||||
|
contributions: kredits.getContributions(),
|
||||||
|
newContributor: Contributor.create({ kind: 'person' })
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
import Ember from 'ember';
|
||||||
|
import Proposal from 'kredits-web/models/proposal';
|
||||||
|
|
||||||
|
const {
|
||||||
|
Route,
|
||||||
|
RSVP,
|
||||||
|
inject: {
|
||||||
|
service
|
||||||
|
}
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
|
export default Route.extend({
|
||||||
|
|
||||||
|
kredits: service(),
|
||||||
|
|
||||||
|
model(params) {
|
||||||
|
const proposal = Proposal.create({
|
||||||
|
recipientAddress: params.recipient,
|
||||||
|
amount: params.amount,
|
||||||
|
url: params.url,
|
||||||
|
kind: params.kind || 'dev',
|
||||||
|
ipfsHash: params.ipfsHash
|
||||||
|
});
|
||||||
|
|
||||||
|
return RSVP.hash({
|
||||||
|
proposal,
|
||||||
|
contributors: this.get('kredits').getContributors()
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
setupController(controller, model) {
|
||||||
|
this._super(controller, model.proposal);
|
||||||
|
|
||||||
|
controller.set('contributors', model.contributors);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
import Ember from 'ember';
|
||||||
|
|
||||||
|
export default Ember.Route.extend({
|
||||||
|
});
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import Ember from 'ember';
|
||||||
|
import ipfsAPI from 'npm:ipfs-api';
|
||||||
|
import config from 'kredits-web/config/environment';
|
||||||
|
|
||||||
|
export default Ember.Service.extend({
|
||||||
|
|
||||||
|
ipfsInstance: null,
|
||||||
|
|
||||||
|
ipfs: function() {
|
||||||
|
if (this.get('ipfsInstance')) {
|
||||||
|
return this.get('ipfsInstance');
|
||||||
|
}
|
||||||
|
let ipfs = ipfsAPI(config.ipfs);
|
||||||
|
this.set('ipfsInstance', ipfs);
|
||||||
|
return ipfs;
|
||||||
|
}.property('ipfsInstance'),
|
||||||
|
|
||||||
|
storeFile(content) {
|
||||||
|
let ipfs = this.get('ipfs');
|
||||||
|
return ipfs.add(new ipfs.Buffer(content)).then(res => {
|
||||||
|
Ember.Logger.debug('[ipfs] stored content in IPFS', content, res[0].hash);
|
||||||
|
return res[0].hash;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getFile(hash) {
|
||||||
|
return this.get('ipfs').cat(hash, { buffer: true }).then(res => {
|
||||||
|
return res.toString();
|
||||||
|
}, err => {
|
||||||
|
Ember.Logger.error('[ipfs] error trying to fetch file', hash, err);
|
||||||
|
throw err;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
+236
-352
@@ -1,400 +1,284 @@
|
|||||||
import ethers from 'npm:ethers';
|
import Ember from 'ember';
|
||||||
import Kredits from 'npm:kredits-contracts';
|
import Web3 from 'npm:web3';
|
||||||
import RSVP from 'rsvp';
|
|
||||||
|
|
||||||
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 groupBy from 'kredits-web/utils/group-by';
|
|
||||||
import formatKredits from 'kredits-web/utils/format-kredits';
|
|
||||||
|
|
||||||
import config from 'kredits-web/config/environment';
|
import config from 'kredits-web/config/environment';
|
||||||
import Contributor from 'kredits-web/models/contributor'
|
import Contributor from 'kredits-web/models/contributor';
|
||||||
import Proposal from 'kredits-web/models/proposal'
|
import Proposal from 'kredits-web/models/proposal';
|
||||||
import Contribution from 'kredits-web/models/contribution'
|
import Contribution from 'kredits-web/models/contribution';
|
||||||
|
import kreditsContracts from 'npm:kredits-contracts';
|
||||||
|
import uuid from 'npm:uuid';
|
||||||
|
|
||||||
|
const {
|
||||||
|
Service,
|
||||||
|
isPresent,
|
||||||
|
inject: {
|
||||||
|
service
|
||||||
|
}
|
||||||
|
} = Ember;
|
||||||
|
|
||||||
export default Service.extend({
|
export default Service.extend({
|
||||||
|
|
||||||
currentBlock: null,
|
ipfs: service(),
|
||||||
currentUserAccounts: null, // default to not having an account. this is the wen web3 is loaded.
|
|
||||||
currentUser: null,
|
|
||||||
contributors: null,
|
|
||||||
contributions: null,
|
|
||||||
proposals: null,
|
|
||||||
|
|
||||||
currentUserIsContributor: notEmpty('currentUser'),
|
web3Instance: null,
|
||||||
currentUserIsCore: alias('currentUser.isCore'),
|
web3Provided: false, // Web3 provided (using Mist Browser, Metamask et al.)
|
||||||
hasAccounts: notEmpty('currentUserAccounts'),
|
|
||||||
|
|
||||||
accountNeedsUnlock: computed('currentUserAccounts', function() {
|
web3: function() {
|
||||||
return this.currentUserAccounts && isEmpty(this.currentUserAccounts);
|
if (this.get('web3Instance')) {
|
||||||
}),
|
return this.get('web3Instance');
|
||||||
|
}
|
||||||
|
|
||||||
contributionsUnconfirmed: computed('contributions.[]', 'currentBlock', function() {
|
let web3Instance;
|
||||||
return this.contributions.filter(contribution => {
|
|
||||||
return contribution.confirmedAt > this.currentBlock;
|
|
||||||
});
|
|
||||||
}),
|
|
||||||
|
|
||||||
contributionsConfirmed: computed('contributions.[]', 'currentBlock', function() {
|
if (typeof window.web3 !== 'undefined') {
|
||||||
return this.contributions
|
Ember.Logger.debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
|
||||||
.filterBy('vetoed', false)
|
web3Instance = window.web3;
|
||||||
.filter(contribution => {
|
this.set('web3Provided', true);
|
||||||
return contribution.confirmedAt <= this.currentBlock;
|
} else {
|
||||||
});
|
Ember.Logger.debug('[kredits] Creating new instance from npm module class');
|
||||||
}),
|
let providerUrl = localStorage.getItem('config:web3ProviderUrl') || config.web3ProviderUrl;
|
||||||
|
let provider = new Web3.providers.HttpProvider(providerUrl);
|
||||||
|
web3Instance = new Web3(provider);
|
||||||
|
}
|
||||||
|
|
||||||
kreditsByContributor: computed('contributionsUnconfirmed.@each.vetoed', 'contributors.[]', function() {
|
this.set('web3Instance', web3Instance);
|
||||||
const contributionsUnconfirmed = this.contributionsUnconfirmed.filterBy('vetoed', false);
|
window.web3 = web3Instance;
|
||||||
const contributionsGrouped = groupBy(contributionsUnconfirmed, 'contributorId');
|
|
||||||
const contributorsWithUnconfirmed = contributionsGrouped.map(c => c.value.toString());
|
|
||||||
const contributorsWithOnlyConfirmed = this.contributors.reject(c => contributorsWithUnconfirmed.includes(c.id))
|
|
||||||
|
|
||||||
const kreditsByContributor = contributionsGrouped.map(c => {
|
return web3Instance;
|
||||||
const amountUnconfirmed = c.items.mapBy('amount').reduce((a, b) => a + b);
|
}.property('web3Instance'),
|
||||||
const contributor = this.contributors.findBy('id', c.value.toString());
|
|
||||||
|
|
||||||
return EmberObject.create({
|
currentUserAccounts: function() {
|
||||||
contributor: contributor,
|
return (this.get('web3Provided') && this.get('web3').eth.accounts) || [];
|
||||||
amountUnconfirmed: amountUnconfirmed,
|
}.property('web3Provided', 'web3'),
|
||||||
amountConfirmed: contributor.totalKreditsEarned,
|
|
||||||
amountTotal: contributor.totalKreditsEarned + amountUnconfirmed
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
contributorsWithOnlyConfirmed.forEach(c => {
|
initializeKreditsContract() {
|
||||||
kreditsByContributor.push(EmberObject.create({
|
let contract = null;
|
||||||
contributor: c,
|
|
||||||
amountUnconfirmed: 0,
|
|
||||||
amountConfirmed: c.totalKreditsEarned,
|
|
||||||
amountTotal: c.totalKreditsEarned
|
|
||||||
}));
|
|
||||||
})
|
|
||||||
|
|
||||||
return kreditsByContributor;
|
if (isPresent(config.contractMetadata)) {
|
||||||
}),
|
if (localStorage.getItem('config:networkId')) {
|
||||||
|
config.contractMetadata['networkId'] = localStorage.getItem('config:networkId');
|
||||||
|
}
|
||||||
|
contract = kreditsContracts(this.get('web3'), config.contractMetadata)['Kredits'];
|
||||||
|
} else {
|
||||||
|
contract = kreditsContracts(this.get('web3'))['Kredits'];
|
||||||
|
}
|
||||||
|
|
||||||
init () {
|
return contract;
|
||||||
this._super(...arguments);
|
|
||||||
this.set('contributors', []);
|
|
||||||
this.set('proposals', []);
|
|
||||||
this.set('contributions', []);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// This is called in the application route's beforeModel(). So it is
|
kreditsContract: function() {
|
||||||
// initialized before everything else, and we can rely on the ethProvider and
|
if (this.get('kreditsContractInstance')) {
|
||||||
// the potential currentUserAccounts to be available
|
return this.get('kreditsContractInstance');
|
||||||
getEthProvider () {
|
}
|
||||||
let ethProvider;
|
|
||||||
|
|
||||||
return new RSVP.Promise(async (resolve) => {
|
let contract = this.initializeKreditsContract();
|
||||||
function instantiateWithoutAccount () {
|
|
||||||
console.debug('[kredits] Creating new instance from npm module class');
|
|
||||||
console.debug(`[kredits] providerURL: ${config.web3ProviderUrl}`);
|
|
||||||
ethProvider = new ethers.providers.JsonRpcProvider(config.web3ProviderUrl);
|
|
||||||
resolve({
|
|
||||||
ethProvider: ethProvider,
|
|
||||||
ethSigner: null
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function instantiateWithAccount (web3Provider, context) {
|
this.set('kreditsContractInstance', contract);
|
||||||
console.debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
|
// window.Kredits = contract;
|
||||||
ethProvider = new ethers.providers.Web3Provider(web3Provider);
|
return contract;
|
||||||
// const network = await ethProvider.getNetwork();
|
}.property('kreditsContractInstance', 'web3'),
|
||||||
ethProvider.listAccounts().then(accounts => {
|
|
||||||
context.set('currentUserAccounts', accounts);
|
tokenContract: function() {
|
||||||
const ethSigner = accounts.length === 0 ? null : ethProvider.getSigner();
|
if (this.get('tokenContractInstance')) {
|
||||||
resolve({
|
return this.get('tokenContractInstance');
|
||||||
ethProvider,
|
}
|
||||||
ethSigner
|
|
||||||
|
let contract = kreditsContracts(this.get('web3'), config.contractMetadata)['Token'];
|
||||||
|
this.set('tokenContractInstance', contract);
|
||||||
|
window.Token = contract;
|
||||||
|
return contract;
|
||||||
|
}.property('tokenContractInstance', 'web3'),
|
||||||
|
|
||||||
|
getValueFromContract(contract, contractMethod, ...args) {
|
||||||
|
Ember.Logger.debug('[kredits] read from contract', contract);
|
||||||
|
return new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
|
this.get(contract)[contractMethod](...args, (err, data) => {
|
||||||
|
if (err) { reject(err); return; }
|
||||||
|
resolve(data);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
getContributorData(i) {
|
||||||
|
let promise = new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
|
this.getValueFromContract('kreditsContract', 'contributorAddresses', i).then(address => {
|
||||||
|
this.getValueFromContract('kreditsContract', 'contributors', address).then(person => {
|
||||||
|
this.getValueFromContract('tokenContract', 'balanceOf', address).then(balance => {
|
||||||
|
Ember.Logger.debug('[kredits] person', address, person);
|
||||||
|
|
||||||
|
let contributor = Contributor.create({
|
||||||
|
address: address,
|
||||||
|
ipfsHash: person[2],
|
||||||
|
kredits: balance.toNumber(),
|
||||||
|
isCurrentUser: this.get('currentUserAccounts').includes(address)
|
||||||
|
});
|
||||||
|
|
||||||
|
contributor.loadProfile(this.get('ipfs')).then(
|
||||||
|
() => resolve(contributor),
|
||||||
|
err => reject(err)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
}).catch(err => reject(err));
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
},
|
||||||
|
|
||||||
|
getContributors() {
|
||||||
|
return this.getValueFromContract('kreditsContract', 'contributorsCount').then(contributorsCount => {
|
||||||
|
let contributors = [];
|
||||||
|
|
||||||
|
for(var i = 0; i < contributorsCount.toNumber(); i++) {
|
||||||
|
contributors.push(this.getContributorData(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (window.ethereum) {
|
return Ember.RSVP.all(contributors);
|
||||||
try {
|
|
||||||
// Request account access if needed
|
|
||||||
await window.ethereum.enable();
|
|
||||||
// Acccounts now exposed
|
|
||||||
instantiateWithAccount(window.ethereum, this);
|
|
||||||
} catch (error) {
|
|
||||||
instantiateWithoutAccount();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Legacy dapp browsers...
|
|
||||||
else if (window.web3) {
|
|
||||||
instantiateWithAccount(window.web3.currentProvider, this);
|
|
||||||
}
|
|
||||||
// Non-dapp browsers...
|
|
||||||
else {
|
|
||||||
instantiateWithoutAccount();
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
setup () {
|
getProposalData(i) {
|
||||||
return this.getEthProvider().then((providerAndSigner) => {
|
let promise = new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
let kredits = new Kredits(providerAndSigner.ethProvider, providerAndSigner.ethSigner, {
|
this.getValueFromContract('kreditsContract', 'proposals', i).then(p => {
|
||||||
addresses: { Kernel: config.kreditsKernelAddress },
|
let proposal = Proposal.create({
|
||||||
apm: config.kreditsApmDomain,
|
id : i,
|
||||||
ipfsConfig: config.ipfs
|
creatorAddress : p[0],
|
||||||
});
|
recipientAddress : p[1],
|
||||||
return kredits
|
votesCount : p[2].toNumber(),
|
||||||
.init()
|
votesNeeded : p[3].toNumber(),
|
||||||
.then(async (kredits) => {
|
amount : p[4].toNumber(),
|
||||||
this.set('kredits', kredits);
|
executed : p[5],
|
||||||
this.set('currentBlock', await kredits.provider.getBlockNumber());
|
url : p[6],
|
||||||
|
ipfsHash : p[7]
|
||||||
if (this.currentUserAccounts && this.currentUserAccounts.length > 0) {
|
|
||||||
this.getCurrentUser.then((contributorData) => {
|
|
||||||
this.set('currentUser', contributorData);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return kredits;
|
|
||||||
});
|
});
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
totalSupply: computed(function() {
|
if (proposal.get('ipfsHash')) {
|
||||||
return this.kredits.Token.functions.totalSupply().then(total => {
|
proposal.loadContribution(this.get('ipfs')).then(
|
||||||
return formatKredits(total);
|
() => resolve(proposal),
|
||||||
})
|
err => reject(err)
|
||||||
}),
|
);
|
||||||
|
|
||||||
totalKreditsEarned: computed(function() {
|
|
||||||
return this.kredits.Contribution.functions.totalKreditsEarned(true)
|
|
||||||
.then(total => total.toNumber());
|
|
||||||
}),
|
|
||||||
|
|
||||||
|
|
||||||
loadInitialData () {
|
|
||||||
return this.getContributors()
|
|
||||||
.then(contributors => this.contributors.pushObjects(contributors))
|
|
||||||
.then(() => this.getContributions())
|
|
||||||
.then(contributions => this.contributions.pushObjects(contributions))
|
|
||||||
},
|
|
||||||
|
|
||||||
addContributor (attributes) {
|
|
||||||
if (attributes.github_uid) {
|
|
||||||
const uidInt = parseInt(attributes.github_uid);
|
|
||||||
attributes.github_uid = uidInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.debug('[kredits] add contributor', attributes);
|
|
||||||
|
|
||||||
return this.kredits.Contributor.add(attributes, { gasLimit: 350000 })
|
|
||||||
.then(data => {
|
|
||||||
console.debug('[kredits] add contributor response', data);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
updateContributor (id, attributes) {
|
|
||||||
if (attributes.github_uid) {
|
|
||||||
const uidInt = parseInt(attributes.github_uid);
|
|
||||||
attributes.github_uid = uidInt;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.debug('[kredits] update contributor', attributes);
|
|
||||||
|
|
||||||
return this.kredits.Contributor.updateProfile(id, attributes, { gasLimit: 350000 })
|
|
||||||
.then(data => {
|
|
||||||
console.debug('[kredits] updateProfile response', data);
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getContributors () {
|
|
||||||
return this.kredits.Contributor.all()
|
|
||||||
.then((contributors) => {
|
|
||||||
return contributors.map((contributor) => {
|
|
||||||
return Contributor.create(contributor);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
addContribution (attributes) {
|
|
||||||
console.debug('[kredits] add contribution', attributes);
|
|
||||||
|
|
||||||
return this.kredits.Contribution.addContribution(attributes, { gasLimit: 300000 })
|
|
||||||
.then(data => {
|
|
||||||
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);
|
|
||||||
|
|
||||||
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);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getContributions () {
|
|
||||||
return this.kredits.Contribution.all({page: {size: 200}})
|
|
||||||
.then(contributions => {
|
|
||||||
return contributions.map(contribution => {
|
|
||||||
contribution.contributor = this.contributors.findBy('id', contribution.contributorId.toString());
|
|
||||||
return Contribution.create(contribution);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
vote (proposalId) {
|
|
||||||
console.debug('[kredits] vote for', proposalId);
|
|
||||||
|
|
||||||
return this.kredits.Proposal.functions.vote(proposalId)
|
|
||||||
.then(data => {
|
|
||||||
console.debug('[kredits] vote response', data);
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
veto (contributionId) {
|
|
||||||
console.debug('[kredits] veto against', contributionId);
|
|
||||||
|
|
||||||
return this.kredits.Contribution.functions.veto(contributionId, { gasLimit: 300000 })
|
|
||||||
.then(data => {
|
|
||||||
console.debug('[kredits] veto response', data);
|
|
||||||
return data;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getCurrentUser: computed('kredits.provider', function() {
|
|
||||||
if (isEmpty(this.currentUserAccounts)) {
|
|
||||||
return RSVP.resolve();
|
|
||||||
}
|
|
||||||
return this.kredits.Contributor
|
|
||||||
.functions.getContributorIdByAddress(this.get('currentUserAccounts.firstObject'))
|
|
||||||
.then((id) => {
|
|
||||||
// check if the user is a contributor or not
|
|
||||||
if (id === 0) {
|
|
||||||
return RSVP.resolve();
|
|
||||||
} else {
|
} else {
|
||||||
return this.kredits.Contributor.getById(id);
|
Ember.Logger.warn('[kredits] proposal from blockchain is missing IPFS hash', proposal);
|
||||||
|
resolve(proposal);
|
||||||
}
|
}
|
||||||
|
}).catch(err => reject(err));
|
||||||
|
});
|
||||||
|
return promise;
|
||||||
|
},
|
||||||
|
|
||||||
|
getProposals() {
|
||||||
|
return this.getValueFromContract('kreditsContract', 'proposalsCount').then(proposalsCount => {
|
||||||
|
let proposals = [];
|
||||||
|
|
||||||
|
for(var i = 0; i < proposalsCount.toNumber(); i++) {
|
||||||
|
proposals.push(this.getProposalData(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
return Ember.RSVP.all(proposals);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
vote(proposalId) {
|
||||||
|
Ember.Logger.debug('[kredits] vote for', proposalId);
|
||||||
|
return new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
|
this.get('kreditsContract').vote(proposalId, (err, data) => {
|
||||||
|
if (err) { reject(err); return; }
|
||||||
|
Ember.Logger.debug('[kredits] vote response', data);
|
||||||
|
resolve(data);
|
||||||
});
|
});
|
||||||
}),
|
});
|
||||||
|
|
||||||
findProposalById(proposalId) {
|
|
||||||
return this.proposals.findBy('id', proposalId.toString());
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Contract events
|
addContributor(contributor) {
|
||||||
addContractEventHandlers () {
|
Ember.Logger.debug('[kredits] add contributor', contributor);
|
||||||
this.kredits.Contributor
|
|
||||||
.on('ContributorProfileUpdated', this.handleContributorChange.bind(this))
|
|
||||||
.on('ContributorAccountUpdated', this.handleContributorChange.bind(this))
|
|
||||||
.on('ContributorAdded', this.handleContributorChange.bind(this))
|
|
||||||
|
|
||||||
this.kredits.Contribution
|
contributor.setProperties({
|
||||||
.on('ContributionVetoed', this.handleContributionVetoed.bind(this))
|
kredits: 0,
|
||||||
|
isCurrentUser: this.get('currentUserAccounts').includes(contributor.address)
|
||||||
|
});
|
||||||
|
|
||||||
this.kredits.Proposal
|
let id = uuid.v4();
|
||||||
.on('ProposalCreated', this.handleProposalCreated.bind(this))
|
|
||||||
.on('ProposalVoted', this.handleProposalVoted.bind(this))
|
|
||||||
.on('ProposalExecuted', this.handleProposalExecuted.bind(this));
|
|
||||||
|
|
||||||
this.kredits.Token
|
return new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
.on('Transfer', this.handleTransfer.bind(this));
|
this.get('ipfs').storeFile(contributor.serialize()).then(ipfsHash => {
|
||||||
},
|
contributor.set('ipfsHash', ipfsHash);
|
||||||
|
this.get('kreditsContract').addContributor(contributor.address, contributor.name, contributor.ipfsHash, contributor.isCore, id, (err, data) => {
|
||||||
async handleContributorChange (contributorId, ...args) {
|
if (err) { reject(err); return; }
|
||||||
console.debug('[kredits] Contributor add/update event received for ID', contributorId);
|
Ember.Logger.debug('[kredits] add contributor response', data);
|
||||||
console.debug('[kredits] Event data:', args);
|
resolve(contributor);
|
||||||
const contributorData = await this.kredits.Contributor.getById(contributorId);
|
});
|
||||||
const newContributor = Contributor.create(contributorData);
|
|
||||||
|
|
||||||
const oldContributor = this.contributors.findBy('id', contributorId.toString());
|
|
||||||
if (oldContributor) {
|
|
||||||
console.debug('[kredits] old contributor', oldContributor);
|
|
||||||
this.contributors.removeObject(oldContributor);
|
|
||||||
}
|
|
||||||
|
|
||||||
console.debug('[kredits] new contributor', newContributor);
|
|
||||||
this.contributors.pushObject(newContributor);
|
|
||||||
},
|
|
||||||
|
|
||||||
handleContributionVetoed (contributionId) {
|
|
||||||
console.debug('[kredits] ContributionVetoed event received for ', contributionId);
|
|
||||||
const contribution = this.contributions.findBy('id', contributionId);
|
|
||||||
console.debug('[kredits] contribution', contribution);
|
|
||||||
|
|
||||||
if (contribution) {
|
|
||||||
contribution.set('vetoed', true);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
handleProposalCreated (proposalId) {
|
|
||||||
let proposal = this.findProposalById(proposalId);
|
|
||||||
|
|
||||||
if (proposal) {
|
|
||||||
console.debug('[events] proposal exists, not adding from event');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.kredits.Proposal.getById(proposalId)
|
|
||||||
.then((proposal) => {
|
|
||||||
proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
|
|
||||||
this.proposals.pushObject(Proposal.create(proposal));
|
|
||||||
});
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
// TODO: We may want to reload that proposal to show the voter as voted
|
addProposal(proposal) {
|
||||||
handleProposalVoted (proposalId, voterId, totalVotes) {
|
return new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
let proposal = this.findProposalById(proposalId);
|
const {
|
||||||
|
recipientAddress,
|
||||||
|
amount,
|
||||||
|
url
|
||||||
|
} = proposal.getProperties('recipientAddress', 'amount', 'url');
|
||||||
|
|
||||||
if (proposal) {
|
this.get('ipfs').storeFile(proposal.serializeContribution()).then(ipfsHash => {
|
||||||
proposal.set('votesCount', totalVotes);
|
this.get('kreditsContract').addProposal(recipientAddress, amount, url, ipfsHash, (err, data) => {
|
||||||
}
|
if (err) { reject(err); return; }
|
||||||
|
Ember.Logger.debug('[kredits] add proposal response', data);
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
handleProposalExecuted (proposalId, contributorId, amount) {
|
getTokenMintedEvents(fromBlock=0, toBlock='latest') {
|
||||||
let proposal = this.findProposalById(proposalId);
|
return new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
|
const minted = this.get('tokenContract')
|
||||||
|
.Minted({}, {fromBlock: fromBlock, toBlock: toBlock});
|
||||||
|
|
||||||
if (proposal.get('isExecuted')) {
|
minted.get((err, res) => {
|
||||||
console.debug('[events] proposal already executed, not adding from event');
|
if (err) {
|
||||||
return;
|
Ember.Logger.error('[kredits] Error reading Token#Minted events', res);
|
||||||
}
|
reject(err);
|
||||||
|
return;
|
||||||
proposal.set('executed', true);
|
}
|
||||||
|
Ember.Logger.warn('[kredits] Token#Minted events', res);
|
||||||
this.contributors
|
resolve(res);
|
||||||
.findBy('id', contributorId.toString())
|
});
|
||||||
.incrementProperty('balance', amount);
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
handleTransfer (from, to, value) {
|
getContributions() {
|
||||||
value = value.toNumber();
|
// this.getTokenMintedEvents().then(events => {
|
||||||
|
let contributions = [];
|
||||||
|
|
||||||
this.contributors
|
config.fixtures.mintedEvents.forEach(mintedEvent => {
|
||||||
.findBy('address', from)
|
contributions.push(this.getContributionData(mintedEvent));
|
||||||
.decrementProperty('balance', value);
|
});
|
||||||
|
|
||||||
this.contributors
|
return Ember.RSVP.all(contributions);
|
||||||
.findBy('address', to)
|
// });
|
||||||
.incrementProperty('balance', value);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getContributionData(mintedEvent) {
|
||||||
|
return new Ember.RSVP.Promise((resolve, reject) => {
|
||||||
|
let contribution = Contribution.create({
|
||||||
|
recipientAddress: mintedEvent.args.recipientAddress,
|
||||||
|
contributorId: mintedEvent.args.contributorId,
|
||||||
|
amount: mintedEvent.args.amount,
|
||||||
|
ipfsHash: mintedEvent.args.reference
|
||||||
|
});
|
||||||
|
|
||||||
|
if (contribution.get('ipfsHash')) {
|
||||||
|
contribution.loadDetails(this.get('ipfs')).then(
|
||||||
|
() => resolve(contribution),
|
||||||
|
err => reject(err)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
Ember.Logger.warn('[kredits] contribution from Minted event is missing IPFS hash', contribution);
|
||||||
|
resolve(contribution);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
// logKreditsContract: function() {
|
||||||
|
// Ember.Logger.debug('[kredits] kreditsContract', this.get('kreditsContract'));
|
||||||
|
// }.on('init')
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,42 +0,0 @@
|
|||||||
button, input[type=submit], .button {
|
|
||||||
display: inline-block;
|
|
||||||
padding: 0.6rem 2rem;
|
|
||||||
background-color: rgba(22, 21, 40, 0.6);
|
|
||||||
border: 1px solid rgba(22, 21, 40, 1);
|
|
||||||
border-radius: 3px;
|
|
||||||
color: $primary-color;
|
|
||||||
font-weight: 500;
|
|
||||||
text-decoration: none;
|
|
||||||
text-transform: uppercase;
|
|
||||||
cursor: pointer;
|
|
||||||
letter-spacing: 0.1em;
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(22, 21, 40, 0.8);
|
|
||||||
}
|
|
||||||
|
|
||||||
&.small {
|
|
||||||
font-size: 0.8rem;
|
|
||||||
padding: 0.2rem 0.8rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.danger {
|
|
||||||
color: $red;
|
|
||||||
background-color: rgba(40, 21, 21, 0.6);
|
|
||||||
border-color: rgba(40, 21, 21, 1);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(40, 21, 21, 0.8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.green {
|
|
||||||
color: $green;
|
|
||||||
background-color: rgba(21, 40, 21, 0.6);
|
|
||||||
border-color: rgba(21, 40, 21, 1);
|
|
||||||
|
|
||||||
&:hover {
|
|
||||||
background-color: rgba(21, 40, 21, 0.8);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -5,11 +5,4 @@ $green: #97fb68;
|
|||||||
$yellow: #fbe468;
|
$yellow: #fbe468;
|
||||||
$red: #fb6868;
|
$red: #fb6868;
|
||||||
|
|
||||||
$primary-color: $blue;
|
$primaryColor: $blue;
|
||||||
|
|
||||||
$body-text-color: #fff;
|
|
||||||
|
|
||||||
#topbar {
|
|
||||||
background-color: rgba(255, 0, 255, .2);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|||||||
+18
-69
@@ -1,82 +1,31 @@
|
|||||||
main {
|
section {
|
||||||
padding: 1rem 2rem;
|
@include outer-container;
|
||||||
|
margin-bottom: 8rem;
|
||||||
@include media-max(small) {
|
|
||||||
padding: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&#index {
|
|
||||||
width: 100%;
|
|
||||||
display: grid;
|
|
||||||
grid-row-gap: 2rem;
|
|
||||||
grid-template-areas:
|
|
||||||
"stats"
|
|
||||||
"contributions";
|
|
||||||
}
|
|
||||||
|
|
||||||
&.center-column {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
|
|
||||||
section {
|
|
||||||
width: 600px;
|
|
||||||
max-width: 100%;
|
|
||||||
|
|
||||||
header {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (min-width: 550px) {
|
|
||||||
main {
|
|
||||||
&#index {
|
|
||||||
grid-column-gap: 4rem;
|
|
||||||
grid-row-gap: 2rem;
|
|
||||||
grid-template-columns: 2fr 4fr;
|
|
||||||
grid-template-areas:
|
|
||||||
"stats contributions";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
main section {
|
|
||||||
margin-bottom: 5rem;
|
|
||||||
|
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
margin-top: 2rem;
|
margin-top: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media-max(small) {
|
@include media($mobile) {
|
||||||
margin-bottom: 5rem;
|
margin-bottom: 5rem;
|
||||||
|
&:first-of-type {
|
||||||
|
margin-top: 2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
margin-bottom: 3rem;
|
@include span-columns(12);
|
||||||
|
padding-bottom: 3rem;
|
||||||
|
text-align: center;
|
||||||
|
// background-color: purple;
|
||||||
|
|
||||||
&.with-nav {
|
@include media($mobile) {
|
||||||
display: grid;
|
@include span-columns(10);
|
||||||
grid-template-columns: auto 5rem;
|
@include shift(1);
|
||||||
grid-template-areas:
|
padding-bottom: 2rem;
|
||||||
"title" "actions";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
div.content {
|
||||||
display: inline-block;
|
@include span-columns(12);
|
||||||
// padding-left: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
nav {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: row;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
|
|
||||||
@include media-max(small) {
|
|
||||||
margin-bottom: 2rem;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,33 +0,0 @@
|
|||||||
$breakpoints-max: (
|
|
||||||
small: 600px,
|
|
||||||
medium: 960px,
|
|
||||||
large: 1280px
|
|
||||||
);
|
|
||||||
|
|
||||||
$breakpoints-min: (
|
|
||||||
small: 601px,
|
|
||||||
medium: 961px,
|
|
||||||
large: 1281px
|
|
||||||
);
|
|
||||||
|
|
||||||
@mixin media-max($screen-size) {
|
|
||||||
@if map-has-key($breakpoints-max, $screen-size) {
|
|
||||||
@media (max-width: map-get($breakpoints-max, $screen-size)) {
|
|
||||||
@content;
|
|
||||||
}
|
|
||||||
} @else {
|
|
||||||
// Debugging
|
|
||||||
@warn "'#{$screen-size}' has not been declared as a breakpoint."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@mixin media-min($screen-size) {
|
|
||||||
@if map-has-key($breakpoints-min, $screen-size) {
|
|
||||||
@media (min-width: map-get($breakpoints-min, $screen-size)) {
|
|
||||||
@content;
|
|
||||||
}
|
|
||||||
} @else {
|
|
||||||
// Debugging
|
|
||||||
@warn "'#{$screen-size}' has not been declared as a breakpoint."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+36
-34
@@ -2,7 +2,6 @@
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
font-size: 14px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*:hover, *:active, *:focus {
|
*:hover, *:active, *:focus {
|
||||||
@@ -11,19 +10,23 @@
|
|||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import "mediaqueries";
|
@import "bourbon";
|
||||||
|
@import "settings/neat";
|
||||||
|
@import "neat";
|
||||||
|
@import "settings/breakpoints";
|
||||||
@import "layout";
|
@import "layout";
|
||||||
@import "colors";
|
@import "colors";
|
||||||
|
|
||||||
$font-family-sans: 'Open Sans', sans-serif;
|
$font-family-sans: 'Open Sans', sans-serif;
|
||||||
|
|
||||||
body {
|
body {
|
||||||
font-family: $font-family-sans;
|
background-image: url('/img/bg.jpg');
|
||||||
font-weight: 300;
|
|
||||||
background-image: linear-gradient(to bottom, rgba(22, 21, 40, .4), rgba(0, 0, 0, .75)), url('/img/bg.jpg');
|
|
||||||
background-repeat: none;
|
background-repeat: none;
|
||||||
background-attachment: fixed;
|
background-attachment: fixed;
|
||||||
color: $body-text-color;
|
font-family: $font-family-sans;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 900px) {
|
@media screen and (min-width: 900px) {
|
||||||
@@ -40,32 +43,26 @@ h1, h2, h3, h4, h5, input, button {
|
|||||||
|
|
||||||
section {
|
section {
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 1.4rem;
|
font-size: 2.8rem;
|
||||||
color: $primary-color;
|
color: $primaryColor;
|
||||||
|
@include media($mobile) {
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&#people {
|
&#contributors {
|
||||||
.content {
|
.content {
|
||||||
p.stats {
|
p.stats {
|
||||||
margin-bottom: 1rem;
|
padding-top: 3rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: white;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
span.number {
|
span.number {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
}
|
@include media($mobile) {
|
||||||
}
|
padding-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
&#contributions-by-type {
|
|
||||||
.chart {
|
|
||||||
width: 50%;
|
|
||||||
margin-left: auto;
|
|
||||||
margin-right: auto;
|
|
||||||
|
|
||||||
@include media-max(small) {
|
|
||||||
width: 75%;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,32 +71,37 @@ section {
|
|||||||
.actions {
|
.actions {
|
||||||
padding-top: 3rem;
|
padding-top: 3rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: $primary-color;
|
color: $primaryColor;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
@include media-max(small) {
|
@include media($mobile) {
|
||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: $primary-color;
|
color: $primaryColor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 550px) {
|
button, input[type=submit] {
|
||||||
section {
|
display: inline-block;
|
||||||
h2 {
|
border: 1px solid rgba(22, 21, 40, 1);
|
||||||
font-size: 2rem;
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
}
|
color: $primaryColor;
|
||||||
|
border-radius: 3px;
|
||||||
|
font-weight: 500;
|
||||||
|
text-transform: uppercase;
|
||||||
|
cursor: pointer;
|
||||||
|
letter-spacing: 0.1em;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(22, 21, 40, 0.8);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@import "buttons";
|
|
||||||
@import "forms";
|
|
||||||
@import "components/topbar";
|
|
||||||
@import "components/loading-spinner";
|
@import "components/loading-spinner";
|
||||||
@import "components/contributor-list";
|
@import "components/contributor-list";
|
||||||
|
@import "components/add-contributor";
|
||||||
@import "components/proposal-list";
|
@import "components/proposal-list";
|
||||||
@import "components/contribution-list";
|
@import "components/contribution-list";
|
||||||
@import "components/user-avatar";
|
|
||||||
|
|||||||
@@ -1,28 +1,20 @@
|
|||||||
section#add-contributor,
|
section#add-contributor, section#add-proposal {
|
||||||
section#add-contribution,
|
|
||||||
section#add-proposal {
|
|
||||||
|
|
||||||
form {
|
form {
|
||||||
|
|
||||||
p {
|
p {
|
||||||
margin-bottom: 1.5rem;
|
margin-bottom: 1rem;
|
||||||
|
|
||||||
&.actions {
|
&.actions {
|
||||||
padding-top: 1.5rem;
|
padding-top: 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
a {
|
a {
|
||||||
color: $primary-color;
|
color: $primaryColor;
|
||||||
margin-left: 1rem;
|
margin-left: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
label {
|
|
||||||
display: block;
|
|
||||||
margin-bottom: 0.5rem;
|
|
||||||
opacity: 0.7;
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=text], select {
|
input[type=text], select {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
@@ -31,22 +23,17 @@ section#add-proposal {
|
|||||||
background-color: rgba(22, 21, 40, 0.3);
|
background-color: rgba(22, 21, 40, 0.3);
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 1.2rem;
|
font-size: 1.2rem;
|
||||||
transition: border-color 0.1s linear;
|
|
||||||
|
|
||||||
&:focus, &.valid {
|
&:focus, &.valid {
|
||||||
background-color: rgba(22, 21, 40, 0.6);
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
}
|
}
|
||||||
&:focus {
|
@include placeholder {
|
||||||
border-color: $blue;
|
|
||||||
}
|
|
||||||
&::placeholder {
|
|
||||||
color: rgba(238, 238, 238, 0.5);
|
color: rgba(238, 238, 238, 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
select {
|
select {
|
||||||
-moz-appearance: none;
|
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
|
-moz-appearance: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
border-radius: 0;
|
border-radius: 0;
|
||||||
background-color: rgba(22, 21, 40, 0.6);
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
@@ -1,70 +1,19 @@
|
|||||||
main section {
|
|
||||||
@include media-max(small) {
|
|
||||||
&#contributions-unconfirmed, &#contributions-confirmed {
|
|
||||||
margin-top: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ul.contribution-list {
|
ul.contribution-list {
|
||||||
clear: both;
|
clear: both;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: grid;
|
// display: block;
|
||||||
grid-template-columns: auto 5rem 5rem;
|
padding: 0 1.2rem;
|
||||||
grid-row-gap: 0.5rem;
|
line-height: 4.2rem;
|
||||||
padding: 0.8rem 1.2rem;
|
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255,255,255,0.1);
|
||||||
font-size: 1.2rem;
|
font-size: 1.4rem;
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.2);
|
border-bottom: 1px solid rgba(255,255,255,0.2);
|
||||||
|
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
border-top: 1px solid rgba(255,255,255,0.2);
|
border-top: 1px solid rgba(255,255,255,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
&.confirmed {
|
|
||||||
grid-template-columns: auto 5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.vetoed {
|
|
||||||
grid-template-columns: auto 5rem;
|
|
||||||
text-decoration: line-through;
|
|
||||||
opacity: 0.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
align-self: center;
|
|
||||||
margin: 0;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: 2rem;
|
|
||||||
|
|
||||||
&.kredits-amount, &.voting {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: inherit;
|
|
||||||
|
|
||||||
&.title {
|
|
||||||
a {
|
|
||||||
font-size: inherit;
|
|
||||||
text-decoration: none;
|
|
||||||
color: $body-text-color;
|
|
||||||
}
|
|
||||||
a:hover, a:active {
|
|
||||||
color: $primary-color;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
line-height: 1.4em;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category {
|
.category {
|
||||||
color: $blue;
|
color: $blue;
|
||||||
padding-right: 0.2rem;
|
padding-right: 0.2rem;
|
||||||
@@ -74,61 +23,17 @@ ul.contribution-list {
|
|||||||
&.docs { color: $green; }
|
&.docs { color: $green; }
|
||||||
&.ops { color: $purple; }
|
&.ops { color: $purple; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.amount {
|
.amount {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.symbol {
|
.symbol {
|
||||||
font-size: 0.8rem;
|
font-size: 1rem;
|
||||||
|
font-weight: 500;
|
||||||
padding-left: 0.2rem;
|
padding-left: 0.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recipient {
|
.recipient {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.votes {
|
|
||||||
font-size: 1rem;
|
|
||||||
color: $primary-color;
|
|
||||||
margin-right: 0.5rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 550px) {
|
|
||||||
ul.proposal-list {
|
|
||||||
li {
|
|
||||||
grid-template-columns: auto 10rem;
|
|
||||||
grid-row-gap: 0.5rem;
|
|
||||||
|
|
||||||
p {
|
|
||||||
&.kredits-amount, &.voting {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.unconfirmed {
|
|
||||||
p {
|
|
||||||
&.kredits-amount, &.voting {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.description {
|
|
||||||
grid-column-start: span 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.voting {
|
|
||||||
grid-column-start: span 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.description {
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
table.contributor-list {
|
table.contributor-list {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
border-collapse: collapse;
|
border-collapse: collapse;
|
||||||
margin-bottom: 1.5rem;
|
|
||||||
|
|
||||||
tr {
|
tr {
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.2);
|
border-bottom: 1px solid rgba(255,255,255,0.2);
|
||||||
@@ -16,18 +15,14 @@ table.contributor-list {
|
|||||||
|
|
||||||
&.metadata {
|
&.metadata {
|
||||||
height: 0;
|
height: 0;
|
||||||
visibility: hidden;
|
transition: all 0.2s ease-out;
|
||||||
|
|
||||||
&:not(.visible) {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
td {
|
td {
|
||||||
padding: 0 1.2rem;
|
padding: 0 1.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
color: $primary-color;
|
color: $primaryColor;
|
||||||
&:hover, &:active {
|
&:hover, &:active {
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
@@ -38,6 +33,7 @@ table.contributor-list {
|
|||||||
display: block;
|
display: block;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
height: 0;
|
height: 0;
|
||||||
|
transition: all 0.2s ease-out;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: inline;
|
display: inline;
|
||||||
@@ -49,7 +45,6 @@ table.contributor-list {
|
|||||||
|
|
||||||
&.visible {
|
&.visible {
|
||||||
height: auto;
|
height: auto;
|
||||||
visibility: visible;
|
|
||||||
ul {
|
ul {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
@@ -58,33 +53,30 @@ table.contributor-list {
|
|||||||
|
|
||||||
td {
|
td {
|
||||||
padding: 0 1.2rem;
|
padding: 0 1.2rem;
|
||||||
line-height: 3.6rem;
|
line-height: 4.2rem;
|
||||||
|
|
||||||
&.person {
|
&.person {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: 1.2rem;
|
font-size: 1.4rem;
|
||||||
|
|
||||||
img.avatar {
|
img.avatar {
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
vertical-align: middle;
|
||||||
margin-right: 0.2rem;
|
margin-right: 0.2rem;
|
||||||
|
border-radius: 1rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.kredits {
|
&.kredits {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
.amount {
|
.amount {
|
||||||
font-size: 1.2rem;
|
font-size: 1.4rem;
|
||||||
font-weight: 500;
|
|
||||||
}
|
}
|
||||||
.symbol {
|
.symbol {
|
||||||
font-size: 0.8rem;
|
font-size: 1rem;
|
||||||
padding-left: 0.2rem;
|
padding-left: 0.2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pre {
|
|
||||||
line-height: 1rem;
|
|
||||||
padding-bottom: 1rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,9 +11,9 @@
|
|||||||
margin-top: 12rem;
|
margin-top: 12rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: 1.4rem;
|
font-size: 1.4rem;
|
||||||
color: $primary-color;
|
color: $primaryColor;
|
||||||
|
|
||||||
@include media-max(small) {
|
@include media($mobile) {
|
||||||
margin-top: 6rem;
|
margin-top: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
|
|
||||||
#path-comet {
|
#path-comet {
|
||||||
fill: $primary-color;
|
fill: $primaryColor;
|
||||||
opacity: 0.1;
|
opacity: 0.1;
|
||||||
|
|
||||||
animation-name: pulse;
|
animation-name: pulse;
|
||||||
|
|||||||
@@ -4,46 +4,16 @@ ul.proposal-list {
|
|||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
display: grid;
|
// display: block;
|
||||||
grid-template-columns: auto 5rem;
|
padding: 0 1.2rem;
|
||||||
grid-row-gap: 0.5rem;
|
line-height: 4.2rem;
|
||||||
padding: 1rem 1.2rem;
|
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255,255,255,0.1);
|
||||||
font-size: 1.2rem;
|
font-size: 1.4rem;
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.2);
|
border-bottom: 1px solid rgba(255,255,255,0.2);
|
||||||
|
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
border-top: 1px solid rgba(255,255,255,0.2);
|
border-top: 1px solid rgba(255,255,255,0.2);
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
|
||||||
align-self: center;
|
|
||||||
margin: 0;
|
|
||||||
font-size: inherit;
|
|
||||||
line-height: 2rem;
|
|
||||||
|
|
||||||
&.kredits-amount, &.voting {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.description {
|
|
||||||
grid-column-start: span 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.voting {
|
|
||||||
grid-column-start: span 2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
span {
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
|
||||||
|
|
||||||
.description {
|
|
||||||
line-height: 1.4em;
|
|
||||||
font-size: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.category {
|
.category {
|
||||||
color: $blue;
|
color: $blue;
|
||||||
padding-right: 0.2rem;
|
padding-right: 0.2rem;
|
||||||
@@ -53,62 +23,30 @@ ul.proposal-list {
|
|||||||
&.docs { color: $green; }
|
&.docs { color: $green; }
|
||||||
&.ops { color: $purple; }
|
&.ops { color: $purple; }
|
||||||
}
|
}
|
||||||
|
|
||||||
.amount {
|
.amount {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.symbol {
|
.symbol {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
padding-left: 0.2rem;
|
padding-left: 0.2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.recipient {
|
.recipient {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
.votes {
|
.votes {
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: $primary-color;
|
color: $primaryColor;
|
||||||
margin-right: 0.5rem;
|
padding-left: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
float: right;
|
||||||
|
margin-top: 1.1rem;
|
||||||
|
height: 2rem;
|
||||||
|
line-height: 2rem;
|
||||||
|
padding: 0 0.6rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (min-width: 550px) {
|
|
||||||
ul.proposal-list {
|
|
||||||
li {
|
|
||||||
grid-template-columns: auto 10rem;
|
|
||||||
grid-row-gap: 0.5rem;
|
|
||||||
|
|
||||||
p {
|
|
||||||
&.kredits-amount, &.voting {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
&.unconfirmed {
|
|
||||||
p {
|
|
||||||
&.kredits-amount, &.voting {
|
|
||||||
text-align: right;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.description {
|
|
||||||
grid-column-start: span 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.voting {
|
|
||||||
grid-column-start: span 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.description {
|
|
||||||
font-size: inherit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
#topbar {
|
|
||||||
padding: 0 1rem;
|
|
||||||
height: 3rem;
|
|
||||||
line-height: 3rem;
|
|
||||||
background-color: rgba(0,0,0,.3);
|
|
||||||
|
|
||||||
@include media-min(medium) {
|
|
||||||
padding: 0 2rem;
|
|
||||||
height: 4rem;
|
|
||||||
line-height: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
display: inline-block;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
section#user-account {
|
|
||||||
display: inline-block;
|
|
||||||
float: right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
img.avatar {
|
|
||||||
width: 2rem;
|
|
||||||
height: 2rem;
|
|
||||||
vertical-align: middle;
|
|
||||||
margin-right: 0.2rem;
|
|
||||||
border-radius: 1rem;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
$mobile: new-breakpoint(max-width 600px);
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// $visual-grid: true;
|
||||||
|
// $visual-grid-color: red;
|
||||||
|
// $visual-grid-index: front;
|
||||||
|
// $visual-grid-opacity: 0.5;
|
||||||
|
$max-width: em(500, 12);
|
||||||
@@ -1,16 +1,3 @@
|
|||||||
<header id="topbar">
|
<main>
|
||||||
<h1>Kosmos Kredits</h1>
|
{{outlet}}
|
||||||
|
</main>
|
||||||
<section id="user-account">
|
|
||||||
{{#if kredits.hasAccounts }}
|
|
||||||
{{#if kredits.currentUser}}
|
|
||||||
{{kredits.currentUser.name}}
|
|
||||||
{{#if kredits.currentUserIsCore}}(core){{/if}}
|
|
||||||
{{/if}}
|
|
||||||
{{else}}
|
|
||||||
Anonymous
|
|
||||||
{{/if}}
|
|
||||||
</section>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
{{outlet}}
|
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
<main class="center-column">
|
|
||||||
|
|
||||||
<section id="add-contribution">
|
|
||||||
<header>
|
|
||||||
<h2>Submit a contribution</h2>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
{{add-contribution contributors=sortedContributors save=(action "save")}}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<main class="center-column">
|
|
||||||
|
|
||||||
<section id="add-contributor">
|
|
||||||
<header>
|
|
||||||
<h2>Update contributor profile</h2>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
{{add-contributor attributes=attributes save=(action "save")}}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
<main class="center-column">
|
|
||||||
|
|
||||||
<section id="add-contributor">
|
|
||||||
<header>
|
|
||||||
<h2>Add contributor profile</h2>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
{{add-contributor save=(action "save")}}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
+48
-62
@@ -1,69 +1,55 @@
|
|||||||
<main id="index">
|
<section id="contributors">
|
||||||
|
<header>
|
||||||
|
<h2>Kosmos Contributors</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
<div id="stats">
|
<div class="content">
|
||||||
<section id="people">
|
{{contributor-list contributors=contributorsSorted}}
|
||||||
<header class="with-nav">
|
|
||||||
<h2>Contributors</h2>
|
|
||||||
{{#if kredits.hasAccounts}}
|
|
||||||
<nav>
|
|
||||||
{{link-to "add" "contributors.new" title="Add contributor profile" class="button small green"}}
|
|
||||||
</nav>
|
|
||||||
{{/if}}
|
|
||||||
</header>
|
|
||||||
<div class="content">
|
|
||||||
{{contributor-list contributorList=kreditsToplist
|
|
||||||
showUnconfirmedKredits=showUnconfirmedKredits}}
|
|
||||||
|
|
||||||
<p class="stats">
|
<p class="stats">
|
||||||
<span class="number">{{await kredits.totalKreditsEarned}}</span> kredits confirmed and issued to
|
<span class="number">{{model.totalSupply}}</span> kredits issued and distributed among
|
||||||
<span class="number">{{contributorsWithKredits.length}}</span> contributors
|
<span class="number">{{contributorsWithKredits.length}}</span> contributors.
|
||||||
</p>
|
</p>
|
||||||
<p class="stats">
|
|
||||||
{{input type="checkbox" id="hide-unnconfirmed-kredits" checked=showUnconfirmedKredits}}
|
|
||||||
<label for="hide-unnconfirmed-kredits">Show unconfirmed kredits in toplist</label>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section id="contributions-by-type">
|
|
||||||
<header>
|
|
||||||
<h2>Contributions by type</h2>
|
|
||||||
</header>
|
|
||||||
<div class="content">
|
|
||||||
{{chart-contributions-by-type contributions=contributions}}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
<div id="contributions">
|
{{#if proposalsOpen}}
|
||||||
{{#if contributionsUnconfirmed}}
|
<section id="proposals-open">
|
||||||
<section id="contributions-unconfirmed">
|
<header>
|
||||||
<header class="with-nav">
|
<h2>Open Proposals</h2>
|
||||||
<h2>Latest Contributions</h2>
|
</header>
|
||||||
{{#if kredits.hasAccounts}}
|
<div class="content">
|
||||||
<nav>
|
{{proposal-list proposals=proposalsOpenSorted
|
||||||
{{link-to "add" "contributions.new" title="Submit a contribution" class="button small green"}}
|
confirmAction="confirmProposal"
|
||||||
</nav>
|
contractInteractionEnabled=contractInteractionEnabled}}
|
||||||
{{/if}}
|
|
||||||
</header>
|
|
||||||
<div class="content">
|
|
||||||
{{!-- TODO: We need a better naming for kredits.hasAccounts --}}
|
|
||||||
{{contribution-list contributions=contributionsUnconfirmedSorted
|
|
||||||
vetoContribution=(action "vetoContribution")
|
|
||||||
contractInteractionEnabled=kredits.hasAccounts}}
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
{{/if}}
|
|
||||||
|
|
||||||
<section id="contributions-confirmed">
|
{{#if contractInteractionEnabled}}
|
||||||
<header>
|
<p class="actions">
|
||||||
<h2>Confirmed Contributions</h2>
|
{{#link-to 'proposals.new'}}Create new proposal{{/link-to}}
|
||||||
</header>
|
</p>
|
||||||
<div class="content">
|
{{/if}}
|
||||||
{{contribution-list contributions=contributionsConfirmedSorted
|
</div>
|
||||||
vetoContribution=(action "vetoContribution")}}
|
</section>
|
||||||
</div>
|
{{/if}}
|
||||||
</section>
|
|
||||||
|
<section id="contributions">
|
||||||
|
<header>
|
||||||
|
<h2>Contributions</h2>
|
||||||
|
</header>
|
||||||
|
<div class="content">
|
||||||
|
{{contribution-list contributions=model.contributions
|
||||||
|
contributors=model.contributors}}
|
||||||
</div>
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
</main>
|
<section id="add-contributor">
|
||||||
|
<header>
|
||||||
|
<h2>Add Contributor</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
{{add-contributor contributors=model.contributors
|
||||||
|
newContributor=model.newContributor
|
||||||
|
contractInteractionEnabled=contractInteractionEnabled}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
</header>
|
</header>
|
||||||
|
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{{add-proposal contributors=minedContributors save=(action "save")}}
|
{{add-proposal proposal=model contributors=contributors onSave=(action 'onSave')}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{{loading-spinner}}
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
import { computed } from '@ember/object';
|
|
||||||
import ethers from 'npm:ethers';
|
|
||||||
|
|
||||||
export default function(dependentKey, converterMethod) {
|
|
||||||
return computed(dependentKey, {
|
|
||||||
get () {
|
|
||||||
let value = this.get(dependentKey);
|
|
||||||
if (value && ethers.utils.BigNumber.isBigNumber(value)) {
|
|
||||||
return value[converterMethod]();
|
|
||||||
} else {
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
set (key, value) {
|
|
||||||
const bnValue = ethers.utils.bigNumberify(value);
|
|
||||||
this.set(dependentKey, bnValue);
|
|
||||||
return bnValue[converterMethod]();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
import { computed } from '@ember/object';
|
|
||||||
import ethers from 'npm:ethers';
|
|
||||||
import formatKredits from 'kredits-web/utils/format-kredits';
|
|
||||||
|
|
||||||
export default function(dependentKey, options = {}) {
|
|
||||||
return computed(dependentKey, {
|
|
||||||
get () {
|
|
||||||
const value = this.get(dependentKey);
|
|
||||||
return formatKredits(value, options);
|
|
||||||
},
|
|
||||||
set (key, value) {
|
|
||||||
const bnValue = ethers.utils.bigNumberify(value);
|
|
||||||
this.set(dependentKey, bnValue);
|
|
||||||
return formatKredits(bnValue, options);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import ethers from 'npm:ethers';
|
|
||||||
|
|
||||||
export default function(value, options = {}) {
|
|
||||||
let etherValue = ethers.utils.formatEther(value);
|
|
||||||
if (!options.decimals) {
|
|
||||||
etherValue = parseInt(etherValue).toString();
|
|
||||||
}
|
|
||||||
return etherValue;
|
|
||||||
}
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
//
|
|
||||||
// Code from https://github.com/HeroicEric/ember-group-by (MIT licensed)
|
|
||||||
//
|
|
||||||
import { A } from '@ember/array';
|
|
||||||
import { get } from '@ember/object';
|
|
||||||
import { isPresent } from '@ember/utils';
|
|
||||||
|
|
||||||
export default function groupBy (collection, property) {
|
|
||||||
let groups = A();
|
|
||||||
let items = collection;
|
|
||||||
|
|
||||||
if (items) {
|
|
||||||
items.forEach(function(item) {
|
|
||||||
let value = get(item, property);
|
|
||||||
let group = groups.findBy('value', value);
|
|
||||||
|
|
||||||
if (isPresent(group)) {
|
|
||||||
get(group, 'items').push(item);
|
|
||||||
} else {
|
|
||||||
group = { property: property, value: value, items: [item] };
|
|
||||||
groups.push(group);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
return groups;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "kredits-web",
|
||||||
|
"dependencies": {
|
||||||
|
"ember": "~2.10.0",
|
||||||
|
"ember-cli-shims": "0.1.3",
|
||||||
|
"bourbon": "^4.2.7",
|
||||||
|
"neat": "^1.8.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
-20
@@ -1,11 +1,10 @@
|
|||||||
/* jshint node: true */
|
/* jshint node: true */
|
||||||
'use strict';
|
const fs = require('fs');
|
||||||
|
|
||||||
module.exports = function(environment) {
|
module.exports = function(environment) {
|
||||||
|
var ENV = {
|
||||||
let ENV = {
|
|
||||||
modulePrefix: 'kredits-web',
|
modulePrefix: 'kredits-web',
|
||||||
environment,
|
environment: environment,
|
||||||
rootURL: '/',
|
rootURL: '/',
|
||||||
locationType: 'auto',
|
locationType: 'auto',
|
||||||
|
|
||||||
@@ -35,7 +34,9 @@ module.exports = function(environment) {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
web3ProviderUrl: 'https://rinkeby.infura.io/v3/d4f788b7a6584f7db2fc3c268d4d09e9',
|
contractMetadata: {},
|
||||||
|
|
||||||
|
web3ProviderUrl: 'https://parity.kosmos.org:8545',
|
||||||
|
|
||||||
ipfs: {
|
ipfs: {
|
||||||
host: 'ipfs.kosmos.org',
|
host: 'ipfs.kosmos.org',
|
||||||
@@ -44,19 +45,30 @@ module.exports = function(environment) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (process.env.KREDITS_CONTRACT_ADDR) {
|
||||||
|
ENV.contractMetadata['Kredits'] = { address: process.env.KREDITS_CONTRACT_ADDR };
|
||||||
|
}
|
||||||
|
if (process.env.TOKEN_CONTRACT_ADDR) {
|
||||||
|
ENV.contractMetadata['Token'] = { address: process.env.TOKEN_CONTRACT_ADDR };
|
||||||
|
}
|
||||||
|
if (process.env.WEB3_PROVIDER_URL) {
|
||||||
|
ENV.web3ProviderUrl = process.env.WEB3_PROVIDER_URL;
|
||||||
|
}
|
||||||
|
ENV.contractMetadata['networkId'] = "17";
|
||||||
|
|
||||||
if (environment === 'development') {
|
if (environment === 'development') {
|
||||||
// ENV.APP.LOG_RESOLVER = true;
|
// ENV.APP.LOG_RESOLVER = true;
|
||||||
// ENV.APP.LOG_ACTIVE_GENERATION = true;
|
// ENV.APP.LOG_ACTIVE_GENERATION = true;
|
||||||
// ENV.APP.LOG_TRANSITIONS = true;
|
// ENV.APP.LOG_TRANSITIONS = true;
|
||||||
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
|
// ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
|
||||||
// ENV.APP.LOG_VIEW_LOOKUPS = true;
|
// ENV.APP.LOG_VIEW_LOOKUPS = true;
|
||||||
ENV.web3ProviderUrl = 'https://rinkeby.infura.io/v3/d4f788b7a6584f7db2fc3c268d4d09e9';
|
|
||||||
|
|
||||||
ENV.ipfs = {
|
ENV.ipfs = {
|
||||||
host: 'localhost',
|
host: 'localhost',
|
||||||
port: '5001',
|
port: '5001',
|
||||||
protocol: 'http'
|
protocol: 'http'
|
||||||
};
|
};
|
||||||
|
const mintedEvents = JSON.parse(fs.readFileSync('config/fixtures-token-minted.json'));
|
||||||
|
ENV.fixtures = { mintedEvents: mintedEvents };
|
||||||
}
|
}
|
||||||
|
|
||||||
if (environment === 'test') {
|
if (environment === 'test') {
|
||||||
@@ -68,22 +80,9 @@ module.exports = function(environment) {
|
|||||||
ENV.APP.LOG_VIEW_LOOKUPS = false;
|
ENV.APP.LOG_VIEW_LOOKUPS = false;
|
||||||
|
|
||||||
ENV.APP.rootElement = '#ember-testing';
|
ENV.APP.rootElement = '#ember-testing';
|
||||||
ENV.APP.autoboot = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (environment === 'production') {
|
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;
|
|
||||||
}
|
|
||||||
if (process.env.KREDITS_KERNEL_ADDRESS) {
|
|
||||||
ENV.kreditsKernelAddress = process.env.KREDITS_KERNEL_ADDRESS;
|
|
||||||
}
|
|
||||||
if (process.env.KREDITS_APM_DOMAIN) {
|
|
||||||
ENV.kreditsApmDomain = process.env.KREDITS_APM_DOMAIN;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ENV;
|
return ENV;
|
||||||
|
|||||||
@@ -0,0 +1,291 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0x70ba4415fc788d9481b5c2e557a55ce698de15b02eb5fba514a0b33027796c5a",
|
||||||
|
"blockNumber": 46,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x3d4baea1f8a63f5b80491d5e67f2a833a4a6db7427a0c07ca181a852cd29dedb",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xd4a64570b12da659ee4bbd41c3509b7b1f9c51ac",
|
||||||
|
"contributorId": 1,
|
||||||
|
"amount": "150",
|
||||||
|
"reference": "QmWj7XC6sSu1D7zmcH1tHFV9711P96m1z4qFP8yALZMWem"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0x0112ca39f27dbc17ec7478336a9ba63ede0930cad0ead68b6fd441269950d6cc",
|
||||||
|
"blockNumber": 47,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x8d1277270c51afdb9b6345015de176260412d7a649dfb00307dc8e7c513a250e",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xd4a64570b12da659ee4bbd41c3509b7b1f9c51ac",
|
||||||
|
"contributorId": 2,
|
||||||
|
"amount": "150",
|
||||||
|
"reference": "QmSfgMxbBHNouW9vwD8DHkfdbMjAuMpv1fpBB6uPCazRCA"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0x98fc834495394b8b26520fcd503508b953f7977a89df49a2a2d6711f2aa4d0c6",
|
||||||
|
"blockNumber": 48,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x8f21b1df6ea33520c437bf9252a611603f52dca397ba93a3e2680da2c31d28e1",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xf18e631ea191ae4ebe70046fcb01a43655441c6d",
|
||||||
|
"contributorId": 1,
|
||||||
|
"amount": "1000",
|
||||||
|
"reference": "QmNbmsh3Rozksv6a5cTQM5mapQNpksU4Zcy9zMLcWsJoUf"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0xf34ce94de4496441cb3972525f4010370b6957bbc09deba15501a169d063fa59",
|
||||||
|
"blockNumber": 50,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x328ffbe2b34ba80c861445768b6069bc43eb511e196e7c22042a1f714aad78fa",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xd4a64570b12da659ee4bbd41c3509b7b1f9c51ac",
|
||||||
|
"contributorId": 3,
|
||||||
|
"amount": "150",
|
||||||
|
"reference": "QmYE2ipsfbk9fwLJQ5wBrc9WKtneHjEGfV2RfngsxdKe1g"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0xf6f8c1686497c7dc0ae4af2c87d7547b75bdffb960dce52a62bf74c1976980fb",
|
||||||
|
"blockNumber": 51,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x694796b4b1bd82cadea6471eb2f718323ca85fed00ddb9b8a73524dec31141e6",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xd4a64570b12da659ee4bbd41c3509b7b1f9c51ac",
|
||||||
|
"contributorId": 2,
|
||||||
|
"amount": "50",
|
||||||
|
"reference": "QmZZVbZN6hQTA5ZxrUywehdC2cCHkD6wvkVbVWJP21UmgR"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0x771045eecdd57959e9cb9ac613df988eeee8b800e8f9edebfdf01a8f1a4f3c5d",
|
||||||
|
"blockNumber": 52,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0xaf9f073f80b8b492a7e822cfd38e5d13474a99aaef9be0c3bc0ffaf8c653a5f4",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xf18e631ea191ae4ebe70046fcb01a43655441c6d",
|
||||||
|
"contributorId": 1,
|
||||||
|
"amount": "50",
|
||||||
|
"reference": "QmbrszXGexzCZaWer6nFxjj4EXp5y4WT3WYPrbeNooQMyy"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0x86ee58b0e36f3d199b0d241f3efb868a7276fdf084cff48ef045bdfe235c0506",
|
||||||
|
"blockNumber": 53,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x9c7076b2fa49988fe706639376413bc79e4c5549c0145f00d7f27af6088c7128",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xf18e631ea191ae4ebe70046fcb01a43655441c6d",
|
||||||
|
"contributorId": 1,
|
||||||
|
"amount": "150",
|
||||||
|
"reference": "QmV5wSKLRBdXXbRuxWneQ1tDZP75Dpjv3adQHGye8CemEb"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0xc2b3f860e0b8d4037529eca9b7d539332b3cc08741165378ac8368c22c6a18b3",
|
||||||
|
"blockNumber": 54,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0xfd2f5439e265e8899be5e2e18a9df56f4706e618d5459aa8f206aec091f7c0d9",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0x805bf817be0e53bf618eb41ae0775ac314f989a1",
|
||||||
|
"contributorId": 2,
|
||||||
|
"amount": "50",
|
||||||
|
"reference": "QmNp6ggpaR3yNuEWZbCttnUBjshQonFWE766iyVLAKfq7M"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0x860667b8f67ae22ac97bd67d9ccb245eb98312eb5cb22303d1a8a383defbb5fc",
|
||||||
|
"blockNumber": 60,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0xbe153f64a31a1669ef1bffa16b0aeb1657b1b9fe779c38f6455d05fe3d96fd5b",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0x805bf817be0e53bf618eb41ae0775ac314f989a1",
|
||||||
|
"contributorId": 1,
|
||||||
|
"amount": "50",
|
||||||
|
"reference": "QmY2eBgBtFir4edYbw91KQNidMNHnCCem2LCJpTJ56Q87U"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0x2c5da053f98cb5462a8aa4fa6bb2a5e7bb324baa404fbbd8ea25fdaaaac1b0db",
|
||||||
|
"blockNumber": 65,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x1df5a2819a6312d170c323b517b03a7186a789845ecfe896d37de6fa482b924c",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0x805bf817be0e53bf618eb41ae0775ac314f989a1",
|
||||||
|
"contributorId": 3,
|
||||||
|
"amount": "50",
|
||||||
|
"reference": "QmeVbzGiXmPz4qgi5PfktZi2Esb4EVPQZLRnWnUPVatJgF"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0x0e478ae9cf6e09e2ca8c4413c874f39decfb9d51c976467ef14d99efa79c9bcb",
|
||||||
|
"blockNumber": 75,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0xf16ace4f72c599c3b738bdaa4518f59a47dcdc304a8f24308c5d121ae0ae5b97",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0x0536806df512d6cdde913cf95c9886f65b1d3462",
|
||||||
|
"contributorId": 1,
|
||||||
|
"amount": "100",
|
||||||
|
"reference": "QmS3cywqGhHh6QBLnyBWXPTas2UnHEW8ZV8zZy6pVw95Zx"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0x31e91da869e9b87949e75ee14879005b172df96267f9ffd76d5024a46fe48a3c",
|
||||||
|
"blockNumber": 76,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x735eb48c81f6868b886d3afede6b031323e78b221f3e2653ad2186c3e4e1abe9",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xd4a64570b12da659ee4bbd41c3509b7b1f9c51ac",
|
||||||
|
"contributorId": 2,
|
||||||
|
"amount": "500",
|
||||||
|
"reference": "QmP5RPzjgRdtq9Uj6tXxgMfA1GkY9Fh5ghXpDYBtc9YwMp"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0xd41a4c3caae9e52632eba047d038e430b50920138e3a625b50a0a887e719a487",
|
||||||
|
"blockNumber": 77,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x075beb007d18b38344599fe5b4dc315633aebedf08201ab9537f7d407811b0a2",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0x805bf817be0e53bf618eb41ae0775ac314f989a1",
|
||||||
|
"contributorId": 2,
|
||||||
|
"amount": "1000",
|
||||||
|
"reference": "QmTxwugByKfyPX2czyVDGhXK3NLZkA3uh2DbNnaAMVrVJB"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0xcb3863eb681873a2c5954e07e085d4004a2824fcd17364b647e2fff1bea3ad4b",
|
||||||
|
"blockNumber": 78,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0xdf680c7a0bc60ef02619def582f68230bdd0fd8a945c9006841212ebcd6b80db",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xf18e631ea191ae4ebe70046fcb01a43655441c6d",
|
||||||
|
"contributorId": 3,
|
||||||
|
"amount": "300",
|
||||||
|
"reference": "QmYXyGSK6RyXQHNPHAADjpJ4P3mrz5Lf1bNnrp2yRaDxNo"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0xe322d5292506ef1c4c915e875a4e8c1882d154fd9b711522809045bbb884e11d",
|
||||||
|
"blockNumber": 89,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x5d90bf8c74b18b602e8b04fbca8678033589f6527b1ced08c0ee7d6c96f71949",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xb2d955733e6a470533f68f72d0af442070f24f55",
|
||||||
|
"contributorId": 1,
|
||||||
|
"amount": "300",
|
||||||
|
"reference": "QmZdUuq4NMz2S5bD3m9h9MNNsbTVeFVHzQss4uS1ZqPLsw"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0xbb84cfc9c3298b045d4ae70afa9cc966db578b00e897f3d6988b08deeca0e3d9",
|
||||||
|
"blockNumber": 120,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0xf91a038b17cfd9b5eac8f4474d5e4d9a5034dead51fc2fffc9e88afdefd9129c",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0xf18e631ea191ae4ebe70046fcb01a43655441c6d",
|
||||||
|
"contributorId": 1,
|
||||||
|
"amount": "500",
|
||||||
|
"reference": "QmdQWivxwjuEHEYVu3ezZCzEWps6wEvQ8ePUHbQ7htSN8V"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"address": "0x63770f81fbe0d2b4159b6752eda99ee7c44ca5e4",
|
||||||
|
"blockHash": "0xc85a520ffc16b5f84d5f5bd29478d0871a045356e598c72be9a44ae3e6826bb5",
|
||||||
|
"blockNumber": 121,
|
||||||
|
"logIndex": 0,
|
||||||
|
"transactionHash": "0x59a2e3e1f81b8113b3b71eba26f28f75ba18d60b6dda6a4a216d566d7d68a31d",
|
||||||
|
"transactionIndex": 0,
|
||||||
|
"transactionLogIndex": "0x0",
|
||||||
|
"type": "mined",
|
||||||
|
"event": "Minted",
|
||||||
|
"args": {
|
||||||
|
"recipientAddress": "0x805bf817be0e53bf618eb41ae0775ac314f989a1",
|
||||||
|
"contributorId": 1,
|
||||||
|
"amount": "50",
|
||||||
|
"reference": "QmfDG3vCAgQsqkxkb6jCnLqw11wjw3uUpiZRbRBLZ9GpYi"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
{
|
|
||||||
"jquery-integration": true
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
'use strict';
|
|
||||||
|
|
||||||
const browsers = [
|
|
||||||
'last 1 Chrome versions',
|
|
||||||
'last 1 Firefox versions',
|
|
||||||
'last 1 Safari versions'
|
|
||||||
];
|
|
||||||
|
|
||||||
const isCI = !!process.env.CI;
|
|
||||||
const isProduction = process.env.EMBER_ENV === 'production';
|
|
||||||
|
|
||||||
if (isCI || isProduction) {
|
|
||||||
browsers.push('ie 11');
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = {
|
|
||||||
browsers
|
|
||||||
};
|
|
||||||
+10
-12
@@ -1,17 +1,15 @@
|
|||||||
'use strict';
|
/*jshint node:true*/
|
||||||
|
/* global require, module */
|
||||||
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
|
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
|
||||||
|
|
||||||
module.exports = function(defaults) {
|
module.exports = function(defaults) {
|
||||||
let app = new EmberApp(defaults, {
|
var app = new EmberApp(defaults, {
|
||||||
// sassOptions: {
|
// Add options here
|
||||||
// includePaths: [
|
sassOptions: {
|
||||||
// 'node_modules/bourbon/app/assets/stylesheets'
|
includePaths: [
|
||||||
// ]
|
'bower_components/bourbon/app/assets/stylesheets',
|
||||||
// },
|
'bower_components/neat/app/assets/stylesheets'
|
||||||
sourcemaps: {
|
]
|
||||||
enabled: true,
|
|
||||||
extensions: ['js']
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
{
|
|
||||||
"node": true,
|
|
||||||
"browser": false
|
|
||||||
}
|
|
||||||
Generated
-20098
File diff suppressed because it is too large
Load Diff
+49
-50
@@ -1,70 +1,69 @@
|
|||||||
{
|
{
|
||||||
"name": "kredits-web",
|
"name": "kredits-web",
|
||||||
"version": "1.2.0",
|
"version": "1.0.0",
|
||||||
"private": true,
|
|
||||||
"description": "Contribution dashboard of the Kosmos project",
|
"description": "Contribution dashboard of the Kosmos project",
|
||||||
"repository": "https://github.com/67P/kredits-web",
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "Kosmos Contributors <mail@kosmos.org>",
|
"author": "Kosmos Contributors <mail@kosmos.org>",
|
||||||
|
"contributors": [
|
||||||
|
"Garret Alfert <alfert@wevelop.de>",
|
||||||
|
"Sebastian Kippe <sebastian@kip.pe>",
|
||||||
|
"Michael Bumann <hello@michaelbumann.com>"
|
||||||
|
],
|
||||||
"directories": {
|
"directories": {
|
||||||
"doc": "doc",
|
"doc": "doc",
|
||||||
"test": "tests"
|
"test": "tests"
|
||||||
},
|
},
|
||||||
|
"repository": "https://github.com/67P/kredits-web",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"lint:hbs": "ember-template-lint .",
|
"start": "ember server",
|
||||||
"lint:js": "eslint .",
|
"start-local": "WEB3_PROVIDER_URL=http://localhost:8545 KREDITS_PROVIDER_URL=http://localhost:8545 KREDITS_CONTRACT_ADDR=`kredits-inspect -c Kredits -r -w address` TOKEN_CONTRACT_ADDR=`kredits-inspect -c Token -r -w address` npm start",
|
||||||
"test": "ember test",
|
"test": "ember test",
|
||||||
"start": "KREDITS_APM_DOMAIN=open.aragonpm.eth ember serve",
|
"postinstall": "bower install",
|
||||||
"start:local": "WEB3_PROVIDER_URL=http://localhost:7545 ember s",
|
|
||||||
"build": "ember build",
|
"build": "ember build",
|
||||||
"build-prod": "rm -rf release/* && ember build -prod --output-path release",
|
"build-prod": "ember build --environment production",
|
||||||
"preversion": "npm test",
|
"update-version-file": "bash scripts/update-version-file.sh",
|
||||||
"version": "npm run build-prod && git add release/",
|
"deploy": "npm run build-prod && npm run update-version-file && bash scripts/deploy.sh",
|
||||||
"postversion": "git push origin master",
|
"kredits-console": "kredits-console",
|
||||||
"deploy": "git push 5apps master"
|
"kredits-parity": "kredits-parity",
|
||||||
|
"kredits-deploy": "kredits-deploy",
|
||||||
|
"kredits-inspect": "kredits-inspect",
|
||||||
|
"kredits-seed": "kredits-seed"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ember/jquery": "^0.5.2",
|
|
||||||
"@ember/optional-features": "^0.6.3",
|
|
||||||
"babel-preset-es2015": "^6.22.0",
|
"babel-preset-es2015": "^6.22.0",
|
||||||
"babelify": "^7.3.0",
|
"babelify": "^7.3.0",
|
||||||
"broccoli-asset-rev": "^2.7.0",
|
"broccoli-asset-rev": "^2.4.5",
|
||||||
"ember-ajax": "^4.0.1",
|
"ember-ajax": "^2.4.1",
|
||||||
"ember-awesome-macros": "0.41.0",
|
|
||||||
"ember-browserify": "^1.1.13",
|
"ember-browserify": "^1.1.13",
|
||||||
"ember-cli": "~3.8.1",
|
"ember-cli": "2.10.0",
|
||||||
"ember-cli-app-version": "^3.2.0",
|
"ember-cli-app-version": "^2.0.0",
|
||||||
"ember-cli-babel": "^7.1.2",
|
"ember-cli-babel": "^5.1.7",
|
||||||
"ember-cli-chart": "^3.4.0",
|
"ember-cli-dependency-checker": "^1.3.0",
|
||||||
"ember-cli-dependency-checker": "^3.1.0",
|
"ember-cli-htmlbars": "^1.0.10",
|
||||||
"ember-cli-eslint": "^4.2.3",
|
"ember-cli-htmlbars-inline-precompile": "^0.3.3",
|
||||||
"ember-cli-htmlbars": "^3.0.0",
|
"ember-cli-inject-live-reload": "^1.4.1",
|
||||||
"ember-cli-htmlbars-inline-precompile": "^1.0.3",
|
"ember-cli-jshint": "^2.0.1",
|
||||||
"ember-cli-inject-live-reload": "^1.8.2",
|
"ember-cli-qunit": "^3.0.1",
|
||||||
"ember-cli-sass": "^7.2.0",
|
"ember-cli-release": "^0.2.9",
|
||||||
"ember-cli-sri": "^2.1.1",
|
"ember-cli-sass": "^7.0.0",
|
||||||
"ember-cli-template-lint": "^1.0.0-beta.1",
|
"ember-cli-sri": "^2.1.0",
|
||||||
"ember-cli-uglify": "^2.1.0",
|
"ember-cli-test-loader": "^1.1.0",
|
||||||
"ember-cli-update": "^0.21.2",
|
"ember-cli-uglify": "^1.2.0",
|
||||||
"ember-export-application-global": "^2.0.0",
|
"ember-export-application-global": "^1.0.5",
|
||||||
"ember-flatpickr": "^2.14.0",
|
"ember-load-initializers": "^0.5.1",
|
||||||
"ember-load-initializers": "^1.1.0",
|
"ember-parachute": "0.1.0",
|
||||||
"ember-macro-helpers": "0.17.0",
|
"ember-resolver": "^2.0.3",
|
||||||
"ember-maybe-import-regenerator": "^0.1.6",
|
"ember-truth-helpers": "1.3.0",
|
||||||
"ember-promise-helpers": "1.0.6",
|
"ipfs-api": "^12.1.7",
|
||||||
"ember-qunit": "^3.4.1",
|
"kosmos-schemas": "~1.1.2",
|
||||||
"ember-resolver": "^5.0.1",
|
"kredits-contracts": "^2.4.0",
|
||||||
"ember-source": "~3.8.0",
|
"loader.js": "^4.0.10",
|
||||||
"ember-truth-helpers": "github:jmurphyau/ember-truth-helpers#31a14373a31f1f82c77537720549b47a95c28e5f",
|
"tv4": "^1.3.0",
|
||||||
"eslint-plugin-ember": "^5.2.0",
|
"uuid": "^3.0.1",
|
||||||
"ethers": "^4.0.27",
|
"web3": "^0.18.2"
|
||||||
"kosmos-schemas": "^2.0.0",
|
|
||||||
"kredits-contracts": "^5.3.0",
|
|
||||||
"loader.js": "^4.7.0",
|
|
||||||
"qunit-dom": "^0.8.0",
|
|
||||||
"tv4": "^1.3.0"
|
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": "8.* || >= 10.*"
|
"node": ">= 0.12.0"
|
||||||
}
|
},
|
||||||
|
"private": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,15 @@
|
|||||||
|
<?xml version="1.0"?>
|
||||||
|
<!DOCTYPE cross-domain-policy SYSTEM "http://www.adobe.com/xml/dtds/cross-domain-policy.dtd">
|
||||||
|
<cross-domain-policy>
|
||||||
|
<!-- Read this: www.adobe.com/devnet/articles/crossdomain_policy_file_spec.html -->
|
||||||
|
|
||||||
|
<!-- Most restrictive policy: -->
|
||||||
|
<site-control permitted-cross-domain-policies="none"/>
|
||||||
|
|
||||||
|
<!-- Least restrictive policy: -->
|
||||||
|
<!--
|
||||||
|
<site-control permitted-cross-domain-policies="all"/>
|
||||||
|
<allow-access-from domain="*" to-ports="*" secure="false"/>
|
||||||
|
<allow-http-request-headers-from domain="*" headers="*" secure="false"/>
|
||||||
|
-->
|
||||||
|
</cross-domain-policy>
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,190 +0,0 @@
|
|||||||
"use strict"
|
|
||||||
define("kredits-web/app",["exports","kredits-web/resolver","ember-load-initializers","kredits-web/config/environment"],function(e,t,n,r){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var i=Ember.Application.extend({modulePrefix:r.default.modulePrefix,podModulePrefix:r.default.podModulePrefix,Resolver:t.default});(0,n.default)(i,r.default.modulePrefix)
|
|
||||||
var o=i
|
|
||||||
e.default=o}),define("kredits-web/components/add-contribution/component",["exports"],function(e){function t(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,o=void 0
|
|
||||||
try{for(var s,u=e[Symbol.iterator]();!(r=(s=u.next()).done)&&(n.push(s.value),!t||n.length!==t);r=!0);}catch(a){i=!0,o=a}finally{try{r||null==u.return||u.return()}finally{if(i)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var n=Ember.Component.extend({attributes:null,contributors:Object.freeze([]),isValidContributor:Ember.computed.notEmpty("contributorId"),isValidKind:Ember.computed.notEmpty("kind"),isValidAmount:Ember.computed("amount",function(){return parseInt(this.amount,10)>0}),isValidDescription:Ember.computed.notEmpty("description"),isValidUrl:Ember.computed.notEmpty("url"),isValid:Ember.computed.and("isValidContributor","isValidKind","isValidAmount","isValidDescription"),init:function(){this._super.apply(this,arguments),this.set("defaultDate",new Date),this.set("attributes",{contributorId:null,kind:null,date:[new Date],amount:null,description:null,url:null}),this.reset()},reset:function(){this.setProperties(this.attributes)},actions:{submit:function(){var e=this
|
|
||||||
if(this.isValid){var n=this.getProperties(Object.keys(this.attributes)),r=t(n.date[0].toISOString().split("T"),1)[0]
|
|
||||||
n.date=r,this.set("inProgress",!0),this.save(n).then(function(){e.reset()},function(e){console.warn(e),window.alert("Something went wrong. Check the browser console for details.")}).finally(function(){return e.set("inProgress",!1)})}else alert("Invalid data. Please review and try again.")}}})
|
|
||||||
e.default=n}),define("kredits-web/components/add-contribution/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"U4IJj1aB",block:'{"symbols":["contributor"],"statements":[[7,"form"],[9],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["contributorId"]]],null]],[["value"],["target.value"]]]],[9],[0,"\\n "],[7,"option"],[11,"value",""],[11,"selected",""],[11,"disabled",""],[11,"hidden",""],[9],[0,"Contributor"],[10],[0,"\\n"],[4,"each",[[23,["contributors"]]],null,{"statements":[[0," "],[7,"option"],[12,"value",[22,1,["id"]]],[12,"selected",[27,"eq",[[23,["contributorId"]],[22,1,["id"]]],null]],[9],[1,[22,1,["name"]],false],[10],[0,"\\n"]],"parameters":[1]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["kind"]]],null]],[["value"],["target.value"]]]],[9],[0,"\\n "],[7,"option"],[11,"value",""],[11,"selected",""],[11,"disabled",""],[11,"hidden",""],[9],[0,"Kind"],[10],[0,"\\n "],[7,"option"],[11,"value","community"],[12,"selected",[27,"eq",[[23,["kind"]],"community"],null]],[9],[0,"Community"],[10],[0,"\\n "],[7,"option"],[11,"value","design"],[12,"selected",[27,"eq",[[23,["kind"]],"design"],null]],[9],[0,"Design"],[10],[0,"\\n "],[7,"option"],[11,"value","dev"],[12,"selected",[27,"eq",[[23,["kind"]],"dev"],null]],[9],[0,"Development"],[10],[0,"\\n "],[7,"option"],[11,"value","docs"],[12,"selected",[27,"eq",[[23,["kind"]],"docs"],null]],[9],[0,"Documentation"],[10],[0,"\\n "],[7,"option"],[11,"value","ops"],[12,"selected",[27,"eq",[[23,["kind"]],"ops"],null]],[9],[0,"IT Operations"],[10],[0,"\\n "],[7,"option"],[11,"value","special"],[12,"selected",[27,"eq",[[23,["kind"]],"special"],null]],[9],[0,"Special"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"ember-flatpickr",null,[["allowInput","altFormat","altInput","altInputClass","date","dateFormat","defaultDate","maxDate","onChange"],[false,"F j, Y",true,"date-alt",[23,["date"]],"Y-m-d",[23,["defaultDate"]],[23,["defaultDate"]],[27,"action",[[22,0,[]],[27,"mut",[[23,["date"]]],null]],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","500",[23,["amount"]],[27,"if",[[23,["isValidAmount"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","Description",[23,["description"]],[27,"if",[[23,["isValidDescription"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","URL (optional)",[23,["url"]],[27,"if",[[23,["isValidUrl"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","actions"],[9],[0,"\\n "],[1,[27,"input",null,[["type","disabled","value"],["submit",[23,["inProgress"]],[27,"if",[[23,["inProgress"]],"Processing","Save"],null]]]],false],[0,"\\n "],[10],[0,"\\n"],[3,"action",[[22,0,[]],"submit"],[["on"],["submit"]]],[10],[0,"\\n\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/add-contribution/template.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/components/add-contributor/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Component.extend({kredits:Ember.inject.service(),attributes:null,isValidAccount:Ember.computed.notEmpty("account"),isValidName:Ember.computed.notEmpty("name"),isValidURL:Ember.computed.notEmpty("url"),isValidGithubUID:Ember.computed.notEmpty("github_uid"),isValidGithubUsername:Ember.computed.notEmpty("github_username"),isValidGiteaUsername:Ember.computed.notEmpty("gitea_username"),isValidWikiUsername:Ember.computed.notEmpty("wiki_username"),isValid:Ember.computed.and("isValidAccount","isValidName","isValidGithubUID"),inProgress:!1,init:function(){this._super.apply(this,arguments),this.setDefaultAttributes(),this.reset()},setDefaultAttributes:function(){Ember.isPresent(this.attributes)||this.set("attributes",{account:null,name:null,kind:"person",url:null,github_username:null,github_uid:null,gitea_username:null,wiki_username:null})},reset:function(){this.setProperties(this.attributes)},actions:{submit:function(){var e=this
|
|
||||||
if(this.isValid){var t=Object.keys(this.attributes),n=this.getProperties(t)
|
|
||||||
this.set("inProgress",!0),this.save(n).then(function(){e.reset()}).catch(function(e){console.warn(e),window.alert("Something went wrong. Please check the browser console.")}).finally(function(){e.set("inProgress",!1)})}else alert("Invalid data. Please review and try again.")}}})
|
|
||||||
e.default=t}),define("kredits-web/components/add-contributor/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"ub+zr3DC",block:'{"symbols":[],"statements":[[7,"form"],[9],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"label"],[11,"for","c-account"],[9],[0,"Ethereum account"],[10],[0,"\\n "],[1,[27,"input",null,[["name","id","type","value","placeholder","class"],["account","c-account","text",[23,["account"]],"0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4",[27,"if",[[23,["isValidAccount"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"label"],[11,"for","c-kind"],[9],[0,"Kind"],[10],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["kind"]]],null]],[["value"],["target.value"]]]],[11,"id","c-kind"],[9],[0,"\\n "],[7,"option"],[11,"value","person"],[12,"selected",[27,"eq",[[23,["kind"]],"person"],null]],[9],[0,"Person"],[10],[0,"\\n "],[7,"option"],[11,"value","organization"],[12,"selected",[27,"eq",[[23,["kind"]],"organization"],null]],[9],[0,"Organization"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"label"],[11,"for","c-name"],[9],[0,"Name"],[10],[0,"\\n "],[1,[27,"input",null,[["name","type","value","placeholder","class","id"],["name","text",[23,["name"]],"Zero Cool",[27,"if",[[23,["isValidName"]],"valid",""],null],"c-name"]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"label"],[11,"for","c-url"],[9],[0,"URL"],[10],[0,"\\n "],[1,[27,"input",null,[["name","type","value","placeholder","class","id"],["url","text",[23,["url"]],"http://zerocool.bit",[27,"if",[[23,["isValidURL"]],"valid",""],null],"c-url"]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"label"],[11,"for","c-github-uid"],[9],[0,"GitHub UID"],[10],[0,"\\n "],[1,[27,"input",null,[["name","type","value","placeholder","class","id"],["github_uid","text",[23,["github_uid"]],"2342",[27,"if",[[23,["isValidGithubUID"]],"valid",""],null],"c-github-uid"]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"label"],[11,"for","c-github-username"],[9],[0,"GitHub username"],[10],[0,"\\n "],[1,[27,"input",null,[["name","type","value","placeholder","class","id"],["github_username","text",[23,["github_username"]],"zerocool",[27,"if",[[23,["isValidGithubUsername"]],"valid",""],null],"c-github-username"]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"label"],[11,"for","c-gitea-username"],[9],[0,"Gitea username"],[10],[0,"\\n "],[1,[27,"input",null,[["name","type","value","placeholder","class","id"],["gitea_username","text",[23,["gitea_username"]],"zerocool",[27,"if",[[23,["isValidGiteaUsername"]],"valid",""],null],"c-gitea-username"]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"label"],[11,"for","c-wiki-username"],[9],[0,"Wiki username"],[10],[0,"\\n "],[1,[27,"input",null,[["name","type","value","placeholder","class","id"],["wiki_username","text",[23,["wiki_username"]],"ZeroCool",[27,"if",[[23,["isValidWikiUsername"]],"valid",""],null],"c-wiki-username"]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","actions"],[9],[0,"\\n "],[1,[27,"input",null,[["type","disabled","value"],["submit",[23,["inProgress"]],[27,"if",[[23,["inProgress"]],"Processing","Save"],null]]]],false],[0,"\\n "],[10],[0,"\\n"],[3,"action",[[22,0,[]],"submit"],[["on"],["submit"]]],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/add-contributor/template.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/components/add-proposal/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Component.extend({attributes:null,contributors:Object.freeze([]),isValidContributor:Ember.computed.notEmpty("contributorId"),isValidAmount:Ember.computed("amount",function(){return parseInt(this.amount,10)>0}),isValidDescription:Ember.computed.notEmpty("description"),isValidUrl:Ember.computed.notEmpty("url"),isValid:Ember.computed.and("isValidContributor","isValidAmount","isValidDescription"),init:function(){this._super.apply(this,arguments),this.set("attributes",{contributorId:null,kind:"community",amount:null,description:null,url:null})},didInsertElement:function(){this._super.apply(this,arguments),this.reset()},reset:function(){this.setProperties(this.attributes)},actions:{submit:function(){var e=this
|
|
||||||
if(this.isValid){var t=Object.keys(this.attributes),n=this.getProperties(t),r=this.save(n)
|
|
||||||
this.set("inProgress",r),r.then(function(){e.reset(),window.scroll(0,0),window.alert("Proposal added.")})}else alert("Invalid data. Please review and try again.")}}})
|
|
||||||
e.default=t}),define("kredits-web/components/add-proposal/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"3DOgBCvD",block:'{"symbols":["contributor"],"statements":[[7,"form"],[9],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["contributorId"]]],null]],[["value"],["target.value"]]]],[9],[0,"\\n "],[7,"option"],[11,"value",""],[11,"selected",""],[11,"disabled",""],[11,"hidden",""],[9],[0,"Contributor"],[10],[0,"\\n"],[4,"each",[[23,["contributors"]]],null,{"statements":[[0," "],[7,"option"],[12,"value",[22,1,["id"]]],[12,"selected",[27,"eq",[[23,["contributorId"]],[22,1,["id"]]],null]],[9],[1,[22,1,["github_username"]],false],[10],[0,"\\n"]],"parameters":[1]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[7,"select"],[11,"required",""],[12,"onchange",[27,"action",[[22,0,[]],[27,"mut",[[23,["kind"]]],null]],[["value"],["target.value"]]]],[9],[0,"\\n "],[7,"option"],[11,"value","community"],[12,"selected",[27,"eq",[[23,["kind"]],"community"],null]],[9],[0,"Community"],[10],[0,"\\n "],[7,"option"],[11,"value","design"],[12,"selected",[27,"eq",[[23,["kind"]],"design"],null]],[9],[0,"Design"],[10],[0,"\\n "],[7,"option"],[11,"value","dev"],[12,"selected",[27,"eq",[[23,["kind"]],"dev"],null]],[9],[0,"Development"],[10],[0,"\\n "],[7,"option"],[11,"value","docs"],[12,"selected",[27,"eq",[[23,["kind"]],"docs"],null]],[9],[0,"Documentation"],[10],[0,"\\n "],[7,"option"],[11,"value","ops"],[12,"selected",[27,"eq",[[23,["kind"]],"ops"],null]],[9],[0,"IT Operations"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","100",[23,["amount"]],[27,"if",[[23,["isValidAmount"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","Description",[23,["description"]],[27,"if",[[23,["isValidDescription"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[9],[0,"\\n "],[1,[27,"input",null,[["type","placeholder","value","class"],["text","URL (optional)",[23,["url"]],[27,"if",[[23,["isValidUrl"]],"valid",""],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","actions"],[9],[0,"\\n "],[1,[27,"input",null,[["type","disabled","value"],["submit",[27,"is-pending",[[23,["inProgress"]]],null],[27,"if",[[27,"is-pending",[[23,["inProgress"]]],null],"Processing","Save"],null]]]],false],[0,"\\n "],[4,"link-to",["index"],null,{"statements":[[0,"Back"]],"parameters":[]},null],[0,"\\n "],[10],[0,"\\n"],[3,"action",[[22,0,[]],"submit"],[["on"],["submit"]]],[10],[0,"\\n\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/add-proposal/template.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/components/chart-contributions-by-type/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t="#fb6868",n="#fbe468",r="#e068fb",i="#97fb68",o="#8f68fb",s=Ember.Component.extend({contributions:null,chartOptions:Object.freeze({legend:{display:!1}}),chartData:Ember.computed("contributions",function(){var e=this.contributions.filterBy("vetoed",!1).map(function(e){return{kind:e.kind,amount:e.amount}}).reduce(function(e,t){return t.kind in e?e[t.kind]=e[t.kind]+t.amount:e[t.kind]=t.amount,e},{})
|
|
||||||
return{datasets:[{data:[e.community,e.design,e.dev,e.ops,e.docs],borderColor:[t,n,r,o,i],borderWidth:1}],labels:["Community","Design","Development","Operations & Infrastructure","Documentation"]}})})
|
|
||||||
e.default=s}),define("kredits-web/components/chart-contributions-by-type/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"knNRD8x3",block:'{"symbols":[],"statements":[[7,"div"],[11,"class","chart"],[9],[0,"\\n "],[1,[27,"ember-chart",null,[["type","data","options","width","height"],["doughnut",[23,["chartData"]],[23,["chartOptions"]],200,200]]],false],[0,"\\n"],[10]],"hasEval":false}',meta:{moduleName:"kredits-web/components/chart-contributions-by-type/template.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/components/contribution-list/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Component.extend({tagName:"ul",classNames:["contribution-list"],actions:{veto:function(e){this.contractInteractionEnabled?this.vetoContribution(e):window.alert("Only members can veto contributions. Please ask someone to set you up.")}}})
|
|
||||||
e.default=t}),define("kredits-web/components/contribution-list/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"xYW3ZUYB",block:'{"symbols":["contribution"],"statements":[[4,"each",[[23,["contributions"]]],null,{"statements":[[0," "],[7,"li"],[12,"data-contribution-id",[22,1,["id"]]],[12,"class",[28,[[27,"contribution-status",[[22,1,[]]],null]," ",[27,"if",[[22,1,["vetoed"]],"vetoed"],null]]]],[9],[0,"\\n "],[7,"p"],[11,"class","meta"],[9],[0,"\\n "],[7,"span"],[11,"class","recipient"],[9],[1,[27,"user-avatar",null,[["contributor"],[[22,1,["contributor"]]]]],false],[10],[0,"\\n "],[7,"span"],[12,"class",[28,["category ",[22,1,["kind"]]]]],[9],[0,"("],[1,[22,1,["kind"]],false],[0,")"],[10],[0,"\\n "],[7,"span"],[11,"class","title"],[9],[0,"\\n"],[4,"if",[[22,1,["url"]]],null,{"statements":[[0," "],[7,"a"],[12,"href",[22,1,["url"]]],[11,"target","_blank"],[11,"rel","noopener"],[9],[1,[22,1,["description"]],false],[10],[0,"\\n"]],"parameters":[]},{"statements":[[0," "],[1,[22,1,["description"]],false],[0,"\\n"]],"parameters":[]}],[0," "],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","kredits-amount"],[9],[0,"\\n "],[7,"span"],[11,"class","amount"],[9],[1,[22,1,["amount"]],false],[10],[7,"span"],[11,"class","symbol"],[9],[0,"₭S"],[10],[0,"\\n "],[10],[0,"\\n"],[4,"unless",[[22,1,["vetoed"]]],null,{"statements":[[4,"unless",[[27,"is-confirmed-contribution",[[22,1,[]]],null]],null,{"statements":[[0," "],[7,"p"],[11,"class","voting"],[9],[0,"\\n "],[7,"button"],[11,"class","small danger"],[9],[0,"veto"],[3,"action",[[22,0,[]],"veto",[22,1,["id"]]]],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null]],"parameters":[]},null],[0," "],[10],[0,"\\n"]],"parameters":[1]},null]],"hasEval":false}',meta:{moduleName:"kredits-web/components/contribution-list/template.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/components/contributor-list/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Component.extend({tagName:"table",classNames:"contributor-list",selectedContributor:null,actions:{toggleContributorInfo:function(e){e.showMetadata?e.set("showMetadata",!1):(this.contributorList.setEach("showMetadata",!1),e.set("showMetadata",!0))}}})
|
|
||||||
e.default=t}),define("kredits-web/components/contributor-list/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"1on37xaL",block:'{"symbols":["c"],"statements":[[7,"tbody"],[9],[0,"\\n"],[4,"each",[[23,["contributorList"]]],null,{"statements":[[0," "],[7,"tr"],[11,"role","button"],[12,"class",[27,"if",[[27,"is-current-user",[[22,1,["contributor"]]],null],"current-user"],null]],[9],[0,"\\n "],[7,"td"],[11,"class","person"],[9],[0,"\\n "],[1,[27,"user-avatar",null,[["contributor"],[[22,1,["contributor"]]]]],false],[0," "],[1,[22,1,["contributor","name"]],false],[0,"\\n "],[10],[0,"\\n "],[7,"td"],[11,"class","kredits"],[9],[0,"\\n "],[7,"span"],[11,"class","amount"],[9],[0,"\\n"],[4,"if",[[23,["showUnconfirmedKredits"]]],null,{"statements":[[0," "],[1,[22,1,["amountTotal"]],false],[0,"\\n"]],"parameters":[]},{"statements":[[0," "],[1,[22,1,["amountConfirmed"]],false],[0,"\\n"]],"parameters":[]}],[0," "],[10],[0,"\\n "],[7,"span"],[11,"class","symbol"],[9],[0,"₭S"],[10],[0,"\\n "],[10],[0,"\\n "],[3,"action",[[22,0,[]],"toggleContributorInfo",[22,1,[]]]],[10],[0,"\\n "],[7,"tr"],[12,"class",[28,["metadata ",[27,"if",[[27,"is-current-user",[[22,1,["contributor"]]],null],"current-user"],null]," ",[27,"if",[[22,1,["showMetadata"]],"visible"],null]]]],[9],[0,"\\n "],[7,"td"],[11,"colspan","2"],[9],[0,"\\n "],[7,"ul"],[9],[0,"\\n "],[7,"li"],[9],[0,"\\n "],[7,"a"],[12,"href",[28,["https://rinkeby.etherscan.io/address/",[22,1,["contributor","account"]]]]],[11,"target","_blank"],[11,"rel","noopener"],[9],[0,"Inspect Ethereum transactions"],[10],[0,"\\n "],[10],[0,"\\n"],[4,"if",[[22,1,["contributor","ipfsHash"]]],null,{"statements":[[0," "],[7,"li"],[9],[0,"\\n "],[7,"a"],[12,"href",[28,["https://ipfs.io/ipfs/",[22,1,["contributor","ipfsHash"]]]]],[11,"target","_blank"],[11,"rel","noopener"],[9],[0,"Inspect IPFS profile"],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[7,"li"],[9],[0,"\\n "],[4,"link-to",["contributors.edit",[22,1,["contributor","id"]]],null,{"statements":[[0,"Edit profile"]],"parameters":[]},null],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n"],[4,"if",[[22,1,["showMetadata"]]],null,{"statements":[[0," "],[7,"pre"],[9],[1,[22,1,["contributor","ipfsData"]],false],[10],[0,""]],"parameters":[]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[1]},null],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/contributor-list/template.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/components/ember-chart",["exports","ember-cli-chart/components/ember-chart"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var n=t.default
|
|
||||||
e.default=n}),define("kredits-web/components/ember-flatpickr",["exports","ember-flatpickr/components/ember-flatpickr"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})}),define("kredits-web/components/loading-spinner/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Component.extend({classNames:["loading-spinner"]})
|
|
||||||
e.default=t}),define("kredits-web/components/loading-spinner/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"b6SWTOaj",block:'{"symbols":[],"statements":[[7,"p"],[9],[0,"\\n "],[7,"svg"],[11,"xmlns","http://www.w3.org/2000/svg","http://www.w3.org/2000/xmlns/"],[11,"xmlns:xlink","http://www.w3.org/1999/xlink","http://www.w3.org/2000/xmlns/"],[11,"version","1.1"],[11,"x","0px"],[11,"y","0px"],[11,"viewBox","0 0 132 100"],[11,"enable-background","new 0 0 100 100"],[11,"xml:space","preserve","http://www.w3.org/XML/1998/namespace"],[9],[0,"\\n "],[7,"path"],[11,"id","path-comet"],[11,"d","M79.062,24.173L79.062,24.173l-0.021-0.011c-0.068-0.03-0.137-0.062-0.204-0.093L42.392,7.337\\n c0,0,3.065,14.104,4.458,18.019l0,0c0,0-41.754-12.481-46.85-13.67c1.67,6.52,30.607,62.492,30.607,62.492\\n c5.848,11.873,19.394,18.485,33.522,18.485c19.811,0,35.87-16.059,35.87-35.869C100,42.313,91.418,29.837,79.062,24.173z"],[9],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n"],[10],[0,"\\n"],[7,"p"],[9],[0,"\\n Loading data...\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/components/loading-spinner/template.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/components/proposal-list/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Component.extend({tagName:"ul",classNames:["proposal-list"],actions:{confirm:function(e){this.contractInteractionEnabled?this.confirmProposal(e):window.alert("Only members can vote on proposals. Please ask someone to set you up.")}}})
|
|
||||||
e.default=t}),define("kredits-web/components/proposal-list/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"pZHMSOZc",block:'{"symbols":["proposal"],"statements":[[4,"each",[[23,["proposals"]]],null,{"statements":[[0," "],[7,"li"],[12,"data-proposal-id",[22,1,["id"]]],[12,"class",[27,"if",[[22,1,["isExecuted"]],"confirmed","unconfirmed"],null]],[9],[0,"\\n "],[7,"p"],[11,"class","meta"],[9],[0,"\\n "],[7,"span"],[12,"class",[28,["category ",[22,1,["kind"]]]]],[9],[0,"♥ ("],[1,[22,1,["kind"]],false],[0,")"],[10],[0,"\\n "],[7,"span"],[11,"class","recipient"],[9],[1,[22,1,["contributor","name"]],false],[0,":"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","kredits-amount"],[9],[0,"\\n "],[7,"span"],[11,"class","amount"],[9],[1,[22,1,["amount"]],false],[10],[7,"span"],[11,"class","symbol"],[9],[0,"₭S"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","description"],[9],[0,"\\n "],[7,"span"],[11,"class","description"],[9],[1,[22,1,["description"]],false],[10],[0,"\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","voting"],[9],[0,"\\n"],[4,"unless",[[22,1,["isExecuted"]]],null,{"statements":[[0," "],[7,"span"],[11,"class","votes"],[9],[0,"("],[1,[22,1,["votesCount"]],false],[0,"/"],[1,[22,1,["votesNeeded"]],false],[0," votes)"],[10],[0,"\\n "],[7,"button"],[9],[0,"+1"],[3,"action",[[22,0,[]],"confirm",[22,1,["id"]]]],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[1]},null]],"hasEval":false}',meta:{moduleName:"kredits-web/components/proposal-list/template.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/components/user-avatar/component",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Component.extend({contributor:null,tagName:"img",classNames:["avatar"],attributeBindings:["src","title"],src:Ember.computed.alias("contributor.avatarURL"),title:Ember.computed.alias("contributor.name")})
|
|
||||||
e.default=t}),define("kredits-web/components/user-avatar/template",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"rnnAjEgP",block:'{"symbols":[],"statements":[],"hasEval":false}',meta:{moduleName:"kredits-web/components/user-avatar/template.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/controllers/application",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Controller.extend({kredits:Ember.inject.service()})
|
|
||||||
e.default=t}),define("kredits-web/controllers/contributions/new",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Controller.extend({kredits:Ember.inject.service(),contributors:Ember.computed.alias("kredits.contributors"),minedContributors:Ember.computed.filterBy("contributors","id"),contributorsSorting:Object.freeze(["name:asc"]),sortedContributors:Ember.computed.sort("minedContributors","contributorsSorting"),actions:{save:function(e){var t=this,n=this.contributors.findBy("id",e.contributorId)
|
|
||||||
return e.contributorIpfsHash=n.ipfsHash,this.kredits.addContribution(e).then(function(e){return t.transitionToRoute("index"),e})}}})
|
|
||||||
e.default=t}),define("kredits-web/controllers/contributors/edit",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Controller.extend({kredits:Ember.inject.service(),actions:{save:function(e){var t=this
|
|
||||||
return this.kredits.updateContributor(this.model.id,e).then(function(){return t.transitionToRoute("index")})}}})
|
|
||||||
e.default=t}),define("kredits-web/controllers/contributors/new",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Controller.extend({kredits:Ember.inject.service(),actions:{save:function(e){var t=this
|
|
||||||
return this.kredits.addContributor(e).then(function(){return t.transitionToRoute("index")})}}})
|
|
||||||
e.default=t}),define("kredits-web/controllers/index",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Controller.extend({kredits:Ember.inject.service(),currentBlock:Ember.computed.alias("kredits.currentBlock"),contributions:Ember.computed.alias("kredits.contributions"),contributionsConfirmed:Ember.computed.alias("kredits.contributionsConfirmed"),contributionsUnconfirmed:Ember.computed.alias("kredits.contributionsUnconfirmed"),contributionsSorting:Object.freeze(["date:desc","time:desc","id:desc"]),contributionsUnconfirmedSorted:Ember.computed.sort("contributionsUnconfirmed","contributionsSorting"),contributionsConfirmedSorted:Ember.computed.sort("contributionsConfirmed","contributionsSorting"),kreditsByContributor:Ember.computed.alias("kredits.kreditsByContributor"),kreditsToplistSorting:Ember.computed("showUnconfirmedKredits",function(){return this.showUnconfirmedKredits?["amountTotal:desc"]:["amountConfirmed:desc"]}),kreditsToplist:Ember.computed.sort("kreditsByContributor","kreditsToplistSorting"),showUnconfirmedKredits:!0,hideUnconfirmedKredits:Ember.computed.not("showUnconfirmedKredits"),actions:{vetoContribution:function(e){this.kredits.veto(e).then(function(e){console.debug("[controllers:index] Veto submitted to Ethereum blockhain: "+e.hash)})},confirmProposal:function(e){this.kredits.vote(e).then(function(e){console.debug("[controllers:index] Vote submitted to Ethereum blockhain: "+e.hash)})}}})
|
|
||||||
e.default=t}),define("kredits-web/controllers/proposals/new",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Controller.extend({kredits:Ember.inject.service(),contributors:Ember.computed.alias("kredits.contributors"),minedContributors:Ember.computed.filterBy("contributors","id"),actions:{save:function(e){var t=this,n=this.contributors.findBy("id",e.contributorId)
|
|
||||||
return e.contributorIpfsHash=n.get("ipfsHash"),this.kredits.addProposal(e).then(function(e){return t.transitionToRoute("index"),e})}}})
|
|
||||||
e.default=t}),define("kredits-web/helpers/and",["exports","ember-truth-helpers/helpers/and"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"and",{enumerable:!0,get:function(){return t.and}})}),define("kredits-web/helpers/app-version",["exports","kredits-web/config/environment","ember-cli-app-version/utils/regexp"],function(e,t,n){function r(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},i=t.default.APP.version,o=r.versionOnly||r.hideSha,s=r.shaOnly||r.hideVersion,u=null
|
|
||||||
return o&&(r.showExtended&&(u=i.match(n.versionExtendedRegExp)),u||(u=i.match(n.versionRegExp))),s&&(u=i.match(n.shaRegExp)),u?u[0]:i}Object.defineProperty(e,"__esModule",{value:!0}),e.appVersion=r,e.default=void 0
|
|
||||||
var i=Ember.Helper.helper(r)
|
|
||||||
e.default=i}),define("kredits-web/helpers/await",["exports","ember-promise-helpers/helpers/await"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})})
|
|
||||||
define("kredits-web/helpers/contribution-status",["exports"],function(e){function t(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,o=void 0
|
|
||||||
try{for(var s,u=e[Symbol.iterator]();!(r=(s=u.next()).done)&&(n.push(s.value),!t||n.length!==t);r=!0);}catch(a){i=!0,o=a}finally{try{r||null==u.return||u.return()}finally{if(i)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var n=Ember.Helper.extend({kredits:Ember.inject.service(),currentBlock:Ember.computed.alias("kredits.currentBlock"),compute:function(e){var n=t(e,1)[0]
|
|
||||||
return n.vetoed?"vetoed":n.confirmedAt>this.currentBlock?"unconfirmed":"confirmed"}})
|
|
||||||
e.default=n}),define("kredits-web/helpers/eq",["exports","ember-truth-helpers/helpers/equal"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"equal",{enumerable:!0,get:function(){return t.equal}})}),define("kredits-web/helpers/gt",["exports","ember-truth-helpers/helpers/gt"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gt",{enumerable:!0,get:function(){return t.gt}})}),define("kredits-web/helpers/gte",["exports","ember-truth-helpers/helpers/gte"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"gte",{enumerable:!0,get:function(){return t.gte}})}),define("kredits-web/helpers/is-array",["exports","ember-truth-helpers/helpers/is-array"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isArray",{enumerable:!0,get:function(){return t.isArray}})}),define("kredits-web/helpers/is-confirmed-contribution",["exports"],function(e){function t(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,o=void 0
|
|
||||||
try{for(var s,u=e[Symbol.iterator]();!(r=(s=u.next()).done)&&(n.push(s.value),!t||n.length!==t);r=!0);}catch(a){i=!0,o=a}finally{try{r||null==u.return||u.return()}finally{if(i)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var n=Ember.Helper.extend({kredits:Ember.inject.service(),currentBlock:Ember.computed.alias("kredits.currentBlock"),compute:function(e){var n=t(e,1)[0]
|
|
||||||
return!n.vetoed&&n.confirmedAt<=this.currentBlock}})
|
|
||||||
e.default=n}),define("kredits-web/helpers/is-current-user",["exports"],function(e){function t(e,t){return function(e){if(Array.isArray(e))return e}(e)||function(e,t){var n=[],r=!0,i=!1,o=void 0
|
|
||||||
try{for(var s,u=e[Symbol.iterator]();!(r=(s=u.next()).done)&&(n.push(s.value),!t||n.length!==t);r=!0);}catch(a){i=!0,o=a}finally{try{r||null==u.return||u.return()}finally{if(i)throw o}}return n}(e,t)||function(){throw new TypeError("Invalid attempt to destructure non-iterable instance")}()}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var n=Ember.Helper.extend({kredits:Ember.inject.service(),currentUser:Ember.computed.alias("kredits.currentUser"),compute:function(e){var n=t(e,1)[0]
|
|
||||||
return Ember.isPresent(n)&&Ember.isPresent(this.currentUser)&&n.account===this.currentUser.account}})
|
|
||||||
e.default=n}),define("kredits-web/helpers/is-equal",["exports","ember-truth-helpers/helpers/is-equal"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isEqual",{enumerable:!0,get:function(){return t.isEqual}})}),define("kredits-web/helpers/is-fulfilled",["exports","ember-promise-helpers/helpers/is-fulfilled"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isFulfilled",{enumerable:!0,get:function(){return t.isFulfilled}})}),define("kredits-web/helpers/is-pending",["exports","ember-promise-helpers/helpers/is-pending"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isPending",{enumerable:!0,get:function(){return t.isPending}})}),define("kredits-web/helpers/is-rejected",["exports","ember-promise-helpers/helpers/is-rejected"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"isRejected",{enumerable:!0,get:function(){return t.isRejected}})}),define("kredits-web/helpers/lt",["exports","ember-truth-helpers/helpers/lt"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lt",{enumerable:!0,get:function(){return t.lt}})}),define("kredits-web/helpers/lte",["exports","ember-truth-helpers/helpers/lte"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"lte",{enumerable:!0,get:function(){return t.lte}})}),define("kredits-web/helpers/not-eq",["exports","ember-truth-helpers/helpers/not-equal"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"notEq",{enumerable:!0,get:function(){return t.notEq}})}),define("kredits-web/helpers/not",["exports","ember-truth-helpers/helpers/not"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"not",{enumerable:!0,get:function(){return t.not}})}),define("kredits-web/helpers/or",["exports","ember-truth-helpers/helpers/or"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"or",{enumerable:!0,get:function(){return t.or}})}),define("kredits-web/helpers/promise-all",["exports","ember-promise-helpers/helpers/promise-all"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"promiseAll",{enumerable:!0,get:function(){return t.promiseAll}})}),define("kredits-web/helpers/promise-hash",["exports","ember-promise-helpers/helpers/promise-hash"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"promiseHash",{enumerable:!0,get:function(){return t.promiseHash}})}),define("kredits-web/helpers/promise-rejected-reason",["exports","ember-promise-helpers/helpers/promise-rejected-reason"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})}),define("kredits-web/helpers/xor",["exports","ember-truth-helpers/helpers/xor"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}}),Object.defineProperty(e,"xor",{enumerable:!0,get:function(){return t.xor}})}),define("kredits-web/initializers/app-version",["exports","ember-cli-app-version/initializer-factory","kredits-web/config/environment"],function(e,t,n){var r,i
|
|
||||||
Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0,n.default.APP&&(r=n.default.APP.name,i=n.default.APP.version)
|
|
||||||
var o={name:"App Version",initialize:(0,t.default)(r,i)}
|
|
||||||
e.default=o}),define("kredits-web/initializers/container-debug-adapter",["exports","ember-resolver/resolvers/classic/container-debug-adapter"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var n={name:"container-debug-adapter",initialize:function(){var e=arguments[1]||arguments[0]
|
|
||||||
e.register("container-debug-adapter:main",t.default),e.inject("container-debug-adapter:main","namespace","application:main")}}
|
|
||||||
e.default=n}),define("kredits-web/initializers/export-application-global",["exports","kredits-web/config/environment"],function(e,t){function n(){var e=arguments[1]||arguments[0]
|
|
||||||
if(!1!==t.default.exportApplicationGlobal){var n
|
|
||||||
if("undefined"!=typeof window)n=window
|
|
||||||
else if("undefined"!=typeof global)n=global
|
|
||||||
else{if("undefined"==typeof self)return
|
|
||||||
n=self}var r,i=t.default.exportApplicationGlobal
|
|
||||||
r="string"==typeof i?i:Ember.String.classify(t.default.modulePrefix),n[r]||(n[r]=e,e.reopen({willDestroy:function(){this._super.apply(this,arguments),delete n[r]}}))}}Object.defineProperty(e,"__esModule",{value:!0}),e.initialize=n,e.default=void 0
|
|
||||||
var r={name:"export-application-global",initialize:n}
|
|
||||||
e.default=r}),define("kredits-web/models/contribution",["exports","kredits-web/utils/cps/bignumber"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var n=Ember.Object.extend({id:null,contributorId:null,amount:null,confirmedAt:(0,t.default)("confirmedAtBlock","toNumber"),vetoed:null,ipfsHash:null,creatorAccount:null,kind:null,description:null,details:null,url:null,ipfsData:"",init:function(){this._super.apply(this,arguments),this.set("details",{})}})
|
|
||||||
e.default=n}),define("kredits-web/models/contributor",["exports","kredits-web/utils/cps/bignumber","kredits-web/utils/cps/kredits"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var r=Ember.Object.extend({id:(0,t.default)("idRaw","toString"),account:null,balance:(0,n.default)("balanceRaw"),totalKreditsEarned:(0,t.default)("totalKreditsEarnedRaw","toNumber"),contributionsCount:(0,t.default)("contributionsCountRaw","toNumber"),isCore:!1,ipfsHash:null,kind:null,name:null,url:null,github_username:null,github_uid:null,wiki_username:null,ipfsData:"",avatarURL:Ember.computed("github_uid",function(){var e=this.github_uid
|
|
||||||
if(e)return"https://avatars2.githubusercontent.com/u/".concat(e,"?v=3&s=128")})})
|
|
||||||
e.default=r}),define("kredits-web/models/proposal",["exports","kredits-web/utils/cps/bignumber"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var n=Ember.Object.extend({id:(0,t.default)("idRaw","toString"),creatorAccount:null,contributorId:(0,t.default)("contributorIdRaw","toString"),amount:(0,t.default)("amountRaw","toNumber"),votesCount:(0,t.default)("votesCountRaw","toNumber"),votesNeeded:(0,t.default)("votesNeededRaw","toNumber"),executed:null,ipfsHash:null,isExecuted:Ember.computed.alias("executed"),kind:null,description:null,details:null,url:null,ipfsData:"",init:function(){this._super.apply(this,arguments),this.set("details",{})}})
|
|
||||||
e.default=n}),define("kredits-web/resolver",["exports","ember-resolver"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var n=t.default
|
|
||||||
e.default=n}),define("kredits-web/router",["exports","kredits-web/config/environment"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var n=Ember.Router.extend({location:t.default.locationType,rootURL:t.default.rootURL})
|
|
||||||
n.map(function(){this.route("proposals",function(){this.route("new")}),this.route("contributions",function(){this.route("new")}),this.route("contributors",function(){this.route("new"),this.route("edit",{path:":id/edit"})})})
|
|
||||||
var r=n
|
|
||||||
e.default=r}),define("kredits-web/routes/application",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Route.extend({kredits:Ember.inject.service(),beforeModel:function(e){var t=this.kredits
|
|
||||||
return t.setup().then(function(){t.get("kredits").preflightChecks().catch(function(e){console.error("Kredits preflight check failed!"),console.error(e)}),t.get("accountNeedsUnlock")&&confirm("It looks like you have an Ethereum wallet available. Please unlock your account.")&&e.retry()}).catch(function(e){console.log("Error initializing Kredits",e)})},afterModel:function(){var e=this
|
|
||||||
return this.kredits.loadInitialData().then(function(){e.kredits.addContractEventHandlers()})}})
|
|
||||||
e.default=t}),define("kredits-web/routes/contributors/edit",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.Route.extend({kredits:Ember.inject.service(),contributors:Ember.computed.alias("kredits.contributors"),model:function(e){return this.kredits.contributors.findBy("id",e.id)},setupController:function(e,t){this._super(e,t),e.set("attributes",{account:t.account,name:t.name,kind:t.kind,url:t.url,github_username:t.github_username,github_uid:t.github_uid,gitea_username:t.gitea_username,wiki_username:t.wiki_username})}})
|
|
||||||
e.default=t})
|
|
||||||
define("kredits-web/services/ajax",["exports","ember-ajax/services/ajax"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),Object.defineProperty(e,"default",{enumerable:!0,get:function(){return t.default}})}),define("kredits-web/services/kredits",["exports","npm:ethers","npm:kredits-contracts","kredits-web/utils/group-by","kredits-web/utils/format-kredits","kredits-web/config/environment","kredits-web/models/contributor","kredits-web/models/proposal","kredits-web/models/contribution"],function(e,t,n,r,i,o,s,u,a){function l(e,t,n,r,i,o,s){try{var u=e[o](s),a=u.value}catch(l){return void n(l)}u.done?t(a):Promise.resolve(a).then(r,i)}function d(e){return function(){var t=this,n=arguments
|
|
||||||
return new Promise(function(r,i){var o=e.apply(t,n)
|
|
||||||
function s(e){l(o,r,i,s,u,"next",e)}function u(e){l(o,r,i,s,u,"throw",e)}s(void 0)})}}Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var c=Ember.Service.extend({currentBlock:null,currentUserAccounts:null,currentUser:null,contributors:null,contributions:null,proposals:null,currentUserIsContributor:Ember.computed.notEmpty("currentUser"),currentUserIsCore:Ember.computed.alias("currentUser.isCore"),hasAccounts:Ember.computed.notEmpty("currentUserAccounts"),accountNeedsUnlock:Ember.computed("currentUserAccounts",function(){return this.currentUserAccounts&&Ember.isEmpty(this.currentUserAccounts)}),contributionsUnconfirmed:Ember.computed("contributions.[]","currentBlock",function(){var e=this
|
|
||||||
return this.contributions.filter(function(t){return t.confirmedAt>e.currentBlock})}),contributionsConfirmed:Ember.computed("contributions.[]","currentBlock",function(){var e=this
|
|
||||||
return this.contributions.filterBy("vetoed",!1).filter(function(t){return t.confirmedAt<=e.currentBlock})}),kreditsByContributor:Ember.computed("contributionsUnconfirmed.@each.vetoed","contributors.[]",function(){var e=this,t=this.contributionsUnconfirmed.filterBy("vetoed",!1),n=(0,r.default)(t,"contributorId"),i=n.map(function(e){return e.value.toString()}),o=this.contributors.reject(function(e){return i.includes(e.id)}),s=n.map(function(t){var n=t.items.mapBy("amount").reduce(function(e,t){return e+t}),r=e.contributors.findBy("id",t.value.toString())
|
|
||||||
return Ember.Object.create({contributor:r,amountUnconfirmed:n,amountConfirmed:r.totalKreditsEarned,amountTotal:r.totalKreditsEarned+n})})
|
|
||||||
return o.forEach(function(e){s.push(Ember.Object.create({contributor:e,amountUnconfirmed:0,amountConfirmed:e.totalKreditsEarned,amountTotal:e.totalKreditsEarned}))}),s}),init:function(){this._super.apply(this,arguments),this.set("contributors",[]),this.set("proposals",[]),this.set("contributions",[])},getEthProvider:function(){var e,n=this
|
|
||||||
return new Ember.RSVP.Promise(function(){var r=d(regeneratorRuntime.mark(function r(i){var s,u,a
|
|
||||||
return regeneratorRuntime.wrap(function(r){for(;;)switch(r.prev=r.next){case 0:if(a=function(){return(a=d(regeneratorRuntime.mark(function n(r,o){return regeneratorRuntime.wrap(function(n){for(;;)switch(n.prev=n.next){case 0:console.debug("[kredits] Using user-provided instance, e.g. from Mist browser or Metamask"),(e=new t.default.providers.Web3Provider(r)).listAccounts().then(function(t){o.set("currentUserAccounts",t)
|
|
||||||
var n=0===t.length?null:e.getSigner()
|
|
||||||
i({ethProvider:e,ethSigner:n})})
|
|
||||||
case 3:case"end":return n.stop()}},n)}))).apply(this,arguments)},u=function(e,t){return a.apply(this,arguments)},s=function(){console.debug("[kredits] Creating new instance from npm module class"),console.debug("[kredits] providerURL: ".concat(o.default.web3ProviderUrl)),e=new t.default.providers.JsonRpcProvider(o.default.web3ProviderUrl),i({ethProvider:e,ethSigner:null})},!window.ethereum){r.next=15
|
|
||||||
break}return r.prev=4,r.next=7,window.ethereum.enable()
|
|
||||||
case 7:u(window.ethereum,n),r.next=13
|
|
||||||
break
|
|
||||||
case 10:r.prev=10,r.t0=r.catch(4),s()
|
|
||||||
case 13:r.next=16
|
|
||||||
break
|
|
||||||
case 15:window.web3?u(window.web3.currentProvider,n):s()
|
|
||||||
case 16:case"end":return r.stop()}},r,null,[[4,10]])}))
|
|
||||||
return function(e){return r.apply(this,arguments)}}())},setup:function(){var e=this
|
|
||||||
return this.getEthProvider().then(function(t){return new n.default(t.ethProvider,t.ethSigner,{addresses:{Kernel:o.default.kreditsKernelAddress},apm:o.default.kreditsApmDomain,ipfsConfig:o.default.ipfs}).init().then(function(){var t=d(regeneratorRuntime.mark(function t(n){return regeneratorRuntime.wrap(function(t){for(;;)switch(t.prev=t.next){case 0:return e.set("kredits",n),t.t0=e,t.next=4,n.provider.getBlockNumber()
|
|
||||||
case 4:return t.t1=t.sent,t.t0.set.call(t.t0,"currentBlock",t.t1),e.currentUserAccounts&&e.currentUserAccounts.length>0&&e.getCurrentUser.then(function(t){e.set("currentUser",t)}),t.abrupt("return",n)
|
|
||||||
case 8:case"end":return t.stop()}},t)}))
|
|
||||||
return function(e){return t.apply(this,arguments)}}())})},totalSupply:Ember.computed(function(){return this.kredits.Token.functions.totalSupply().then(function(e){return(0,i.default)(e)})}),totalKreditsEarned:Ember.computed(function(){return this.kredits.Contribution.functions.totalKreditsEarned(!0).then(function(e){return e.toNumber()})}),loadInitialData:function(){var e=this
|
|
||||||
return this.getContributors().then(function(t){return e.contributors.pushObjects(t)}).then(function(){return e.getContributions()}).then(function(t){return e.contributions.pushObjects(t)})},addContributor:function(e){if(e.github_uid){var t=parseInt(e.github_uid)
|
|
||||||
e.github_uid=t}return console.debug("[kredits] add contributor",e),this.kredits.Contributor.add(e,{gasLimit:35e4}).then(function(e){console.debug("[kredits] add contributor response",e)})},updateContributor:function(e,t){if(t.github_uid){var n=parseInt(t.github_uid)
|
|
||||||
t.github_uid=n}return console.debug("[kredits] update contributor",t),this.kredits.Contributor.updateProfile(e,t,{gasLimit:35e4}).then(function(e){console.debug("[kredits] updateProfile response",e)})},getContributors:function(){return this.kredits.Contributor.all().then(function(e){return e.map(function(e){return s.default.create(e)})})},addContribution:function(e){var t=this
|
|
||||||
return console.debug("[kredits] add contribution",e),this.kredits.Contribution.addContribution(e,{gasLimit:3e5}).then(function(n){console.debug("[kredits] add contribution response",n),e.contributor=t.contributors.findBy("id",e.contributorId)
|
|
||||||
var r=a.default.create(e)
|
|
||||||
return r.set("confirmedAtBlock",n.blockNumber+40320),t.contributions.pushObject(r),r})},addProposal:function(e){var t=this
|
|
||||||
return console.debug("[kredits] add proposal",e),this.kredits.Proposal.addProposal(e).then(function(n){return console.debug("[kredits] add proposal response",n),e.contributor=t.contributors.findBy("id",e.contributorId),u.default.create(e)})},getProposals:function(){var e=this
|
|
||||||
return this.kredits.Proposal.all().then(function(t){return t.map(function(t){return t.contributor=e.contributors.findBy("id",t.contributorId.toString()),u.default.create(t)})})},getContributions:function(){var e=this
|
|
||||||
return this.kredits.Contribution.all({page:{size:200}}).then(function(t){return t.map(function(t){return t.contributor=e.contributors.findBy("id",t.contributorId.toString()),a.default.create(t)})})},vote:function(e){return console.debug("[kredits] vote for",e),this.kredits.Proposal.functions.vote(e).then(function(e){return console.debug("[kredits] vote response",e),e})},veto:function(e){return console.debug("[kredits] veto against",e),this.kredits.Contribution.functions.veto(e,{gasLimit:3e5}).then(function(e){return console.debug("[kredits] veto response",e),e})},getCurrentUser:Ember.computed("kredits.provider",function(){var e=this
|
|
||||||
return Ember.isEmpty(this.currentUserAccounts)?Ember.RSVP.resolve():this.kredits.Contributor.functions.getContributorIdByAddress(this.get("currentUserAccounts.firstObject")).then(function(t){return 0===t?Ember.RSVP.resolve():e.kredits.Contributor.getById(t)})}),findProposalById:function(e){return this.proposals.findBy("id",e.toString())},addContractEventHandlers:function(){this.kredits.Contributor.on("ContributorProfileUpdated",this.handleContributorChange.bind(this)).on("ContributorAccountUpdated",this.handleContributorChange.bind(this)).on("ContributorAdded",this.handleContributorChange.bind(this)),this.kredits.Contribution.on("ContributionVetoed",this.handleContributionVetoed.bind(this)),this.kredits.Proposal.on("ProposalCreated",this.handleProposalCreated.bind(this)).on("ProposalVoted",this.handleProposalVoted.bind(this)).on("ProposalExecuted",this.handleProposalExecuted.bind(this)),this.kredits.Token.on("Transfer",this.handleTransfer.bind(this))},handleContributorChange:function(){var e=d(regeneratorRuntime.mark(function e(t){var n,r,i,o,u,a,l=arguments
|
|
||||||
return regeneratorRuntime.wrap(function(e){for(;;)switch(e.prev=e.next){case 0:for(console.debug("[kredits] Contributor add/update event received for ID",t),n=l.length,r=new Array(n>1?n-1:0),i=1;i<n;i++)r[i-1]=l[i]
|
|
||||||
return console.debug("[kredits] Event data:",r),e.next=5,this.kredits.Contributor.getById(t)
|
|
||||||
case 5:o=e.sent,u=s.default.create(o),(a=this.contributors.findBy("id",t.toString()))&&(console.debug("[kredits] old contributor",a),this.contributors.removeObject(a)),console.debug("[kredits] new contributor",u),this.contributors.pushObject(u)
|
|
||||||
case 11:case"end":return e.stop()}},e,this)}))
|
|
||||||
return function(t){return e.apply(this,arguments)}}(),handleContributionVetoed:function(e){console.debug("[kredits] ContributionVetoed event received for ",e)
|
|
||||||
var t=this.contributions.findBy("id",e)
|
|
||||||
console.debug("[kredits] contribution",t),t&&t.set("vetoed",!0)},handleProposalCreated:function(e){var t=this
|
|
||||||
this.findProposalById(e)?console.debug("[events] proposal exists, not adding from event"):this.kredits.Proposal.getById(e).then(function(e){e.contributor=t.contributors.findBy("id",e.contributorId.toString()),t.proposals.pushObject(u.default.create(e))})},handleProposalVoted:function(e,t,n){var r=this.findProposalById(e)
|
|
||||||
r&&r.set("votesCount",n)},handleProposalExecuted:function(e,t,n){var r=this.findProposalById(e)
|
|
||||||
r.get("isExecuted")?console.debug("[events] proposal already executed, not adding from event"):(r.set("executed",!0),this.contributors.findBy("id",t.toString()).incrementProperty("balance",n))},handleTransfer:function(e,t,n){n=n.toNumber(),this.contributors.findBy("address",e).decrementProperty("balance",n),this.contributors.findBy("address",t).incrementProperty("balance",n)}})
|
|
||||||
e.default=c}),define("kredits-web/templates/application-loading",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"/K85jZFR",block:'{"symbols":[],"statements":[[1,[21,"loading-spinner"],false],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/application-loading.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/templates/application",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"M6vaFJ5T",block:'{"symbols":[],"statements":[[7,"header"],[11,"id","topbar"],[9],[0,"\\n "],[7,"h1"],[9],[0,"Kosmos Kredits"],[10],[0,"\\n\\n "],[7,"section"],[11,"id","user-account"],[9],[0,"\\n"],[4,"if",[[23,["kredits","hasAccounts"]]],null,{"statements":[[4,"if",[[23,["kredits","currentUser"]]],null,{"statements":[[0," "],[1,[23,["kredits","currentUser","name"]],false],[0,"\\n "],[4,"if",[[23,["kredits","currentUserIsCore"]]],null,{"statements":[[0,"(core)"]],"parameters":[]},null],[0,"\\n"]],"parameters":[]},null]],"parameters":[]},{"statements":[[0," Anonymous\\n"]],"parameters":[]}],[0," "],[10],[0,"\\n"],[10],[0,"\\n\\n"],[1,[21,"outlet"],false],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/application.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/templates/contributions/new",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"YPbtYII6",block:'{"symbols":[],"statements":[[7,"main"],[11,"class","center-column"],[9],[0,"\\n\\n "],[7,"section"],[11,"id","add-contribution"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Submit a contribution"],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"add-contribution",null,[["contributors","save"],[[23,["sortedContributors"]],[27,"action",[[22,0,[]],"save"],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/contributions/new.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/templates/contributors/edit",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"LZQyoYt+",block:'{"symbols":[],"statements":[[7,"main"],[11,"class","center-column"],[9],[0,"\\n\\n "],[7,"section"],[11,"id","add-contributor"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Update contributor profile"],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"add-contributor",null,[["attributes","save"],[[23,["attributes"]],[27,"action",[[22,0,[]],"save"],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/contributors/edit.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/templates/contributors/new",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"IoVi6fNU",block:'{"symbols":[],"statements":[[7,"main"],[11,"class","center-column"],[9],[0,"\\n\\n "],[7,"section"],[11,"id","add-contributor"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Add contributor profile"],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"add-contributor",null,[["save"],[[27,"action",[[22,0,[]],"save"],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/contributors/new.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/templates/index",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"kSDGlXXL",block:'{"symbols":[],"statements":[[7,"main"],[11,"id","index"],[9],[0,"\\n\\n "],[7,"div"],[11,"id","stats"],[9],[0,"\\n "],[7,"section"],[11,"id","people"],[9],[0,"\\n "],[7,"header"],[11,"class","with-nav"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Contributors"],[10],[0,"\\n"],[4,"if",[[23,["kredits","hasAccounts"]]],null,{"statements":[[0," "],[7,"nav"],[9],[0,"\\n "],[4,"link-to",["contributors.new"],[["title","class"],["Add contributor profile","button small green"]],{"statements":[[0,"add"]],"parameters":[]},null],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"contributor-list",null,[["contributorList","showUnconfirmedKredits"],[[23,["kreditsToplist"]],[23,["showUnconfirmedKredits"]]]]],false],[0,"\\n\\n "],[7,"p"],[11,"class","stats"],[9],[0,"\\n "],[7,"span"],[11,"class","number"],[9],[1,[27,"await",[[23,["kredits","totalKreditsEarned"]]],null],false],[10],[0," kredits confirmed and issued to\\n "],[7,"span"],[11,"class","number"],[9],[1,[23,["contributorsWithKredits","length"]],false],[10],[0," contributors\\n "],[10],[0,"\\n "],[7,"p"],[11,"class","stats"],[9],[0,"\\n "],[1,[27,"input",null,[["type","id","checked"],["checkbox","hide-unnconfirmed-kredits",[23,["showUnconfirmedKredits"]]]]],false],[0,"\\n "],[7,"label"],[11,"for","hide-unnconfirmed-kredits"],[9],[0,"Show unconfirmed kredits in toplist"],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"section"],[11,"id","contributions-by-type"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Contributions by type"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"chart-contributions-by-type",null,[["contributions"],[[23,["contributions"]]]]],false],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"id","contributions"],[9],[0,"\\n"],[4,"if",[[23,["contributionsUnconfirmed"]]],null,{"statements":[[0," "],[7,"section"],[11,"id","contributions-unconfirmed"],[9],[0,"\\n "],[7,"header"],[11,"class","with-nav"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Latest Contributions"],[10],[0,"\\n"],[4,"if",[[23,["kredits","hasAccounts"]]],null,{"statements":[[0," "],[7,"nav"],[9],[0,"\\n "],[4,"link-to",["contributions.new"],[["title","class"],["Submit a contribution","button small green"]],{"statements":[[0,"add"]],"parameters":[]},null],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0," "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n"],[0," "],[1,[27,"contribution-list",null,[["contributions","vetoContribution","contractInteractionEnabled"],[[23,["contributionsUnconfirmedSorted"]],[27,"action",[[22,0,[]],"vetoContribution"],null],[23,["kredits","hasAccounts"]]]]],false],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n"]],"parameters":[]},null],[0,"\\n "],[7,"section"],[11,"id","contributions-confirmed"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Confirmed Contributions"],[10],[0,"\\n "],[10],[0,"\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"contribution-list",null,[["contributions","vetoContribution"],[[23,["contributionsConfirmedSorted"]],[27,"action",[[22,0,[]],"vetoContribution"],null]]]],false],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n "],[10],[0,"\\n\\n"],[10],[0,"\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/index.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/templates/proposals/new",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=void 0
|
|
||||||
var t=Ember.HTMLBars.template({id:"vauAEy3a",block:'{"symbols":[],"statements":[[7,"section"],[11,"id","add-proposal"],[9],[0,"\\n "],[7,"header"],[9],[0,"\\n "],[7,"h2"],[9],[0,"Add Proposal"],[10],[0,"\\n "],[10],[0,"\\n\\n "],[7,"div"],[11,"class","content"],[9],[0,"\\n "],[1,[27,"add-proposal",null,[["contributors","save"],[[23,["minedContributors"]],[27,"action",[[22,0,[]],"save"],null]]]],false],[0,"\\n "],[10],[0,"\\n"],[10],[0,"\\n\\n"]],"hasEval":false}',meta:{moduleName:"kredits-web/templates/proposals/new.hbs"}})
|
|
||||||
e.default=t}),define("kredits-web/utils/cps/bignumber",["exports","npm:ethers"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,n){return Ember.computed(e,{get:function(){var r=this.get(e)
|
|
||||||
return r&&t.default.utils.BigNumber.isBigNumber(r)?r[n]():r},set:function(r,i){var o=t.default.utils.bigNumberify(i)
|
|
||||||
return this.set(e,o),o[n]()}})}}),define("kredits-web/utils/cps/kredits",["exports","npm:ethers","kredits-web/utils/format-kredits"],function(e,t,n){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){var r=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{}
|
|
||||||
return Ember.computed(e,{get:function(){var t=this.get(e)
|
|
||||||
return(0,n.default)(t,r)},set:function(i,o){var s=t.default.utils.bigNumberify(o)
|
|
||||||
return this.set(e,s),(0,n.default)(s,r)}})}}),define("kredits-web/utils/format-kredits",["exports","npm:ethers"],function(e,t){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},r=t.default.utils.formatEther(e)
|
|
||||||
n.decimals||(r=parseInt(r).toString())
|
|
||||||
return r}}),define("kredits-web/utils/group-by",["exports"],function(e){Object.defineProperty(e,"__esModule",{value:!0}),e.default=function(e,t){var n=Ember.A(),r=e
|
|
||||||
r&&r.forEach(function(e){var r=Ember.get(e,t),i=n.findBy("value",r)
|
|
||||||
Ember.isPresent(i)?Ember.get(i,"items").push(e):(i={property:t,value:r,items:[e]},n.push(i))})
|
|
||||||
return n}}),define("kredits-web/config/environment",[],function(){try{var e="kredits-web/config/environment",t=document.querySelector('meta[name="'+e+'"]').getAttribute("content"),n={default:JSON.parse(decodeURIComponent(t))}
|
|
||||||
return Object.defineProperty(n,"__esModule",{value:!0}),n}catch(r){throw new Error('Could not read config from meta tag with name "'+e+'".')}}),runningTests||require("kredits-web/app").default.create({name:"kredits-web",version:"1.2.0+f5c89fd5"})
|
|
||||||
|
|
||||||
//# sourceMappingURL=kredits-web-7c4a80176b0108122ca081687f9fe9e8.map
|
|
||||||
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
Binary file not shown.
|
Before Width: | Height: | Size: 669 KiB |
@@ -1,9 +0,0 @@
|
|||||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
|
||||||
version="1.1" x="0px" y="0px" viewBox="0 0 100 100"
|
|
||||||
enable-background="new 0 0 100 100" xml:space="preserve">
|
|
||||||
<path id="path-comet"
|
|
||||||
d="M79.062,24.173L79.062,24.173l-0.021-0.011c-0.068-0.03-0.137-0.062-0.204-0.093L42.392,7.337
|
|
||||||
c0,0,3.065,14.104,4.458,18.019l0,0c0,0-41.754-12.481-46.85-13.67c1.67,6.52,30.607,62.492,30.607,62.492
|
|
||||||
c5.848,11.873,19.394,18.485,33.522,18.485c19.811,0,35.87-16.059,35.87-35.869C100,42.313,91.418,29.837,79.062,24.173z">
|
|
||||||
</path>
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 590 B |
@@ -1,32 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<meta charset="utf-8">
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
||||||
<title>Kosmos Kredits</title>
|
|
||||||
<meta name="description" content="">
|
|
||||||
<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%7D%2C%22APP%22%3A%7B%22name%22%3A%22kredits-web%22%2C%22version%22%3A%221.2.0%2Bf5c89fd5%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%7D%2C%22kreditsApmDomain%22%3A%22open.aragonpm.eth%22%2C%22exportApplicationGlobal%22%3Afalse%7D" />
|
|
||||||
|
|
||||||
<link integrity="" rel="stylesheet" href="/assets/vendor-179cf27a97ea5bbb0ce72403a401cc8c.css">
|
|
||||||
<link integrity="" rel="stylesheet" href="/assets/kredits-web-29d147f9bc6d79dbc7aff481f8ee5541.css">
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
<script>
|
|
||||||
window.addEventListener('load', function() {
|
|
||||||
window.windowLoadComplete = true;
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
|
|
||||||
|
|
||||||
<script src="/assets/vendor-801d0f45e82f8bef6ee0b28f728036e5.js" integrity="sha256-0rvoxLzxNRaodYFUkwv5D3zakixGtC+//xKSO9XtbKc= sha512-YNRAvmy8HT14rRH3MwaQciCOYPZwuuiDT5Bsi3aIXUWtADH2HNxR3K88BTGtNEbOXCCSewh0vpkiBt1o1eyTvg==" ></script>
|
|
||||||
<script src="/assets/kredits-web-b12d883fdbeaf315e3cd3e3302904d30.js" integrity="sha256-VVMzBYeO6bs3raMutSy2L5hOW0sd7q8UMjd6G8gblto= sha512-yP5/L4EkuYjPSFMENaxdSB2q8EYXWJrrIEVw5X3Lsxf1+tvkg11hRnhcEDpGQLqDfIc7uSItsRXsH4oIyYJVTA==" ></script>
|
|
||||||
|
|
||||||
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
@@ -1,3 +0,0 @@
|
|||||||
# http://www.robotstxt.org
|
|
||||||
User-agent: *
|
|
||||||
Disallow:
|
|
||||||
Executable
+20
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
set -xe
|
||||||
|
|
||||||
|
# Get revision from local master
|
||||||
|
rev=`git rev-parse HEAD`
|
||||||
|
short_rev=${rev:0:7}
|
||||||
|
# Check out build branch
|
||||||
|
git checkout build-production
|
||||||
|
# Copy from build dir to root
|
||||||
|
cp -r dist/* .
|
||||||
|
# Add all files
|
||||||
|
git add --all
|
||||||
|
# Commit build files
|
||||||
|
git commit -m "Build production from $short_rev"
|
||||||
|
# Push to remote
|
||||||
|
git push 5apps build-production:master
|
||||||
|
# Push build branch to collab repo
|
||||||
|
git push origin build-production:build-production
|
||||||
|
# Go back to previous branch
|
||||||
|
git checkout -
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
PACKAGE_VERSION=$(cat package.json \
|
||||||
|
| grep version \
|
||||||
|
| head -1 \
|
||||||
|
| awk -F: '{ print $2 }' \
|
||||||
|
| sed 's/[",]//g' \
|
||||||
|
| tr -d '[[:space:]]')
|
||||||
|
|
||||||
|
echo $PACKAGE_VERSION > dist/VERSION
|
||||||
@@ -1,25 +1,13 @@
|
|||||||
|
/*jshint node:true*/
|
||||||
module.exports = {
|
module.exports = {
|
||||||
test_page: 'tests/index.html?hidepassed',
|
"framework": "qunit",
|
||||||
disable_watching: true,
|
"test_page": "tests/index.html?hidepassed",
|
||||||
launch_in_ci: [
|
"disable_watching": true,
|
||||||
'Chrome'
|
"launch_in_ci": [
|
||||||
|
"PhantomJS"
|
||||||
],
|
],
|
||||||
launch_in_dev: [
|
"launch_in_dev": [
|
||||||
'Chrome'
|
"PhantomJS",
|
||||||
],
|
"Chrome"
|
||||||
browser_args: {
|
]
|
||||||
Chrome: {
|
|
||||||
ci: [
|
|
||||||
// --no-sandbox is needed when running Chrome inside a container
|
|
||||||
process.env.CI ? '--no-sandbox' : null,
|
|
||||||
'--headless',
|
|
||||||
'--disable-gpu',
|
|
||||||
'--disable-dev-shm-usage',
|
|
||||||
'--disable-software-rasterizer',
|
|
||||||
'--mute-audio',
|
|
||||||
'--remote-debugging-port=0',
|
|
||||||
'--window-size=1440,900'
|
|
||||||
].filter(Boolean)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"predef": [
|
||||||
|
"document",
|
||||||
|
"window",
|
||||||
|
"location",
|
||||||
|
"setTimeout",
|
||||||
|
"$",
|
||||||
|
"-Promise",
|
||||||
|
"define",
|
||||||
|
"console",
|
||||||
|
"visit",
|
||||||
|
"exists",
|
||||||
|
"fillIn",
|
||||||
|
"click",
|
||||||
|
"keyEvent",
|
||||||
|
"triggerEvent",
|
||||||
|
"find",
|
||||||
|
"findWithAssert",
|
||||||
|
"wait",
|
||||||
|
"DS",
|
||||||
|
"andThen",
|
||||||
|
"currentURL",
|
||||||
|
"currentPath",
|
||||||
|
"currentRouteName"
|
||||||
|
],
|
||||||
|
"node": false,
|
||||||
|
"browser": false,
|
||||||
|
"boss": true,
|
||||||
|
"curly": true,
|
||||||
|
"debug": false,
|
||||||
|
"devel": false,
|
||||||
|
"eqeqeq": true,
|
||||||
|
"evil": true,
|
||||||
|
"forin": false,
|
||||||
|
"immed": false,
|
||||||
|
"laxbreak": false,
|
||||||
|
"newcap": true,
|
||||||
|
"noarg": true,
|
||||||
|
"noempty": false,
|
||||||
|
"nonew": false,
|
||||||
|
"nomen": false,
|
||||||
|
"onevar": false,
|
||||||
|
"plusplus": false,
|
||||||
|
"regexp": false,
|
||||||
|
"undef": true,
|
||||||
|
"sub": true,
|
||||||
|
"strict": false,
|
||||||
|
"white": false,
|
||||||
|
"eqnull": true,
|
||||||
|
"esversion": 6,
|
||||||
|
"unused": true
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user