Compare commits
345 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 07c579850e | |||
| 091ebf4b6a | |||
| b4e89492b4 | |||
| f5c89fd567 | |||
| 1fbf8f0769 | |||
| cc8952f844 | |||
| 25ea20e63b | |||
| e60651858d | |||
| 24390c6503 | |||
| c1d5c90745 | |||
| 3d20bce5e3 | |||
| 3fe8043c76 | |||
| bad86232b4 | |||
| 7eb14ac4e2 | |||
| 8b0cd8c986 | |||
| 5064a472f2 | |||
| afc5a5fe50 | |||
| f9f6786f95 | |||
| 03f31e2d20 | |||
| 1c1f772ff5 | |||
| 58bd729acb | |||
| 1ea5305e6e | |||
| e84a1cbc4e | |||
| 29115d9b16 | |||
| 409d5e33f9 | |||
| 883b5dc415 | |||
| 16ee3b6b6b | |||
| 4efd6f8f88 | |||
| af9951ca5a | |||
| c30c6c2b36 | |||
| 8bd4c6e6e1 | |||
| 9a98b37bb6 | |||
| fad10ec1ea | |||
| cec87f6caf | |||
| 22a9786168 | |||
| 18be60da9b | |||
| 4b6c79345b | |||
| f07100b7ea | |||
| 7083da367d | |||
| 8720a0faab | |||
| d8b1b3d777 | |||
| 4c2d95f8f1 | |||
| 9386c30d09 | |||
| 6638691c9f | |||
| d2bb70e8a1 | |||
| ef45d55521 | |||
| f86c53de89 | |||
| 82b275caaa | |||
| e524e5558d | |||
| 6593005566 | |||
| cf77f20d41 | |||
| 67ee2d9a74 | |||
| 48e5ddbc02 | |||
| e1737392a7 | |||
| 00b7b380b9 | |||
| 9821c8b2ea | |||
| c6a37f7e94 | |||
| f25c74c7e9 | |||
| 1c49d56b19 | |||
| 109ffd2898 | |||
| 7d5b93a62c | |||
| 6c0cb1a29c | |||
| d444b86ca8 | |||
| 185d7c58c2 | |||
| 283ec1d48a | |||
| f32a34a702 | |||
| afa09f4b8f | |||
| 24a3d8beb4 | |||
| 2a7ec1073f | |||
| d02fb4716a | |||
| 49bfad51b6 | |||
| 25ead15014 | |||
| 85a9d1c73b | |||
| 247fc8785a | |||
| efd1b371f9 | |||
| 3c73ddd443 | |||
| 29e9df97fb | |||
| fa95376fda | |||
| 028391386b | |||
| de937aceee | |||
| 2f4807cdda | |||
| d1791cadfe | |||
| 83fd9a94b0 | |||
| 562a8d159b | |||
| 1000dd12bc | |||
| 6f4afaf84a | |||
| 5de33a18f5 | |||
| 2aae2a8f90 | |||
| 6dcbd1efbf | |||
| a2ddb2313d | |||
| 6de7f64d3d | |||
| d0cae59070 | |||
| 6bd87ae0de | |||
| 0380ea3e98 | |||
| 9dba432542 | |||
| da608a0012 | |||
| 0af78e3dbd | |||
| 5db628311e | |||
| aa28a14d04 | |||
| 9c4e431e3b | |||
| 8984b1ecb7 | |||
| f05b0bbd8b | |||
| bff611f866 | |||
| b17e4c0a63 | |||
| f0b75d96db | |||
| 190975b981 | |||
| e4c9a88eca | |||
| 1f8fa367a5 | |||
| 5202fe0f8e | |||
| f202b34d28 | |||
| 07fa07eb22 | |||
| 137f9ae8bf | |||
| e44a8efa4a | |||
| a7b288c25f | |||
| 3dbcba5eb2 | |||
| bd2a640be0 | |||
| 889f2c05fc | |||
| c3f2afcaf5 | |||
| 32c85ea56b | |||
| 97210df0ba | |||
| 88be3525b5 | |||
| 7da7de1edc | |||
| 7592d67d69 | |||
| b75ac5c8b9 | |||
| 2954955e39 | |||
| 1fb20b1d08 | |||
| bfa0b350ac | |||
| 487013f301 | |||
| b16bb2d93a | |||
| 64997d74e9 | |||
| 297ed4ee45 | |||
| b4a094bc89 | |||
| e43706e2a6 | |||
| 2befc91d90 | |||
| 7a35f5177c | |||
| 6efc3ea790 | |||
| ef0f3ffbfb | |||
| 1e14cc695e | |||
| c074ccf460 | |||
| 5436469128 | |||
| 32714efeb9 | |||
| cf777571dc | |||
| 44b4340a91 | |||
| 24e3171311 | |||
| 575c1a11c2 | |||
| 47b8421d35 | |||
| 38d853a272 | |||
| 0320d6149f | |||
| ba9b3530fa | |||
| e78832e2c8 | |||
| 804060ad34 | |||
| 840519a437 | |||
| 7c54ebcbd0 | |||
| d07c0d67bf | |||
| a0ee2f7bb8 | |||
| d070288e17 | |||
| 681f80f6ab | |||
| eb5c87308a | |||
| 3e7fe1b5be | |||
| 552ca3026d | |||
| ba50e5a878 | |||
| acd1ce28f4 | |||
| 1b2b1bd447 | |||
| 7083d2369d | |||
| 8fed06b494 | |||
| 75650c19ab | |||
| ade47dadde | |||
| eaec617756 | |||
| 2199394abc | |||
| 93a18a8a20 | |||
| 2190b7af68 | |||
| 7da4956f1e | |||
| 31e27865bb | |||
| 967f213cba | |||
| 0e556aa794 | |||
| e2ac6099e3 | |||
| a4088e7acf | |||
| 550bd48fdb | |||
| f0f82a96fb | |||
| 8d303ea5af | |||
| c0b5c36115 | |||
| ba3c707da3 | |||
| b09f19f399 | |||
| 539f32911d | |||
| e009caaf25 | |||
| 1761ffbd3b | |||
| 33d6499dd4 | |||
| 3839eb2be4 | |||
| a04ab09ed6 | |||
| 89d6b920b1 | |||
| d425ed6b9e | |||
| e4215557c8 | |||
| fcc4045a4e | |||
| 5bcce71b36 | |||
| c9abec8a46 | |||
| 62e195d186 | |||
| e5f69a5e9a | |||
| e31ff492d5 | |||
| 99bbcda709 | |||
| 8aa941e704 | |||
| fdda30da67 | |||
| 399ee27af9 | |||
| d2c43b9ef1 | |||
| 7e6c6a037d | |||
| e1f19a1832 | |||
| 7b5cea3613 | |||
| 5d875d23e2 | |||
| e24fc6c81d | |||
| 72c6266474 | |||
| 4a711788f6 | |||
| c373c901a2 | |||
| 32846194b6 | |||
| 1a5d33b1f0 | |||
| 0e330a6529 | |||
| e9f0638ca2 | |||
| ce8fef79dc | |||
| b9fa0e2d60 | |||
| 41a04d6b53 | |||
| e527099b00 | |||
| 7e04cef964 | |||
| cb1208acaa | |||
| f985ce6402 | |||
| f54a36f240 | |||
| 4182f0993c | |||
| 28f7466595 | |||
| 6cfd4240de | |||
| 6e24015f76 | |||
| 5390c5cea8 | |||
| adcc81ba52 | |||
| 31a1f21dcd | |||
| b7316e15a2 | |||
| ad92ffa447 | |||
| 45044c0f61 | |||
| cc7c47cbab | |||
| 27f4006f05 | |||
| 576313a7b0 | |||
| 13c3feaa69 | |||
| a0dd8b925b | |||
| 21f187cac2 | |||
| d8951caddb | |||
| 206c657b98 | |||
| 6e262537a4 | |||
| 0587559939 | |||
| 939baec1a8 | |||
| 429f670c12 | |||
| b21d2ad864 | |||
| 8f841522a3 | |||
| fa7db66f4e | |||
| 499b22af15 | |||
| f992fb10bd | |||
| 603224e906 | |||
| bbea07b2a7 | |||
| b9d78efaff | |||
| 1a58099413 | |||
| e2d02d357c | |||
| 0812ff3467 | |||
| 6dafc26deb | |||
| a418ddbe52 | |||
| 6a5eb5a313 | |||
| 6354b03717 | |||
| 5d6b4a5255 | |||
| 3f0b1ccbcd | |||
| f00ecfd9ab | |||
| ee0d3370b1 | |||
| 73d7ed52dd | |||
| 6a31b0d579 | |||
| 869c4c0ae9 | |||
| 4be696ea62 | |||
| 83a0d56314 | |||
| 0d1418e595 | |||
| 7db521a72a | |||
| e7ff606891 | |||
| 60de3d8a31 | |||
| f12740dfa8 | |||
| 020a1c5682 | |||
| 576e2741a9 | |||
| bc19363bf9 | |||
| 72cf4b495e | |||
| b1db64a07d | |||
| 22affa7663 | |||
| b125d941ba | |||
| 9b37f130f3 | |||
| 993cd85e4a | |||
| e51586a78c | |||
| 8aa86fa553 | |||
| 510f7de693 | |||
| 918ae5b2d1 | |||
| 6263254a1b | |||
| 99e921c302 | |||
| 7f2f781a77 | |||
| 3571cc633e | |||
| 2011636173 | |||
| cbb15f4d6f | |||
| 33072900e9 | |||
| c98a50cd42 | |||
| 1f41dbcae5 | |||
| a918719b8f | |||
| 7b91e64af4 | |||
| 0afbeea01b | |||
| 0510cf2389 | |||
| c893f91ce2 | |||
| eced2f423f | |||
| 6eeb505701 | |||
| 4cb3f5d8ba | |||
| 372a8a9b2d | |||
| a714601c63 | |||
| 240d446b97 | |||
| 33e81a7668 | |||
| f8b75cca61 | |||
| 32e1bbd617 | |||
| 1de26004ab | |||
| 0a66c19b0a | |||
| 40d6b9905a | |||
| 228825053c | |||
| eda0f7a467 | |||
| 3052c9dfc5 | |||
| dbb4094eab | |||
| f875cd7b91 | |||
| 45f17100a2 | |||
| dda5a8d350 | |||
| 4f57ceaee9 | |||
| 2405e3e118 | |||
| d7aaadea2b | |||
| 8d07c7d741 | |||
| 2b260bccd5 | |||
| 7299394809 | |||
| 0b7afc0dd5 | |||
| f57e90941c | |||
| be6c5574ff | |||
| 859cca3820 | |||
| ba1cd1cd49 | |||
| a1f73b0307 | |||
| 3be14b945a | |||
| 675dff7314 | |||
| 2ff76c902b | |||
| 642015700e | |||
| 969ef8d1ed | |||
| b5f8216f7f | |||
| e6740d9b4f | |||
| 2e61b4c8ad | |||
| 62a0733a11 | |||
| 09aa8a5669 | |||
| 01c1a9c804 | |||
| 0a2f44cec8 | |||
| e7fa188797 |
+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": false
|
"disableAnalytics": true
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
# 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
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
+16
-7
@@ -1,17 +1,26 @@
|
|||||||
# 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
|
||||||
/node_modules
|
/bower_components/
|
||||||
/bower_components
|
/node_modules/
|
||||||
|
|
||||||
# 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
|
||||||
|
|||||||
@@ -1,32 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
extends: 'recommended',
|
||||||
|
|
||||||
|
rules: {
|
||||||
|
'simple-unless': false
|
||||||
|
}
|
||||||
|
};
|
||||||
+17
-10
@@ -1,25 +1,32 @@
|
|||||||
---
|
---
|
||||||
language: node_js
|
language: node_js
|
||||||
node_js:
|
node_js:
|
||||||
- "6"
|
- "10"
|
||||||
|
|
||||||
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,22 +10,24 @@ 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/)
|
||||||
* [PhantomJS](http://phantomjs.org/)
|
* [Google Chrome](https://google.com/chrome/)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
* `git clone <repository-url>` this repository
|
* `git clone git@github.com:67P/kredits-web.git` 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
|
||||||
|
|
||||||
@@ -36,6 +38,12 @@ 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)
|
||||||
@@ -43,11 +51,66 @@ Make use of the many generators for code, try `ember help generate` for more det
|
|||||||
|
|
||||||
### Deploying
|
### Deploying
|
||||||
|
|
||||||
Specify what it takes to deploy your app.
|
_(You need collaborator permissions on the 5apps Deploy project.)_
|
||||||
|
|
||||||
|
`npm run deploy`
|
||||||
|
|
||||||
|
## Working with locally deployed contracts
|
||||||
|
|
||||||
|
The smart contracts and their JavaScript wrapper library are developed in the
|
||||||
|
[kredits-contracts](https://github.com/67P/kredits-contracts) repo/package.
|
||||||
|
|
||||||
|
You can run `kredits-web` on your machine, against a local, simulated Ethereum
|
||||||
|
network, provided e.g. by [ganache](http://truffleframework.com/ganache/).
|
||||||
|
|
||||||
|
[kredits-contracts](https://github.com/67P/kredits-contracts) holds all the tools
|
||||||
|
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:
|
||||||
|
|
||||||
|
#### 1. IPFS
|
||||||
|
|
||||||
|
Run a local IPFS deamon in offline mode.
|
||||||
|
|
||||||
|
* Make sure CORS headers are configured. See [IPFS](#ipfs) for more info.
|
||||||
|
* `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](http://emberjs.com/)
|
* [ember.js](https://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)
|
||||||
|
|||||||
+2
-6
@@ -1,13 +1,9 @@
|
|||||||
import Ember from 'ember';
|
import Application from '@ember/application';
|
||||||
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';
|
||||||
|
|
||||||
let App;
|
const App = Application.extend({
|
||||||
|
|
||||||
Ember.MODEL_FACTORY_INJECTIONS = true;
|
|
||||||
|
|
||||||
App = Ember.Application.extend({
|
|
||||||
modulePrefix: config.modulePrefix,
|
modulePrefix: config.modulePrefix,
|
||||||
podModulePrefix: config.podModulePrefix,
|
podModulePrefix: config.podModulePrefix,
|
||||||
Resolver
|
Resolver
|
||||||
|
|||||||
@@ -0,0 +1,70 @@
|
|||||||
|
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));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
<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,68 +1,76 @@
|
|||||||
import Ember from 'ember';
|
import Component from '@ember/component';
|
||||||
|
import { and, notEmpty } from '@ember/object/computed';
|
||||||
|
import { inject as service } from '@ember/service';
|
||||||
|
import { isPresent } from '@ember/utils';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Component.extend({
|
||||||
|
|
||||||
id: null,
|
kredits: service(),
|
||||||
realName: null,
|
|
||||||
address: null,
|
attributes: null,
|
||||||
ipfsHash: null,
|
|
||||||
isCore: true,
|
// TODO: add proper address validation
|
||||||
|
isValidAccount: notEmpty('account'),
|
||||||
|
isValidName: notEmpty('name'),
|
||||||
|
isValidURL: notEmpty('url'),
|
||||||
|
isValidGithubUID: notEmpty('github_uid'),
|
||||||
|
isValidGithubUsername: notEmpty('github_username'),
|
||||||
|
isValidGiteaUsername: notEmpty('gitea_username'),
|
||||||
|
isValidWikiUsername: notEmpty('wiki_username'),
|
||||||
|
isValid: and(
|
||||||
|
'isValidAccount',
|
||||||
|
'isValidName',
|
||||||
|
'isValidGithubUID'
|
||||||
|
),
|
||||||
|
|
||||||
inProgress: false,
|
inProgress: false,
|
||||||
|
|
||||||
isValidId: function() {
|
init () {
|
||||||
return Ember.isPresent(this.get('id'));
|
this._super(...arguments);
|
||||||
}.property('id'),
|
this.setDefaultAttributes();
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
|
||||||
isValidRealName: function() {
|
setDefaultAttributes () {
|
||||||
return Ember.isPresent(this.get('realName'));
|
if (isPresent(this.attributes)) { return; }
|
||||||
}.property('realName'),
|
|
||||||
|
|
||||||
isValidAddress: function() {
|
this.set('attributes', {
|
||||||
return this.get('kredits.web3Instance').isAddress(this.get('address'));
|
account: null,
|
||||||
}.property('address'),
|
name: null,
|
||||||
|
kind: 'person',
|
||||||
isValid: function() {
|
url: null,
|
||||||
return this.get('isValidId') && this.get('isValidRealName') && this.get('isValidAddress');
|
github_username: null,
|
||||||
}.property('isValidAddress', 'isValidId', 'isValidRealName'),
|
github_uid: null,
|
||||||
|
gitea_username: null,
|
||||||
|
wiki_username: null
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
reset: function() {
|
reset: function() {
|
||||||
this.setProperties({
|
this.setProperties(this.attributes);
|
||||||
id: null,
|
|
||||||
realName: null,
|
|
||||||
address: null,
|
|
||||||
ipfsHash: null,
|
|
||||||
isCore: true,
|
|
||||||
inProgress: false
|
|
||||||
});
|
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
save() {
|
submit () {
|
||||||
if (!this.get('contractInteractionEnabled')) {
|
if (!this.isValid) {
|
||||||
alert('Only core team members can add new contributors. Please ask someone to set you up.');
|
alert('Invalid data. Please review and try again.');
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.get('isValid')) {
|
const attributes = Object.keys(this.attributes);
|
||||||
|
const contributor = this.getProperties(attributes);
|
||||||
|
|
||||||
this.set('inProgress', true);
|
this.set('inProgress', true);
|
||||||
|
|
||||||
this.get('kredits').addContributor(
|
this.save(contributor).then(() => {
|
||||||
this.get('address'),
|
|
||||||
this.get('realName'),
|
|
||||||
'', // TODO: this.get('ipfsHash')
|
|
||||||
this.get('isCore'),
|
|
||||||
this.get('id')
|
|
||||||
).then(contributor => {
|
|
||||||
this.reset();
|
this.reset();
|
||||||
this.get('contributors').pushObject(contributor);
|
}).catch(err => {
|
||||||
window.scroll(0,0);
|
console.warn(err);
|
||||||
|
window.alert('Something went wrong. Please check the browser console.');
|
||||||
|
}).finally(() => {
|
||||||
|
this.set('inProgress', false);
|
||||||
});
|
});
|
||||||
} else {
|
|
||||||
alert('Invalid data. Please review and try again.');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,50 @@
|
|||||||
<form {{action "save" on="submit"}}>
|
<form {{action "submit" on="submit"}}>
|
||||||
<p>
|
<p>
|
||||||
{{input name="id"
|
<label for="c-account">Ethereum account</label>
|
||||||
type="text"
|
{{input name="account" id="c-account"
|
||||||
placeholder="GitHub UID (123)"
|
type="text" value=account
|
||||||
value=id
|
|
||||||
class=(if isValidId 'valid' '')}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{input name="realname"
|
|
||||||
type="text"
|
|
||||||
placeholder="Carl Sagan"
|
|
||||||
value=realName
|
|
||||||
class=(if isValidRealName 'valid' '')}}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
{{input name="address"
|
|
||||||
type="text"
|
|
||||||
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
|
placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4"
|
||||||
value=address
|
class=(if isValidAccount "valid" "")}}
|
||||||
class=(if isValidAddress 'valid' '')}}
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="c-kind">Kind</label>
|
||||||
|
<select required onchange={{action (mut kind) value="target.value"}} id="c-kind">
|
||||||
|
<option value="person" selected={{eq kind "person"}}>Person</option>
|
||||||
|
<option value="organization" selected={{eq kind "organization"}}>Organization</option>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="c-name">Name</label>
|
||||||
|
{{input name="name" type="text" value=name placeholder="Zero Cool"
|
||||||
|
class=(if isValidName "valid" "") id="c-name"}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="c-url">URL</label>
|
||||||
|
{{input name="url" type="text" value=url placeholder="http://zerocool.bit"
|
||||||
|
class=(if isValidURL "valid" "") id="c-url"}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="c-github-uid">GitHub UID</label>
|
||||||
|
{{input name="github_uid" type="text" value=github_uid placeholder="2342"
|
||||||
|
class=(if isValidGithubUID "valid" "") id="c-github-uid"}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="c-github-username">GitHub username</label>
|
||||||
|
{{input name="github_username" type="text" value=github_username placeholder="zerocool"
|
||||||
|
class=(if isValidGithubUsername "valid" "") id="c-github-username"}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<label for="c-gitea-username">Gitea username</label>
|
||||||
|
{{input name="gitea_username" type="text" value=gitea_username placeholder="zerocool"
|
||||||
|
class=(if isValidGiteaUsername "valid" "") id="c-gitea-username"}}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<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" value=(if inProgress 'Processing' 'Save') disabled=inProgress}}
|
{{input type="submit" disabled=inProgress
|
||||||
|
value=(if inProgress "Processing" "Save")}}
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
|||||||
@@ -0,0 +1,64 @@
|
|||||||
|
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'),
|
||||||
|
isValidAmount: computed('amount', function() {
|
||||||
|
return parseInt(this.amount, 10) > 0;
|
||||||
|
}),
|
||||||
|
isValidDescription: notEmpty('description'),
|
||||||
|
isValidUrl: notEmpty('url'),
|
||||||
|
isValid: and('isValidContributor',
|
||||||
|
'isValidAmount',
|
||||||
|
'isValidDescription'),
|
||||||
|
|
||||||
|
init () {
|
||||||
|
this._super(...arguments);
|
||||||
|
|
||||||
|
// Default attributes used by reset
|
||||||
|
this.set('attributes', {
|
||||||
|
contributorId: null,
|
||||||
|
kind: 'community',
|
||||||
|
amount: null,
|
||||||
|
description: null,
|
||||||
|
url: null,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
didInsertElement() {
|
||||||
|
this._super(...arguments);
|
||||||
|
this.reset();
|
||||||
|
},
|
||||||
|
|
||||||
|
reset: function() {
|
||||||
|
this.setProperties(this.attributes);
|
||||||
|
},
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
submit() {
|
||||||
|
if (!this.isValid) {
|
||||||
|
alert('Invalid data. Please review and try again.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let attributes = Object.keys(this.attributes);
|
||||||
|
let proposal = this.getProperties(attributes);
|
||||||
|
let saved = this.save(proposal);
|
||||||
|
|
||||||
|
// The promise handles inProgress
|
||||||
|
this.set('inProgress', saved);
|
||||||
|
|
||||||
|
saved.then(() => {
|
||||||
|
this.reset();
|
||||||
|
window.scroll(0,0);
|
||||||
|
window.alert('Proposal added.');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
<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.github_username}}</option>
|
||||||
|
{{/each}}
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<select required onchange={{action (mut kind) value="target.value"}}>
|
||||||
|
<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>
|
||||||
|
</select>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{{input type="text"
|
||||||
|
placeholder="100"
|
||||||
|
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=(is-pending inProgress)
|
||||||
|
value=(if (is-pending inProgress) "Processing" "Save")}}
|
||||||
|
{{#link-to "index"}}Back{{/link-to}}
|
||||||
|
</p>
|
||||||
|
</form>
|
||||||
|
|
||||||
@@ -0,0 +1,64 @@
|
|||||||
|
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'
|
||||||
|
],
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
<div class="chart">
|
||||||
|
{{ember-chart type="doughnut"
|
||||||
|
data=chartData
|
||||||
|
options=chartOptions
|
||||||
|
width=200
|
||||||
|
height=200}}
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
import Component from '@ember/component';
|
||||||
|
|
||||||
|
export default Component.extend({
|
||||||
|
|
||||||
|
tagName: 'ul',
|
||||||
|
classNames: ['contribution-list'],
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
|
||||||
|
veto (contributionId) {
|
||||||
|
if (this.contractInteractionEnabled) {
|
||||||
|
this.vetoContribution(contributionId);
|
||||||
|
} else {
|
||||||
|
window.alert('Only members can veto contributions. Please ask someone to set you up.');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
{{#each contributions as |contribution|}}
|
||||||
|
<li data-contribution-id={{contribution.id}} class="{{contribution-status contribution}} {{if contribution.vetoed "vetoed"}}">
|
||||||
|
<p class="meta">
|
||||||
|
<span class="recipient">{{user-avatar contributor=contribution.contributor}}</span>
|
||||||
|
<span class="category {{contribution.kind}}">({{contribution.kind}})</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>
|
||||||
|
{{/each}}
|
||||||
@@ -1,8 +1,22 @@
|
|||||||
import Ember from 'ember';
|
import Component from '@ember/component';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Component.extend({
|
||||||
|
|
||||||
tagName: 'table',
|
tagName: 'table',
|
||||||
classNames: 'contributor-list'
|
classNames: 'contributor-list',
|
||||||
|
selectedContributor: null,
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
|
||||||
|
toggleContributorInfo(contributor) {
|
||||||
|
if (contributor.showMetadata) {
|
||||||
|
contributor.set('showMetadata', false);
|
||||||
|
} else {
|
||||||
|
this.contributorList.setEach('showMetadata', false);
|
||||||
|
contributor.set('showMetadata', true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,14 +1,39 @@
|
|||||||
<tbody>
|
<tbody>
|
||||||
{{#each contributors as |contributor|}}
|
{{#each contributorList as |c|}}
|
||||||
<tr class="{{if contributor.isCurrentUser 'current-user'}}">
|
<tr role="button" class={{if (is-current-user c.contributor) "current-user"}} {{action "toggleContributorInfo" c}}>
|
||||||
<td class="person">
|
<td class="person">
|
||||||
<img class="avatar" src={{contributor.avatarURL}}>
|
{{user-avatar contributor=c.contributor}} {{c.contributor.name}}
|
||||||
{{contributor.github_username}}
|
|
||||||
</td>
|
</td>
|
||||||
<td class="kredits">
|
<td class="kredits">
|
||||||
<span class="amount">{{contributor.kredits}}</span>
|
<span class="amount">
|
||||||
|
{{#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"}}">
|
||||||
|
<td colspan="2">
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<a href="https://rinkeby.etherscan.io/address/{{c.contributor.account}}" target="_blank" rel="noopener">Inspect Ethereum transactions</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}}
|
||||||
|
<li>
|
||||||
|
{{link-to "Edit profile" "contributors.edit" c.contributor.id}}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
{{#if c.showMetadata}}
|
||||||
|
<pre>{{c.contributor.ipfsData}}</pre>
|
||||||
|
{{/if}}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Ember from 'ember';
|
import Component from '@ember/component';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Component.extend({
|
||||||
|
|
||||||
classNames: ['loading-spinner']
|
classNames: ['loading-spinner']
|
||||||
|
|
||||||
|
|||||||
@@ -10,5 +10,5 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Loading data from Ethereum...
|
Loading data...
|
||||||
</p>
|
</p>
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import Ember from 'ember';
|
import Component from '@ember/component';
|
||||||
|
|
||||||
export default Ember.Component.extend({
|
export default Component.extend({
|
||||||
|
|
||||||
tagName: 'ul',
|
tagName: 'ul',
|
||||||
classNames: ['proposal-list'],
|
classNames: ['proposal-list'],
|
||||||
@@ -8,8 +8,8 @@ export default Ember.Component.extend({
|
|||||||
actions: {
|
actions: {
|
||||||
|
|
||||||
confirm(proposalId) {
|
confirm(proposalId) {
|
||||||
if (this.get('contractInteractionEnabled')) {
|
if (this.contractInteractionEnabled) {
|
||||||
this.sendAction('confirmAction', proposalId);
|
this.confirmProposal(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,11 +1,20 @@
|
|||||||
{{#each proposals as |proposal|}}
|
{{#each proposals as |proposal|}}
|
||||||
<li>
|
<li data-proposal-id={{proposal.id}} class={{if proposal.isExecuted "confirmed" "unconfirmed"}}>
|
||||||
<span class="id">#{{proposal.id}}</span>
|
<p class="meta">
|
||||||
Issue{{#if proposal.executed}}d{{/if}}
|
<span class="category {{proposal.kind}}">♥ ({{proposal.kind}})</span>
|
||||||
|
<span class="recipient">{{proposal.contributor.name}}:</span>
|
||||||
|
</p>
|
||||||
|
<p class="kredits-amount">
|
||||||
<span class="amount">{{proposal.amount}}</span><span class="symbol">₭S</span>
|
<span class="amount">{{proposal.amount}}</span><span class="symbol">₭S</span>
|
||||||
to <span class="recipient" title="{{proposal.recipientAddress}}">{{proposal.recipientName}}</span>
|
</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>
|
<span class="votes">({{proposal.votesCount}}/{{proposal.votesNeeded}} votes)</span>
|
||||||
|
<button {{action "confirm" proposal.id}}>+1</button>
|
||||||
{{#unless proposal.executed}}<button {{action "confirm" proposal.id}}>+1</button>{{/unless}}
|
{{/unless}}
|
||||||
|
</p>
|
||||||
</li>
|
</li>
|
||||||
{{/each}}
|
{{/each}}
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
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,4 +1,6 @@
|
|||||||
import Ember from 'ember';
|
import Controller from '@ember/controller';
|
||||||
|
import { inject as service } from '@ember/service';
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
export default Controller.extend({
|
||||||
|
kredits: service(),
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
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;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
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'))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
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'))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
+27
-126
@@ -1,142 +1,43 @@
|
|||||||
import Ember from 'ember';
|
import Controller from '@ember/controller';
|
||||||
import Proposal from 'kredits-web/models/proposal';
|
import { computed } from '@ember/object';
|
||||||
|
import { alias, not, sort } from '@ember/object/computed';
|
||||||
const {
|
import { inject as service } from '@ember/service';
|
||||||
computed,
|
|
||||||
inject: {
|
|
||||||
service
|
|
||||||
}
|
|
||||||
} = Ember;
|
|
||||||
|
|
||||||
export default Ember.Controller.extend({
|
|
||||||
|
|
||||||
|
export default Controller.extend({
|
||||||
kredits: service(),
|
kredits: service(),
|
||||||
|
currentBlock: alias('kredits.currentBlock'),
|
||||||
|
|
||||||
contractInteractionEnabled: computed.alias('kredits.web3Provided'),
|
contributions: alias('kredits.contributions'),
|
||||||
|
contributionsConfirmed: alias('kredits.contributionsConfirmed'),
|
||||||
|
contributionsUnconfirmed: alias('kredits.contributionsUnconfirmed'),
|
||||||
|
|
||||||
findContributorByAddress(address) {
|
contributionsSorting: Object.freeze(['date:desc', 'time:desc', 'id:desc']),
|
||||||
return this.get('model.contributors')
|
contributionsUnconfirmedSorted: sort('contributionsUnconfirmed', 'contributionsSorting'),
|
||||||
.findBy('address', address);
|
contributionsConfirmedSorted: sort('contributionsConfirmed', 'contributionsSorting'),
|
||||||
},
|
|
||||||
|
|
||||||
proposalsOpen: function() {
|
kreditsByContributor: alias('kredits.kreditsByContributor'),
|
||||||
let proposals = this.get('model.proposals')
|
|
||||||
.filterBy('executed', false)
|
|
||||||
.map(p => {
|
|
||||||
p.set('recipientName', this.findContributorByAddress(p.get('recipientAddress')).github_username);
|
|
||||||
return p;
|
|
||||||
});
|
|
||||||
return proposals;
|
|
||||||
}.property('model.proposals.[]', 'model.proposals.@each.executed', 'model.contributors.[]'),
|
|
||||||
|
|
||||||
proposalsClosed: function() {
|
kreditsToplistSorting: computed('showUnconfirmedKredits', function(){
|
||||||
let proposals = this.get('model.proposals')
|
return this.showUnconfirmedKredits ? ['amountTotal:desc'] : ['amountConfirmed:desc'];
|
||||||
.filterBy('executed', true)
|
}),
|
||||||
.map(p => {
|
kreditsToplist: sort('kreditsByContributor', 'kreditsToplistSorting'),
|
||||||
p.set('recipientName', this.findContributorByAddress(p.get('recipientAddress')).github_username);
|
|
||||||
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'),
|
|
||||||
|
|
||||||
contributorsSorting: ['kredits:desc'],
|
|
||||||
contributorsSorted: Ember.computed.sort('model.contributors', '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) {
|
||||||
|
this.kredits.veto(contributionId).then(transaction => {
|
||||||
|
console.debug('[controllers:index] Veto submitted to Ethereum blockhain: '+transaction.hash);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
confirmProposal (proposalId) {
|
confirmProposal (proposalId) {
|
||||||
this.get('kredits').vote(proposalId).then(transactionId => {
|
this.kredits.vote(proposalId).then(transaction => {
|
||||||
window.confirm('Vote submitted to Ethereum blockhain: '+transactionId);
|
console.debug('[controllers:index] Vote submitted to Ethereum blockhain: '+transaction.hash);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
import Controller from '@ember/controller';
|
||||||
|
import { alias, filterBy } 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'),
|
||||||
|
|
||||||
|
actions: {
|
||||||
|
save(proposal) {
|
||||||
|
// 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.
|
||||||
|
let contributor = this.contributors.findBy('id', proposal.contributorId);
|
||||||
|
proposal.contributorIpfsHash = contributor.get('ipfsHash');
|
||||||
|
|
||||||
|
return this.kredits.addProposal(proposal)
|
||||||
|
.then((proposal) => {
|
||||||
|
this.transitionToRoute('index');
|
||||||
|
return proposal;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
+9
-3
@@ -3,16 +3,22 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<title>Kredits</title>
|
<title>Kosmos Kredits</title>
|
||||||
<meta name="description" content="">
|
<meta name="description" content="">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
|
|
||||||
{{content-for "head"}}
|
{{content-for "head"}}
|
||||||
|
|
||||||
<link rel="stylesheet" href="{{rootURL}}assets/vendor.css">
|
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/vendor.css">
|
||||||
<link rel="stylesheet" href="{{rootURL}}assets/kredits-web.css">
|
<link integrity="" rel="stylesheet" href="{{rootURL}}assets/kredits-web.css">
|
||||||
|
|
||||||
{{content-for "head-footer"}}
|
{{content-for "head-footer"}}
|
||||||
|
|
||||||
|
<script>
|
||||||
|
window.addEventListener('load', function() {
|
||||||
|
window.windowLoadComplete = true;
|
||||||
|
});
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
{{content-for "body"}}
|
{{content-for "body"}}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
import EmberObject from '@ember/object';
|
||||||
|
import bignumber from 'kredits-web/utils/cps/bignumber';
|
||||||
|
|
||||||
|
export default EmberObject.extend({
|
||||||
|
|
||||||
|
// Contract
|
||||||
|
id: null,
|
||||||
|
contributorId: null,
|
||||||
|
amount: null,
|
||||||
|
confirmedAt: bignumber('confirmedAtBlock', 'toNumber'),
|
||||||
|
vetoed: null,
|
||||||
|
ipfsHash: null,
|
||||||
|
|
||||||
|
creatorAccount: null,
|
||||||
|
|
||||||
|
// IPFS
|
||||||
|
kind: null,
|
||||||
|
description: null,
|
||||||
|
details: null,
|
||||||
|
url: null,
|
||||||
|
ipfsData: '',
|
||||||
|
|
||||||
|
init () {
|
||||||
|
this._super(...arguments);
|
||||||
|
this.set('details', {});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
+25
-10
@@ -1,16 +1,31 @@
|
|||||||
import Ember from 'ember';
|
import { computed } from '@ember/object';
|
||||||
|
import EmberObject from '@ember/object';
|
||||||
|
import bignumber from 'kredits-web/utils/cps/bignumber';
|
||||||
|
import kreditsValue from 'kredits-web/utils/cps/kredits';
|
||||||
|
|
||||||
export default Ember.Object.extend({
|
export default EmberObject.extend({
|
||||||
|
// Contract
|
||||||
|
id: bignumber('idRaw', 'toString'),
|
||||||
|
account: null,
|
||||||
|
balance: kreditsValue('balanceRaw'),
|
||||||
|
totalKreditsEarned: bignumber('totalKreditsEarnedRaw', 'toNumber'),
|
||||||
|
contributionsCount: bignumber('contributionsCountRaw', 'toNumber'),
|
||||||
|
isCore: false,
|
||||||
|
ipfsHash: null,
|
||||||
|
|
||||||
address: null,
|
// IPFS
|
||||||
|
kind: null,
|
||||||
|
name: null,
|
||||||
|
url: null,
|
||||||
github_username: null,
|
github_username: null,
|
||||||
github_uid: null,
|
github_uid: null,
|
||||||
ipfsHash: null,
|
wiki_username: null,
|
||||||
kredits: null,
|
ipfsData: '',
|
||||||
isCurrentUser: false,
|
|
||||||
|
|
||||||
avatarURL: function() {
|
|
||||||
return `https\:\/\/avatars2.githubusercontent.com/u/${this.get('github_uid')}?v=3&s=128`;
|
|
||||||
}.property('github_uid')
|
|
||||||
|
|
||||||
|
avatarURL: computed('github_uid', function() {
|
||||||
|
let github_uid = this.github_uid;
|
||||||
|
if (github_uid) {
|
||||||
|
return `https://avatars2.githubusercontent.com/u/${github_uid}?v=3&s=128`;
|
||||||
|
}
|
||||||
|
}),
|
||||||
});
|
});
|
||||||
|
|||||||
+26
-10
@@ -1,16 +1,32 @@
|
|||||||
import Ember from 'ember';
|
import EmberObject from '@ember/object';
|
||||||
|
import { alias } from '@ember/object/computed';
|
||||||
|
import bignumber from 'kredits-web/utils/cps/bignumber';
|
||||||
|
|
||||||
export default Ember.Object.extend({
|
export default EmberObject.extend({
|
||||||
|
|
||||||
id: null,
|
// Contract
|
||||||
creatorAddress: null,
|
id: bignumber('idRaw', 'toString'),
|
||||||
recipientAddress: null,
|
creatorAccount: null,
|
||||||
recipientName: null,
|
contributorId: bignumber('contributorIdRaw', 'toString'),
|
||||||
votesCount: null,
|
amount: bignumber('amountRaw', 'toNumber'),
|
||||||
votesNeeded: null,
|
votesCount: bignumber('votesCountRaw', 'toNumber'),
|
||||||
amount: null,
|
votesNeeded: bignumber('votesNeededRaw', 'toNumber'),
|
||||||
executed: null,
|
executed: null,
|
||||||
|
ipfsHash: null,
|
||||||
|
|
||||||
|
// Shortcuts
|
||||||
|
isExecuted: alias('executed'),
|
||||||
|
|
||||||
|
// IPFS
|
||||||
|
kind: null,
|
||||||
|
description: null,
|
||||||
|
details: null,
|
||||||
url: null,
|
url: null,
|
||||||
ipfsHash: null
|
ipfsData: '',
|
||||||
|
|
||||||
|
init () {
|
||||||
|
this._super(...arguments);
|
||||||
|
this.set('details', {});
|
||||||
|
}
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|||||||
+12
-3
@@ -1,13 +1,22 @@
|
|||||||
import Ember from 'ember';
|
import EmberRouter from '@ember/routing/router';
|
||||||
import config from './config/environment';
|
import config from './config/environment';
|
||||||
|
|
||||||
const Router = Ember.Router.extend({
|
const Router = EmberRouter.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('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,4 +1,31 @@
|
|||||||
import Ember from 'ember';
|
import { inject as service } from '@ember/service';
|
||||||
|
import Route from '@ember/routing/route';
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
export default 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();
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,29 @@
|
|||||||
|
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
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
import Ember from 'ember';
|
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
|
||||||
|
|
||||||
kredits: Ember.inject.service(),
|
|
||||||
|
|
||||||
model() {
|
|
||||||
let kredits = this.get('kredits');
|
|
||||||
|
|
||||||
return Ember.RSVP.hash({
|
|
||||||
contributors: kredits.getContributors(),
|
|
||||||
totalSupply: kredits.getValueFromContract('totalSupply'),
|
|
||||||
contributorsCount: kredits.getValueFromContract('contributorsCount'),
|
|
||||||
proposals: kredits.getProposals()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
import Ember from 'ember';
|
|
||||||
|
|
||||||
export default Ember.Route.extend({
|
|
||||||
});
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
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 => {
|
|
||||||
return res[0].hash;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
|
|
||||||
getFile(hash) {
|
|
||||||
return this.get('ipfs').cat(hash, { buffer: true }).then(res => {
|
|
||||||
return res.toString();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
});
|
|
||||||
+358
-122
@@ -1,164 +1,400 @@
|
|||||||
import Ember from 'ember';
|
import ethers from 'npm:ethers';
|
||||||
import Web3 from 'npm:web3';
|
import Kredits from 'npm:kredits-contracts';
|
||||||
|
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 kreditsContracts from 'npm:kredits-contracts';
|
import Contribution from 'kredits-web/models/contribution'
|
||||||
|
|
||||||
export default Ember.Service.extend({
|
export default Service.extend({
|
||||||
|
|
||||||
ipfs: Ember.inject.service(),
|
currentBlock: null,
|
||||||
|
currentUserAccounts: null, // default to not having an account. this is the wen web3 is loaded.
|
||||||
|
currentUser: null,
|
||||||
|
contributors: null,
|
||||||
|
contributions: null,
|
||||||
|
proposals: null,
|
||||||
|
|
||||||
web3Instance: null,
|
currentUserIsContributor: notEmpty('currentUser'),
|
||||||
web3Provided: false, // Web3 provided (using Mist Browser, Metamask et al.)
|
currentUserIsCore: alias('currentUser.isCore'),
|
||||||
|
hasAccounts: notEmpty('currentUserAccounts'),
|
||||||
|
|
||||||
web3: function() {
|
accountNeedsUnlock: computed('currentUserAccounts', function() {
|
||||||
if (this.get('web3Instance')) {
|
return this.currentUserAccounts && isEmpty(this.currentUserAccounts);
|
||||||
return this.get('web3Instance');
|
}),
|
||||||
|
|
||||||
|
contributionsUnconfirmed: computed('contributions.[]', 'currentBlock', function() {
|
||||||
|
return this.contributions.filter(contribution => {
|
||||||
|
return contribution.confirmedAt > this.currentBlock;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
|
contributionsConfirmed: computed('contributions.[]', 'currentBlock', function() {
|
||||||
|
return this.contributions
|
||||||
|
.filterBy('vetoed', false)
|
||||||
|
.filter(contribution => {
|
||||||
|
return contribution.confirmedAt <= this.currentBlock;
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
|
kreditsByContributor: computed('contributionsUnconfirmed.@each.vetoed', 'contributors.[]', function() {
|
||||||
|
const contributionsUnconfirmed = this.contributionsUnconfirmed.filterBy('vetoed', false);
|
||||||
|
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 => {
|
||||||
|
const amountUnconfirmed = c.items.mapBy('amount').reduce((a, b) => a + b);
|
||||||
|
const contributor = this.contributors.findBy('id', c.value.toString());
|
||||||
|
|
||||||
|
return EmberObject.create({
|
||||||
|
contributor: contributor,
|
||||||
|
amountUnconfirmed: amountUnconfirmed,
|
||||||
|
amountConfirmed: contributor.totalKreditsEarned,
|
||||||
|
amountTotal: contributor.totalKreditsEarned + amountUnconfirmed
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
contributorsWithOnlyConfirmed.forEach(c => {
|
||||||
|
kreditsByContributor.push(EmberObject.create({
|
||||||
|
contributor: c,
|
||||||
|
amountUnconfirmed: 0,
|
||||||
|
amountConfirmed: c.totalKreditsEarned,
|
||||||
|
amountTotal: c.totalKreditsEarned
|
||||||
|
}));
|
||||||
|
})
|
||||||
|
|
||||||
|
return kreditsByContributor;
|
||||||
|
}),
|
||||||
|
|
||||||
|
init () {
|
||||||
|
this._super(...arguments);
|
||||||
|
this.set('contributors', []);
|
||||||
|
this.set('proposals', []);
|
||||||
|
this.set('contributions', []);
|
||||||
|
},
|
||||||
|
|
||||||
|
// This is called in the application route's beforeModel(). So it is
|
||||||
|
// initialized before everything else, and we can rely on the ethProvider and
|
||||||
|
// the potential currentUserAccounts to be available
|
||||||
|
getEthProvider () {
|
||||||
|
let ethProvider;
|
||||||
|
|
||||||
|
return new RSVP.Promise(async (resolve) => {
|
||||||
|
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
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
let web3Instance;
|
async function instantiateWithAccount (web3Provider, context) {
|
||||||
|
console.debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
|
||||||
if (typeof window.web3 !== 'undefined') {
|
ethProvider = new ethers.providers.Web3Provider(web3Provider);
|
||||||
Ember.Logger.debug('[kredits] Using user-provided instance, e.g. from Mist browser or Metamask');
|
// const network = await ethProvider.getNetwork();
|
||||||
web3Instance = window.web3;
|
ethProvider.listAccounts().then(accounts => {
|
||||||
this.set('web3Provided', true);
|
context.set('currentUserAccounts', accounts);
|
||||||
} else {
|
const ethSigner = accounts.length === 0 ? null : ethProvider.getSigner();
|
||||||
Ember.Logger.debug('[kredits] Creating new instance from npm module class');
|
resolve({
|
||||||
let provider = new Web3.providers.HttpProvider(config.web3ProviderUrl);
|
ethProvider,
|
||||||
web3Instance = new Web3(provider);
|
ethSigner
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
this.set('web3Instance', web3Instance);
|
if (window.ethereum) {
|
||||||
window.web3 = web3Instance;
|
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();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
return web3Instance;
|
setup () {
|
||||||
}.property('web3Instance'),
|
return this.getEthProvider().then((providerAndSigner) => {
|
||||||
|
let kredits = new Kredits(providerAndSigner.ethProvider, providerAndSigner.ethSigner, {
|
||||||
|
addresses: { Kernel: config.kreditsKernelAddress },
|
||||||
|
apm: config.kreditsApmDomain,
|
||||||
|
ipfsConfig: config.ipfs
|
||||||
|
});
|
||||||
|
return kredits
|
||||||
|
.init()
|
||||||
|
.then(async (kredits) => {
|
||||||
|
this.set('kredits', kredits);
|
||||||
|
this.set('currentBlock', await kredits.provider.getBlockNumber());
|
||||||
|
|
||||||
currentUserAccounts: function() {
|
if (this.currentUserAccounts && this.currentUserAccounts.length > 0) {
|
||||||
return (this.get('web3Provided') && this.get('web3').eth.accounts) || [];
|
this.getCurrentUser.then((contributorData) => {
|
||||||
}.property('web3', 'web3Provided'),
|
this.set('currentUser', contributorData);
|
||||||
|
});
|
||||||
kreditsContract: function() {
|
|
||||||
if (this.get('kreditsContractInstance')) {
|
|
||||||
return this.get('kreditsContractInstance');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(config.ethereumChain);
|
return kredits;
|
||||||
let contract = kreditsContracts(this.get('web3'), config.ethereumChain)['Kredits'];
|
|
||||||
|
|
||||||
this.set('kreditsContractInstance', contract);
|
|
||||||
return contract;
|
|
||||||
}.property('web3'),
|
|
||||||
|
|
||||||
getValueFromContract(contractMethod, ...args) {
|
|
||||||
return new Ember.RSVP.Promise((resolve, reject) => {
|
|
||||||
this.get('kreditsContract')[contractMethod](...args, (err, data) => {
|
|
||||||
if (err) { reject(err); }
|
|
||||||
resolve(data);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getContributorData(i) {
|
totalSupply: computed(function() {
|
||||||
let promise = new Ember.RSVP.Promise((resolve, reject) => {
|
return this.kredits.Token.functions.totalSupply().then(total => {
|
||||||
this.getValueFromContract('contributorAddresses', i).then(address => {
|
return formatKredits(total);
|
||||||
this.getValueFromContract('contributors', address).then(person => {
|
})
|
||||||
this.getValueFromContract('balanceOf', address).then(balance => {
|
}),
|
||||||
let contributor = Contributor.create({
|
|
||||||
address: address,
|
totalKreditsEarned: computed(function() {
|
||||||
github_username: person[1],
|
return this.kredits.Contribution.functions.totalKreditsEarned(true)
|
||||||
github_uid: person[0],
|
.then(total => total.toNumber());
|
||||||
ipfsHash: person[3],
|
}),
|
||||||
kredits: balance.toNumber(),
|
|
||||||
isCurrentUser: this.get('currentUserAccounts').includes(address)
|
|
||||||
|
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);
|
||||||
});
|
});
|
||||||
Ember.Logger.debug('[kredits] contributor', contributor);
|
},
|
||||||
resolve(contributor);
|
|
||||||
|
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);
|
||||||
});
|
});
|
||||||
});
|
|
||||||
}).catch(err => reject(err));
|
|
||||||
});
|
|
||||||
return promise;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getContributors () {
|
getContributors () {
|
||||||
return this.getValueFromContract('contributorsCount').then(contributorsCount => {
|
return this.kredits.Contributor.all()
|
||||||
let contributors = [];
|
.then((contributors) => {
|
||||||
|
return contributors.map((contributor) => {
|
||||||
for(var i = 0; i < contributorsCount.toNumber(); i++) {
|
return Contributor.create(contributor);
|
||||||
contributors.push(this.getContributorData(i));
|
});
|
||||||
}
|
|
||||||
|
|
||||||
return Ember.RSVP.all(contributors);
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
getProposalData(i) {
|
addContribution (attributes) {
|
||||||
let promise = new Ember.RSVP.Promise((resolve, reject) => {
|
console.debug('[kredits] add contribution', attributes);
|
||||||
this.getValueFromContract('proposals', i).then(p => {
|
|
||||||
let proposal = Proposal.create({
|
return this.kredits.Contribution.addContribution(attributes, { gasLimit: 300000 })
|
||||||
id : i,
|
.then(data => {
|
||||||
creatorAddress : p[0],
|
console.debug('[kredits] add contribution response', data);
|
||||||
recipientAddress : p[1],
|
attributes.contributor = this.contributors.findBy('id', attributes.contributorId);
|
||||||
votesCount : p[2].toNumber(),
|
const contribution = Contribution.create(attributes);
|
||||||
votesNeeded : p[3].toNumber(),
|
// TODO receive from wrapper
|
||||||
amount : p[4].toNumber(),
|
contribution.set('confirmedAtBlock', data.blockNumber + 40320);
|
||||||
executed : p[5],
|
this.contributions.pushObject(contribution);
|
||||||
url : p[6],
|
return contribution;
|
||||||
ipfsHash : p[7]
|
|
||||||
});
|
});
|
||||||
Ember.Logger.debug('[kredits] proposal', proposal);
|
},
|
||||||
resolve(proposal);
|
|
||||||
}).catch(err => reject(err));
|
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);
|
||||||
});
|
});
|
||||||
return promise;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
getProposals () {
|
getProposals () {
|
||||||
return this.getValueFromContract('proposalsCount').then(proposalsCount => {
|
return this.kredits.Proposal.all()
|
||||||
let proposals = [];
|
.then((proposals) => {
|
||||||
|
return proposals.map((proposal) => {
|
||||||
|
proposal.contributor = this.contributors.findBy('id', proposal.contributorId.toString());
|
||||||
|
return Proposal.create(proposal);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
for(var i = 0; i < proposalsCount.toNumber(); i++) {
|
getContributions () {
|
||||||
proposals.push(this.getProposalData(i));
|
return this.kredits.Contribution.all({page: {size: 200}})
|
||||||
}
|
.then(contributions => {
|
||||||
|
return contributions.map(contribution => {
|
||||||
return Ember.RSVP.all(proposals);
|
contribution.contributor = this.contributors.findBy('id', contribution.contributorId.toString());
|
||||||
|
return Contribution.create(contribution);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
vote (proposalId) {
|
vote (proposalId) {
|
||||||
Ember.Logger.debug('[kredits] vote for', proposalId);
|
console.debug('[kredits] vote for', proposalId);
|
||||||
return new Ember.RSVP.Promise((resolve, reject) => {
|
|
||||||
this.get('kreditsContract').vote(proposalId, (err, data) => {
|
return this.kredits.Proposal.functions.vote(proposalId)
|
||||||
if (err) { reject(err); }
|
.then(data => {
|
||||||
Ember.Logger.debug('[kredits] vote response', data);
|
console.debug('[kredits] vote response', data);
|
||||||
resolve(data);
|
return data;
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
addContributor(address, name, ipfsHash, isCore, id) {
|
veto (contributionId) {
|
||||||
Ember.Logger.debug('[kredits] add contributor', name, address);
|
console.debug('[kredits] veto against', contributionId);
|
||||||
return new Ember.RSVP.Promise((resolve, reject) => {
|
|
||||||
this.get('kreditsContract').addContributor(address, name, ipfsHash, isCore, id, (err, data) => {
|
return this.kredits.Contribution.functions.veto(contributionId, { gasLimit: 300000 })
|
||||||
if (err) { reject(err); }
|
.then(data => {
|
||||||
Ember.Logger.debug('[kredits] add contributor response', data);
|
console.debug('[kredits] veto response', data);
|
||||||
let contributor = Contributor.create({
|
return data;
|
||||||
address: address,
|
|
||||||
github_username: name,
|
|
||||||
github_uid: id,
|
|
||||||
ipfsHash: ipfsHash,
|
|
||||||
kredits: 0,
|
|
||||||
isCurrentUser: this.get('currentUserAccounts').includes(address)
|
|
||||||
});
|
|
||||||
resolve(contributor);
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
logKreditsContract: function() {
|
getCurrentUser: computed('kredits.provider', function() {
|
||||||
Ember.Logger.debug('[kredits] kreditsContract', this.get('kreditsContract'));
|
if (isEmpty(this.currentUserAccounts)) {
|
||||||
}.on('init')
|
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 {
|
||||||
|
return this.kredits.Contributor.getById(id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
|
||||||
|
findProposalById(proposalId) {
|
||||||
|
return this.proposals.findBy('id', proposalId.toString());
|
||||||
|
},
|
||||||
|
|
||||||
|
// Contract events
|
||||||
|
addContractEventHandlers () {
|
||||||
|
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));
|
||||||
|
},
|
||||||
|
|
||||||
|
async handleContributorChange (contributorId, ...args) {
|
||||||
|
console.debug('[kredits] Contributor add/update event received for ID', contributorId);
|
||||||
|
console.debug('[kredits] Event data:', args);
|
||||||
|
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
|
||||||
|
handleProposalVoted (proposalId, voterId, totalVotes) {
|
||||||
|
let proposal = this.findProposalById(proposalId);
|
||||||
|
|
||||||
|
if (proposal) {
|
||||||
|
proposal.set('votesCount', totalVotes);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
handleProposalExecuted (proposalId, contributorId, amount) {
|
||||||
|
let proposal = this.findProposalById(proposalId);
|
||||||
|
|
||||||
|
if (proposal.get('isExecuted')) {
|
||||||
|
console.debug('[events] proposal already executed, not adding from event');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
proposal.set('executed', true);
|
||||||
|
|
||||||
|
this.contributors
|
||||||
|
.findBy('id', contributorId.toString())
|
||||||
|
.incrementProperty('balance', amount);
|
||||||
|
},
|
||||||
|
|
||||||
|
handleTransfer (from, to, value) {
|
||||||
|
value = value.toNumber();
|
||||||
|
|
||||||
|
this.contributors
|
||||||
|
.findBy('address', from)
|
||||||
|
.decrementProperty('balance', value);
|
||||||
|
|
||||||
|
this.contributors
|
||||||
|
.findBy('address', to)
|
||||||
|
.incrementProperty('balance', value);
|
||||||
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
$blue: #68d7fb;
|
||||||
|
$purple: #8f68fb;
|
||||||
|
$pink: #e068fb;
|
||||||
|
$green: #97fb68;
|
||||||
|
$yellow: #fbe468;
|
||||||
|
$red: #fb6868;
|
||||||
|
|
||||||
|
$primary-color: $blue;
|
||||||
|
|
||||||
|
$body-text-color: #fff;
|
||||||
|
|
||||||
|
#topbar {
|
||||||
|
background-color: rgba(255, 0, 255, .2);
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,107 @@
|
|||||||
|
section#add-contributor,
|
||||||
|
section#add-contribution,
|
||||||
|
section#add-proposal {
|
||||||
|
|
||||||
|
form {
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 1.5rem;
|
||||||
|
|
||||||
|
&.actions {
|
||||||
|
padding-top: 1.5rem;
|
||||||
|
text-align: center;
|
||||||
|
a {
|
||||||
|
color: $primary-color;
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
margin-bottom: 0.5rem;
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=text], select {
|
||||||
|
width: 100%;
|
||||||
|
padding: 1rem;
|
||||||
|
border: none;
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.2);
|
||||||
|
background-color: rgba(22, 21, 40, 0.3);
|
||||||
|
color: #fff;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
transition: border-color 0.1s linear;
|
||||||
|
|
||||||
|
&:focus, &.valid {
|
||||||
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
|
}
|
||||||
|
&:focus {
|
||||||
|
border-color: $blue;
|
||||||
|
}
|
||||||
|
&::placeholder {
|
||||||
|
color: rgba(238, 238, 238, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
select {
|
||||||
|
-moz-appearance: none;
|
||||||
|
-webkit-appearance: none;
|
||||||
|
appearance: none;
|
||||||
|
border-radius: 0;
|
||||||
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
|
background-image:
|
||||||
|
linear-gradient(45deg, transparent 50%, gray 50%),
|
||||||
|
linear-gradient(135deg, gray 50%, transparent 50%);
|
||||||
|
background-position:
|
||||||
|
calc(100% - 1.5rem) calc(1rem + 0.5rem),
|
||||||
|
calc(100% - 1rem) calc(1rem + 0.5rem);
|
||||||
|
background-size:
|
||||||
|
0.5rem 0.5rem,
|
||||||
|
0.5rem 0.5rem;
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
|
||||||
|
&:invalid {
|
||||||
|
color: rgba(238, 238, 238, 0.5);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=submit] {
|
||||||
|
padding: 0.6rem 2rem;
|
||||||
|
&:disabled {
|
||||||
|
background-color: transparent;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=checkbox] {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
label.checkbox {
|
||||||
|
line-height: 3.2rem;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
&::before {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 0.8rem;
|
||||||
|
height: 3.2rem;
|
||||||
|
width: 3.2rem;
|
||||||
|
font-size: 2rem;
|
||||||
|
background-color: rgba(22, 21, 40, 0.3);
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.2);
|
||||||
|
text-align: center;
|
||||||
|
vertical-align: middle;
|
||||||
|
content: '✓';
|
||||||
|
color: rgba(255,255,255,0.2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
input[type=checkbox]:checked + label.checkbox {
|
||||||
|
&::before {
|
||||||
|
background-color: rgba(22, 21, 40, 0.6);
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
+67
-16
@@ -1,31 +1,82 @@
|
|||||||
section {
|
main {
|
||||||
@include outer-container;
|
padding: 1rem 2rem;
|
||||||
margin-bottom: 8rem;
|
|
||||||
&:first-of-type {
|
@include media-max(small) {
|
||||||
margin-top: 6rem;
|
padding: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include media($mobile) {
|
&#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;
|
margin-bottom: 5rem;
|
||||||
|
|
||||||
&:first-of-type {
|
&:first-of-type {
|
||||||
margin-top: 2rem;
|
margin-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include media-max(small) {
|
||||||
|
margin-bottom: 5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
header {
|
header {
|
||||||
@include span-columns(12);
|
margin-bottom: 3rem;
|
||||||
padding-bottom: 3rem;
|
|
||||||
text-align: center;
|
|
||||||
// background-color: purple;
|
|
||||||
|
|
||||||
@include media($mobile) {
|
&.with-nav {
|
||||||
@include span-columns(10);
|
display: grid;
|
||||||
@include shift(1);
|
grid-template-columns: auto 5rem;
|
||||||
padding-bottom: 2rem;
|
grid-template-areas:
|
||||||
|
"title" "actions";
|
||||||
}
|
}
|
||||||
|
|
||||||
div.content {
|
h2 {
|
||||||
@include span-columns(12);
|
display: inline-block;
|
||||||
|
// padding-left: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
}
|
||||||
|
|
||||||
|
@include media-max(small) {
|
||||||
|
margin-bottom: 2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
$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."
|
||||||
|
}
|
||||||
|
}
|
||||||
+48
-32
@@ -2,6 +2,7 @@
|
|||||||
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 {
|
||||||
@@ -10,22 +11,19 @@
|
|||||||
-webkit-tap-highlight-color: transparent;
|
-webkit-tap-highlight-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import "bourbon";
|
@import "mediaqueries";
|
||||||
@import "settings/neat";
|
|
||||||
@import "neat";
|
|
||||||
@import "settings/breakpoints";
|
|
||||||
@import "layout";
|
@import "layout";
|
||||||
|
@import "colors";
|
||||||
|
|
||||||
$font-family-sans: 'Open Sans', sans-serif;
|
$font-family-sans: 'Open Sans', sans-serif;
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-image: url('/img/bg.jpg');
|
font-family: $font-family-sans;
|
||||||
|
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;
|
||||||
font-family: $font-family-sans;
|
color: $body-text-color;
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 300;
|
|
||||||
color: #fff;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 900px) {
|
@media screen and (min-width: 900px) {
|
||||||
@@ -42,48 +40,66 @@ h1, h2, h3, h4, h5, input, button {
|
|||||||
|
|
||||||
section {
|
section {
|
||||||
h2 {
|
h2 {
|
||||||
font-size: 2.8rem;
|
font-size: 1.4rem;
|
||||||
color: lightblue;
|
color: $primary-color;
|
||||||
@include media($mobile) {
|
|
||||||
font-size: 2rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&#contributors {
|
&#people {
|
||||||
.content {
|
.content {
|
||||||
p.stats {
|
p.stats {
|
||||||
padding-top: 3rem;
|
margin-bottom: 1rem;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: lightblue;
|
color: white;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
span.number {
|
span.number {
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
}
|
}
|
||||||
@include media($mobile) {
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&#contributions-by-type {
|
||||||
|
.chart {
|
||||||
|
width: 50%;
|
||||||
|
margin-left: auto;
|
||||||
|
margin-right: auto;
|
||||||
|
|
||||||
|
@include media-max(small) {
|
||||||
|
width: 75%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&#proposals-open, &#proposals-closed {
|
||||||
|
.actions {
|
||||||
|
padding-top: 3rem;
|
||||||
|
font-size: 1rem;
|
||||||
|
color: $primary-color;
|
||||||
|
text-align: center;
|
||||||
|
@include media-max(small) {
|
||||||
padding-top: 2rem;
|
padding-top: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $primary-color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
button, input[type=submit] {
|
@media (min-width: 550px) {
|
||||||
display: inline-block;
|
section {
|
||||||
border: 1px solid rgba(22, 21, 40, 1);
|
h2 {
|
||||||
background-color: rgba(22, 21, 40, 0.6);
|
font-size: 2rem;
|
||||||
color: lightblue;
|
}
|
||||||
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/user-avatar";
|
||||||
|
|||||||
@@ -1,36 +0,0 @@
|
|||||||
section#add-contributor {
|
|
||||||
|
|
||||||
form {
|
|
||||||
|
|
||||||
p {
|
|
||||||
margin-bottom: 1rem;
|
|
||||||
|
|
||||||
&.actions {
|
|
||||||
padding-top: 1rem;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=text] {
|
|
||||||
width: 100%;
|
|
||||||
padding: 1rem;
|
|
||||||
border: none;
|
|
||||||
border-bottom: 1px solid rgba(255,255,255,0.2);
|
|
||||||
background-color: rgba(22, 21, 40, 0.3);
|
|
||||||
color: #fff;
|
|
||||||
font-size: 1.2rem;
|
|
||||||
&:focus, &.valid {
|
|
||||||
background-color: rgba(22, 21, 40, 0.6);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input[type=submit] {
|
|
||||||
padding: 0.6rem 2rem;
|
|
||||||
&:disabled {
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,134 @@
|
|||||||
|
main section {
|
||||||
|
@include media-max(small) {
|
||||||
|
&#contributions-unconfirmed, &#contributions-confirmed {
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.contribution-list {
|
||||||
|
clear: both;
|
||||||
|
width: 100%;
|
||||||
|
list-style: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: auto 5rem 5rem;
|
||||||
|
grid-row-gap: 0.5rem;
|
||||||
|
padding: 0.8rem 1.2rem;
|
||||||
|
background-color: rgba(255,255,255,0.1);
|
||||||
|
font-size: 1.2rem;
|
||||||
|
border-bottom: 1px solid rgba(255,255,255,0.2);
|
||||||
|
|
||||||
|
&:first-of-type {
|
||||||
|
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 {
|
||||||
|
color: $blue;
|
||||||
|
padding-right: 0.2rem;
|
||||||
|
&.community { color: $red; }
|
||||||
|
&.dev { color: $pink; }
|
||||||
|
&.design { color: $yellow; }
|
||||||
|
&.docs { color: $green; }
|
||||||
|
&.ops { color: $purple; }
|
||||||
|
}
|
||||||
|
|
||||||
|
.amount {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.symbol {
|
||||||
|
font-size: 0.8rem;
|
||||||
|
padding-left: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.recipient {
|
||||||
|
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,45 +1,89 @@
|
|||||||
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);
|
||||||
&: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);
|
||||||
}
|
}
|
||||||
|
background-color: rgba(255,255,255,0.1);
|
||||||
|
|
||||||
|
&.current-user {
|
||||||
|
background-color: rgba(255,255,255,0.2);
|
||||||
|
}
|
||||||
|
|
||||||
|
&.metadata {
|
||||||
|
height: 0;
|
||||||
|
visibility: hidden;
|
||||||
|
|
||||||
|
&:not(.visible) {
|
||||||
|
border-bottom: none;
|
||||||
|
}
|
||||||
|
|
||||||
td {
|
td {
|
||||||
padding: 0 1.2rem;
|
padding: 0 1.2rem;
|
||||||
line-height: 4.2rem;
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
color: $primary-color;
|
||||||
|
&:hover, &:active {
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style: none;
|
||||||
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
|
height: 0;
|
||||||
|
|
||||||
|
li {
|
||||||
|
display: inline;
|
||||||
|
&+li {
|
||||||
|
margin-left: 1rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&.visible {
|
||||||
|
height: auto;
|
||||||
|
visibility: visible;
|
||||||
|
ul {
|
||||||
|
height: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
td {
|
||||||
|
padding: 0 1.2rem;
|
||||||
|
line-height: 3.6rem;
|
||||||
|
|
||||||
background-color: rgba(255,255,255,0.1);
|
|
||||||
&.person {
|
&.person {
|
||||||
text-align: left;
|
text-align: left;
|
||||||
font-size: 1.4rem;
|
font-size: 1.2rem;
|
||||||
|
|
||||||
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.4rem;
|
font-size: 1.2rem;
|
||||||
|
font-weight: 500;
|
||||||
}
|
}
|
||||||
.symbol {
|
.symbol {
|
||||||
font-size: 1rem;
|
font-size: 0.8rem;
|
||||||
padding-left: 0.2rem;
|
padding-left: 0.2rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
&.current-user {
|
pre {
|
||||||
td {
|
line-height: 1rem;
|
||||||
background-color: rgba(255,255,255,0.2);
|
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: lightblue;
|
color: $primary-color;
|
||||||
|
|
||||||
@include media($mobile) {
|
@include media-max(small) {
|
||||||
margin-top: 6rem;
|
margin-top: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
|
|
||||||
#path-comet {
|
#path-comet {
|
||||||
fill: lightblue;
|
fill: $primary-color;
|
||||||
opacity: 0.1;
|
opacity: 0.1;
|
||||||
|
|
||||||
animation-name: pulse;
|
animation-name: pulse;
|
||||||
|
|||||||
@@ -4,44 +4,111 @@ ul.proposal-list {
|
|||||||
list-style: none;
|
list-style: none;
|
||||||
|
|
||||||
li {
|
li {
|
||||||
// display: block;
|
display: grid;
|
||||||
padding: 0 1.2rem;
|
grid-template-columns: auto 5rem;
|
||||||
line-height: 4.2rem;
|
grid-row-gap: 0.5rem;
|
||||||
|
padding: 1rem 1.2rem;
|
||||||
background-color: rgba(255,255,255,0.1);
|
background-color: rgba(255,255,255,0.1);
|
||||||
font-size: 1.4rem;
|
font-size: 1.2rem;
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
.id {
|
p {
|
||||||
color: lightblue;
|
align-self: center;
|
||||||
padding-right: 0.2rem;
|
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 {
|
||||||
|
color: $blue;
|
||||||
|
padding-right: 0.2rem;
|
||||||
|
&.community { color: $red; }
|
||||||
|
&.dev { color: $pink; }
|
||||||
|
&.design { color: $yellow; }
|
||||||
|
&.docs { color: $green; }
|
||||||
|
&.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: lightblue;
|
color: $primary-color;
|
||||||
padding-left: 1rem;
|
margin-right: 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
#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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
img.avatar {
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
vertical-align: middle;
|
||||||
|
margin-right: 0.2rem;
|
||||||
|
border-radius: 1rem;
|
||||||
|
}
|
||||||
@@ -1 +0,0 @@
|
|||||||
$mobile: new-breakpoint(max-width 600px);
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
// $visual-grid: true;
|
|
||||||
// $visual-grid-color: red;
|
|
||||||
// $visual-grid-index: front;
|
|
||||||
// $visual-grid-opacity: 0.5;
|
|
||||||
$max-width: em(500, 12);
|
|
||||||
@@ -1,3 +1,16 @@
|
|||||||
<main>
|
<header id="topbar">
|
||||||
|
<h1>Kosmos Kredits</h1>
|
||||||
|
|
||||||
|
<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}}
|
{{outlet}}
|
||||||
</main>
|
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<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>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<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>
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<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
-28
@@ -1,49 +1,69 @@
|
|||||||
<section id="contributors">
|
<main id="index">
|
||||||
<header>
|
|
||||||
<h2>Kosmos Contributors</h2>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
|
<div id="stats">
|
||||||
|
<section id="people">
|
||||||
|
<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">
|
<div class="content">
|
||||||
{{contributor-list contributors=contributorsSorted}}
|
{{contributor-list contributorList=kreditsToplist
|
||||||
|
showUnconfirmedKredits=showUnconfirmedKredits}}
|
||||||
|
|
||||||
<p class="stats">
|
<p class="stats">
|
||||||
<span class="number">{{model.totalSupply}}</span> kredits issued and distributed among
|
<span class="number">{{await kredits.totalKreditsEarned}}</span> kredits confirmed and issued to
|
||||||
<span class="number">{{model.contributorsCount}}</span> contributors.
|
<span class="number">{{contributorsWithKredits.length}}</span> contributors
|
||||||
|
</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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
{{#if proposalsOpen}}
|
<section id="contributions-by-type">
|
||||||
<section id="proposals-open">
|
|
||||||
<header>
|
<header>
|
||||||
<h2>Open Proposals</h2>
|
<h2>Contributions by type</h2>
|
||||||
</header>
|
</header>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{{proposal-list proposals=proposalsOpenSorted
|
{{chart-contributions-by-type contributions=contributions}}
|
||||||
confirmAction="confirmProposal"
|
</div>
|
||||||
contractInteractionEnabled=contractInteractionEnabled}}
|
</section>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="contributions">
|
||||||
|
{{#if contributionsUnconfirmed}}
|
||||||
|
<section id="contributions-unconfirmed">
|
||||||
|
<header class="with-nav">
|
||||||
|
<h2>Latest Contributions</h2>
|
||||||
|
{{#if kredits.hasAccounts}}
|
||||||
|
<nav>
|
||||||
|
{{link-to "add" "contributions.new" title="Submit a contribution" class="button small green"}}
|
||||||
|
</nav>
|
||||||
|
{{/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>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
{{/if}}
|
{{/if}}
|
||||||
|
|
||||||
<section id="proposals-closed">
|
<section id="contributions-confirmed">
|
||||||
<header>
|
<header>
|
||||||
<h2>Closed Proposals</h2>
|
<h2>Confirmed Contributions</h2>
|
||||||
</header>
|
</header>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
{{proposal-list proposals=proposalsClosedSorted
|
{{contribution-list contributions=contributionsConfirmedSorted
|
||||||
confirmAction="confirmProposal"}}
|
vetoContribution=(action "vetoContribution")}}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="add-contributor">
|
|
||||||
<header>
|
|
||||||
<h2>Add Contributor</h2>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
<div class="content">
|
|
||||||
{{add-contributor kredits=kredits
|
|
||||||
contributors=model.contributors
|
|
||||||
contractInteractionEnabled=contractInteractionEnabled}}
|
|
||||||
</div>
|
</div>
|
||||||
</section>
|
|
||||||
|
</main>
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
<section id="add-proposal">
|
||||||
|
<header>
|
||||||
|
<h2>Add Proposal</h2>
|
||||||
|
</header>
|
||||||
|
|
||||||
|
<div class="content">
|
||||||
|
{{add-proposal contributors=minedContributors save=(action "save")}}
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
{{loading-spinner}}
|
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
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]();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
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;
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{
|
|
||||||
"name": "kredits-web",
|
|
||||||
"dependencies": {
|
|
||||||
"ember": "~2.10.0",
|
|
||||||
"ember-cli-shims": "0.1.3",
|
|
||||||
"bourbon": "^4.2.7",
|
|
||||||
"neat": "^1.8.0"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+33
-10
@@ -1,10 +1,14 @@
|
|||||||
/* jshint node: true */
|
/* jshint node: true */
|
||||||
|
'use strict';
|
||||||
|
|
||||||
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',
|
||||||
|
|
||||||
EmberENV: {
|
EmberENV: {
|
||||||
FEATURES: {
|
FEATURES: {
|
||||||
// Here you can enable experimental features on an ember canary build
|
// Here you can enable experimental features on an ember canary build
|
||||||
@@ -22,6 +26,7 @@ module.exports = function(environment) {
|
|||||||
},
|
},
|
||||||
|
|
||||||
browserify: {
|
browserify: {
|
||||||
|
tests: true,
|
||||||
transform: [
|
transform: [
|
||||||
["babelify", {
|
["babelify", {
|
||||||
presets: ["es2015"],
|
presets: ["es2015"],
|
||||||
@@ -30,12 +35,13 @@ module.exports = function(environment) {
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
||||||
web3ProviderUrl: "https://parity.kosmos.org:8545",
|
web3ProviderUrl: 'https://rinkeby.infura.io/v3/d4f788b7a6584f7db2fc3c268d4d09e9',
|
||||||
ethereumChain: "testnet",
|
|
||||||
ipfs: {
|
ipfs: {
|
||||||
host: 'localhost',
|
host: 'ipfs.kosmos.org',
|
||||||
port: '5001',
|
port: '5444',
|
||||||
protocol: 'http'
|
protocol: 'https',
|
||||||
|
gatewayUrl: 'https://ipfs.kosmos.org/ipfs'
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -45,7 +51,13 @@ module.exports = function(environment) {
|
|||||||
// 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.ethereumChain = 'dev';
|
ENV.web3ProviderUrl = 'https://rinkeby.infura.io/v3/d4f788b7a6584f7db2fc3c268d4d09e9';
|
||||||
|
|
||||||
|
ENV.ipfs = {
|
||||||
|
host: 'localhost',
|
||||||
|
port: '5001',
|
||||||
|
protocol: 'http'
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (environment === 'test') {
|
if (environment === 'test') {
|
||||||
@@ -57,11 +69,22 @@ 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') {
|
||||||
ENV.ethereumChain = 'testnet';
|
// here you can enable a production-specific feature
|
||||||
ENV.web3ProviderUrl = 'https://ropsten.infura.io';
|
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,3 @@
|
|||||||
|
{
|
||||||
|
"jquery-integration": true
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
'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
|
||||||
|
};
|
||||||
+12
-10
@@ -1,15 +1,17 @@
|
|||||||
/*jshint node:true*/
|
'use strict';
|
||||||
/* global require, module */
|
|
||||||
var EmberApp = require('ember-cli/lib/broccoli/ember-app');
|
const EmberApp = require('ember-cli/lib/broccoli/ember-app');
|
||||||
|
|
||||||
module.exports = function(defaults) {
|
module.exports = function(defaults) {
|
||||||
var app = new EmberApp(defaults, {
|
let app = new EmberApp(defaults, {
|
||||||
// Add options here
|
// sassOptions: {
|
||||||
sassOptions: {
|
// includePaths: [
|
||||||
includePaths: [
|
// 'node_modules/bourbon/app/assets/stylesheets'
|
||||||
'bower_components/bourbon/app/assets/stylesheets',
|
// ]
|
||||||
'bower_components/neat/app/assets/stylesheets'
|
// },
|
||||||
]
|
sourcemaps: {
|
||||||
|
enabled: true,
|
||||||
|
extensions: ['js']
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"node": true,
|
||||||
|
"browser": false
|
||||||
|
}
|
||||||
Generated
+20211
File diff suppressed because it is too large
Load Diff
+52
-35
@@ -1,53 +1,70 @@
|
|||||||
{
|
{
|
||||||
"name": "kredits-web",
|
"name": "kredits-web",
|
||||||
"version": "0.1.0",
|
"version": "1.3.0",
|
||||||
"description": "Small description for kredits-web goes here",
|
"private": true,
|
||||||
|
"description": "Contribution dashboard of the Kosmos project",
|
||||||
|
"repository": "https://github.com/67P/kredits-web",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "",
|
"author": "Kosmos Contributors <mail@kosmos.org>",
|
||||||
"directories": {
|
"directories": {
|
||||||
"doc": "doc",
|
"doc": "doc",
|
||||||
"test": "tests"
|
"test": "tests"
|
||||||
},
|
},
|
||||||
"repository": "",
|
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "ember server",
|
"lint:hbs": "ember-template-lint .",
|
||||||
|
"lint:js": "eslint .",
|
||||||
"test": "ember test",
|
"test": "ember test",
|
||||||
"postinstall": "bower install",
|
"start": "KREDITS_APM_DOMAIN=open.aragonpm.eth ember serve",
|
||||||
|
"start:local": "WEB3_PROVIDER_URL=http://localhost:7545 ember s",
|
||||||
"build": "ember build",
|
"build": "ember build",
|
||||||
"build-prod": "ember build --environment production",
|
"build-prod": "rm -rf release/* && ember build -prod --output-path release",
|
||||||
"update-version-file": "bash scripts/update-version-file.sh",
|
"preversion": "npm test",
|
||||||
"deploy": "npm run build-prod && npm run update-version-file && bash scripts/deploy.sh"
|
"version": "npm run build-prod && git add release/",
|
||||||
|
"postversion": "git push origin master",
|
||||||
|
"deploy": "git push 5apps master"
|
||||||
},
|
},
|
||||||
"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.4.5",
|
"broccoli-asset-rev": "^2.7.0",
|
||||||
"ember-ajax": "^2.4.1",
|
"ember-ajax": "^4.0.1",
|
||||||
|
"ember-awesome-macros": "0.41.0",
|
||||||
"ember-browserify": "^1.1.13",
|
"ember-browserify": "^1.1.13",
|
||||||
"ember-cli": "2.10.0",
|
"ember-cli": "~3.8.1",
|
||||||
"ember-cli-app-version": "^2.0.0",
|
"ember-cli-app-version": "^3.2.0",
|
||||||
"ember-cli-babel": "^5.1.7",
|
"ember-cli-babel": "^7.1.2",
|
||||||
"ember-cli-dependency-checker": "^1.3.0",
|
"ember-cli-chart": "^3.4.0",
|
||||||
"ember-cli-htmlbars": "^1.0.10",
|
"ember-cli-dependency-checker": "^3.1.0",
|
||||||
"ember-cli-htmlbars-inline-precompile": "^0.3.3",
|
"ember-cli-eslint": "^4.2.3",
|
||||||
"ember-cli-inject-live-reload": "^1.4.1",
|
"ember-cli-htmlbars": "^3.0.0",
|
||||||
"ember-cli-jshint": "^2.0.1",
|
"ember-cli-htmlbars-inline-precompile": "^1.0.3",
|
||||||
"ember-cli-qunit": "^3.0.1",
|
"ember-cli-inject-live-reload": "^1.8.2",
|
||||||
"ember-cli-release": "^0.2.9",
|
"ember-cli-sass": "^7.2.0",
|
||||||
"ember-cli-sass": "6.1.1",
|
"ember-cli-sri": "^2.1.1",
|
||||||
"ember-cli-sri": "^2.1.0",
|
"ember-cli-template-lint": "^1.0.0-beta.1",
|
||||||
"ember-cli-test-loader": "^1.1.0",
|
"ember-cli-uglify": "^2.1.0",
|
||||||
"ember-cli-uglify": "^1.2.0",
|
"ember-cli-update": "^0.21.2",
|
||||||
"ember-export-application-global": "^1.0.5",
|
"ember-export-application-global": "^2.0.0",
|
||||||
"ember-load-initializers": "^0.5.1",
|
"ember-flatpickr": "^2.14.0",
|
||||||
"ember-resolver": "^2.0.3",
|
"ember-load-initializers": "^1.1.0",
|
||||||
"ipfs-api": "^12.1.7",
|
"ember-macro-helpers": "0.17.0",
|
||||||
"kredits-contracts": "67P/kredits-contracts",
|
"ember-maybe-import-regenerator": "^0.1.6",
|
||||||
"loader.js": "^4.0.10",
|
"ember-promise-helpers": "1.0.6",
|
||||||
"web3": "^0.18.2"
|
"ember-qunit": "^3.4.1",
|
||||||
|
"ember-resolver": "^5.0.1",
|
||||||
|
"ember-source": "~3.8.0",
|
||||||
|
"ember-truth-helpers": "github:jmurphyau/ember-truth-helpers#31a14373a31f1f82c77537720549b47a95c28e5f",
|
||||||
|
"eslint-plugin-ember": "^5.2.0",
|
||||||
|
"ethers": "^4.0.27",
|
||||||
|
"kosmos-schemas": "^2.0.0",
|
||||||
|
"kredits-contracts": "^5.4.0",
|
||||||
|
"loader.js": "^4.7.0",
|
||||||
|
"qunit-dom": "^0.8.0",
|
||||||
|
"tv4": "^1.3.0"
|
||||||
},
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.12.0"
|
"node": "8.* || >= 10.*"
|
||||||
},
|
}
|
||||||
"private": true
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,15 +0,0 @@
|
|||||||
<?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
@@ -0,0 +1,190 @@
|
|||||||
|
"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.3.0+091ebf4b"})
|
||||||
|
|
||||||
|
//# sourceMappingURL=kredits-web-5b220860999ba9b761f90fa33b008858.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.
|
After Width: | Height: | Size: 669 KiB |
@@ -0,0 +1,9 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 590 B |
@@ -0,0 +1,32 @@
|
|||||||
|
<!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.3.0%2B091ebf4b%22%7D%2C%22browserify%22%3A%7B%22tests%22%3Atrue%2C%22transform%22%3A%5B%5B%22babelify%22%2C%7B%22presets%22%3A%5B%22es2015%22%5D%2C%22global%22%3Atrue%7D%5D%5D%7D%2C%22web3ProviderUrl%22%3A%22https%3A%2F%2Frinkeby.infura.io%2Fv3%2Fd4f788b7a6584f7db2fc3c268d4d09e9%22%2C%22ipfs%22%3A%7B%22host%22%3A%22ipfs.kosmos.org%22%2C%22port%22%3A%225444%22%2C%22protocol%22%3A%22https%22%2C%22gatewayUrl%22%3A%22https%3A%2F%2Fipfs.kosmos.org%2Fipfs%22%7D%2C%22kreditsApmDomain%22%3A%22open.aragonpm.eth%22%2C%22exportApplicationGlobal%22%3Afalse%7D" />
|
||||||
|
|
||||||
|
<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-80a68be62538fc452f619ea272efa683.js" integrity="sha256-1SzKk/ufxNyb/CdyXniFRUByZMpFGEz+hUTtfJVw7mw= sha512-ixkdWl+f7KrwA+YRsH92A8FSnK9ZG31nJa74FIskk2y40KHDpm6zOln2VVeApLpKdkj+FF7huYSGqJZwE7PRvA==" ></script>
|
||||||
|
<script src="/assets/kredits-web-6306723cba42580aec32537c077ed2db.js" integrity="sha256-W+Xiso5/zyqiqXL6GzknDMsJpJdKWdEmxcocqICH//c= sha512-I4RbGUJS2842cKdecxx+bXcYE954At7+pz19P3n4Cc2hcIbgiIk5jyGh6Kc4hCwfsq6cTciO6e8vMvgDVs/ItA==" ></script>
|
||||||
|
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
# http://www.robotstxt.org
|
||||||
|
User-agent: *
|
||||||
|
Disallow:
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#!/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 -
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
#!/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,13 +1,25 @@
|
|||||||
/*jshint node:true*/
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
"framework": "qunit",
|
test_page: 'tests/index.html?hidepassed',
|
||||||
"test_page": "tests/index.html?hidepassed",
|
disable_watching: true,
|
||||||
"disable_watching": true,
|
launch_in_ci: [
|
||||||
"launch_in_ci": [
|
'Chrome'
|
||||||
"PhantomJS"
|
|
||||||
],
|
],
|
||||||
"launch_in_dev": [
|
launch_in_dev: [
|
||||||
"PhantomJS",
|
'Chrome'
|
||||||
"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)
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,52 +0,0 @@
|
|||||||
{
|
|
||||||
"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
|
|
||||||
}
|
|
||||||
Vendored
+19
@@ -0,0 +1,19 @@
|
|||||||
|
import Model from 'kredits-web/models/contribution';
|
||||||
|
|
||||||
|
const items = [];
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{ id: 1, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500 },
|
||||||
|
{ id: 2, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 5000 },
|
||||||
|
{ id: 3, contributorId: 2, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500 },
|
||||||
|
{ id: 4, contributorId: 2, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500 },
|
||||||
|
{ id: 5, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 5000 },
|
||||||
|
{ id: 6, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: true, amount: 500 },
|
||||||
|
{ id: 7, contributorId: 3, confirmedAtBlock: 2000, claimed: false, vetoed: false, amount: 5000 },
|
||||||
|
{ id: 8, contributorId: 1, confirmedAtBlock: 2000, claimed: false, vetoed: false, amount: 1500 },
|
||||||
|
{ id: 9, contributorId: 3, confirmedAtBlock: 2000, claimed: false, vetoed: true, amount: 1500 },
|
||||||
|
];
|
||||||
|
|
||||||
|
data.forEach(attrs => items.push(Model.create(attrs)));
|
||||||
|
|
||||||
|
export default items;
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
import Contributor from 'kredits-web/models/contributor';
|
||||||
|
|
||||||
|
const contributors = [];
|
||||||
|
|
||||||
|
const data = [
|
||||||
|
{ id: 1, name: 'Bumi', totalKreditsEarned: 11500 },
|
||||||
|
{ id: 2, name: 'Râu Cao', totalKreditsEarned: 3000 },
|
||||||
|
{ id: 3, name: 'Manuel', totalKreditsEarned: 0 }
|
||||||
|
];
|
||||||
|
|
||||||
|
data.forEach(attrs => contributors.push(Contributor.create(attrs)));
|
||||||
|
|
||||||
|
export default contributors;
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user