Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions data-service/api/API.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import * as addressModule from './address';
import { getLastPrice } from './matcher/getLastPrice';
import { getAddressByAlias, getAliasesByAddress } from './aliases/aliases';
import * as pairsModule from './pairs/pairs';
import * as ratingModule from './rating/rating';
import * as dataModule from './data';


Expand All @@ -39,6 +40,10 @@ export const pairs = {
...pairsModule
};

export const rating = {
...ratingModule
};

export const data = {
...dataModule
};
Expand Down
33 changes: 33 additions & 0 deletions data-service/api/rating/rating.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { request } from '../../utils/request';
import { ITokenRating, IParsedRating } from '../../interface';
import { stringifyJSON, toArray } from '../../utils/utils';
// import { get } from '../../config';

const ratingApiUrl = 'https://tokenrating.wavesexplorer.com/api/v1';

export function getAssetsRating(assets: string | Array<string>): Promise<Array<IParsedRating>> {
return request(
{
url: `${ratingApiUrl}/token/`,
fetchOptions: {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json;charset=UTF-8'
},
body: stringifyJSON({
"assetIds": toArray(assets),
"page": 1,
"limit": 25
})
}
})
.then((tokensList: any) => {
return Object.values(tokensList).map((ratingItem: ITokenRating) => {
return {
assetId: ratingItem.assetId,
rating: ratingItem.averageScore
};
})
});
}
1 change: 0 additions & 1 deletion data-service/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ export interface IConfigParams {
assets: IHash<string>;
minimalSeedLength: number;
remappedAssetNames: IHash<string>;
// oracleAddress: string;
oracleWaves: string;
oracleTokenomica: string;
}
23 changes: 23 additions & 0 deletions data-service/interface.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,26 @@ export interface IMoneyFactory {
export interface IPriceMoneyFactory {
(data: string | number | BigNumber, pair: AssetPair): Money;
}

export interface ITokenRating {
assetId: string;
assetName: string;
averageScore: number;
createdAt: string;
details: object;
lastAverageScore: number;
scoreBoard: object;
sender: string
sumTokens: number;
timestamp: number;
top: boolean;
txId: string
voted: boolean;
votes: array;
votesCount: number;
}

export interface IParsedRating {
assetId: string;
rating: number;
}
3 changes: 3 additions & 0 deletions src/img/icons/rating-basic-200.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions src/img/icons/rating-submit-300.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
164 changes: 71 additions & 93 deletions src/img/icons/transaction-icons-30.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/index.hbs
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,7 @@
CANCEL_LEASING: 'cancel-leasing',
CREATE_ALIAS: 'create-alias',
DATA: 'data',
DATA_VOTE: 'data-vote',
SET_SCRIPT: 'set-script',
SCRIPT_CANCEL: 'set-script-cancel',
SPONSORSHIP_START: 'sponsorship-start',
Expand Down
8 changes: 8 additions & 0 deletions src/modules/app/less/app-icons.less
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,14 @@
background-color: rgba(90, 129, 234, 0.1);
}

.icon-tx-data-vote {
&::before {
display: block;
background-position-x: -@tx-icon-size * 23;
}
background-color: rgba(90, 129, 234, 0.1);
}

.icon-tx-sponsorship-start {
&::before {
display: block;
Expand Down
21 changes: 18 additions & 3 deletions src/modules/ui/directives/assetInfoHead/AssetInfoHead.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
* @param user
* @param waves
* @param utils
* @param createPoll
* @return {AssetInfoHead}
*/
const controller = function (Base, $scope, user, waves, utils) {
const controller = function (Base, $scope, user, waves, utils, createPoll) {

class AssetInfoHead extends Base {

Expand All @@ -21,6 +22,7 @@
$postLink() {
this._getAssetInfo();
this.observe('assetId', this._getAssetInfo);
createPoll(this, this._getTokenRating, this._setTokenRating, 60 * 1000);
}

/**
Expand All @@ -30,20 +32,33 @@
waves.node.assets.getAsset(this.assetId).then(asset => {
this.assetName = asset.name;
this.ticker = asset.ticker;
const { hasLabel } = utils.getDataFromOracles(asset.id);
const { hasLabel, isGateway } = utils.getDataFromOracles(asset.id);
this.hasLabel = hasLabel;
this.isGateway = isGateway && this.assetId !== WavesApp.defaultAssets.VST;
$scope.$apply();
});

this.state = { assetId: this.assetId };
}

_getTokenRating() {
return ds.api.rating.getAssetsRating(this.assetId);
}

_setTokenRating([asset]) {
if (!asset) {
return null;
}
this.rating = asset.rating;
$scope.$apply();
}

}

return new AssetInfoHead();
};

controller.$inject = ['Base', '$scope', 'user', 'waves', 'utils'];
controller.$inject = ['Base', '$scope', 'user', 'waves', 'utils', 'createPoll'];

angular.module('app.ui')
.component('wAssetInfoHead', {
Expand Down
25 changes: 20 additions & 5 deletions src/modules/ui/directives/assetInfoHead/asset-info-head.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,27 @@ <h2 ng-cloak class="asset-modal__name basic-900" ng-class="{'has-label': $ctrl.h
<w-asset-status asset-id="$ctrl.assetId"></w-asset-status>
</h2>

<div ng-if="$ctrl.ticker" class="body-2 margin-05 basic-500 asset__ticker">{{$ctrl.ticker}}</div>
<div class="rating-wrapper" ng-if="!$ctrl.isGateway">
<w-rating-stars asset-id="$ctrl.assetId" rating="$ctrl.rating" can-rate="'true'">
</w-rating-stars>
<span class="rating-number" w-nice-number="$ctrl.rating"></span>
<w-help-icon class="info">
<div class="help-icon__row headline-3" w-i18n="modal.assetInfo.rating.tooltipTitle"></div>
<div class="help-icon__row" w-i18n="modal.assetInfo.rating.tooltipText"></div>
<div class="help-icon__row">
<a href="https://tokenrating.wavesexplorer.com"
w-i18n="modal.assetInfo.rating.tooltipLink"
target="_blank"
rel="noopener noreferrer"
></a>
</div>
</w-help-icon>
</div>
<div class="chart-wrapper">
<w-asset-rate-chart no-update="::true" asset-id="$ctrl.assetId"></w-asset-rate-chart>
<div class="interactive-stop"></div>
</div>

<div class="chart-wrapper">
<w-asset-rate-chart no-update="::true" asset-id="$ctrl.assetId"></w-asset-rate-chart>
<div class="interactive-stop"></div>
</div>

</div>
</div>
2 changes: 1 addition & 1 deletion src/modules/ui/directives/footer/footer.html
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<footer class="footer" w-i18n-ns="app.welcome">
<footer class="footer" w-i18n-ns="app.welcome" w-web-only-class="WEB ONLY">
<section>
<div class="section-wrapper">
<div class="footer-left">
Expand Down
18 changes: 18 additions & 0 deletions src/modules/ui/directives/ratingStars/ratingStars.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<!--<div class="rating-stars">-->
<!-- <div ng-repeat="star in $ctrl.starsList"-->
<!-- ng-class="{'filled': star.filled}"-->
<!-- class="rating-stars__star"></div>-->
<!--</div>-->
<div class="rating-stars-wrapper" ng-class="{ 'can-rate': $ctrl.canRate, 'has-balance':$ctrl.hasBalance }"></div>
<div class="tooltip tooltip_vote" ng-if="$ctrl.canRate">
<span class="tooltip__content" w-i18n="modal.assetInfo.rating.canVoteTip"></span>
</div>
<div class="tooltip_need-money" ng-if="$ctrl.canRate">
<div class="tooltip_need-money__content">
<span class="tooltip__content__row headline-3">
<span w-i18n="modal.assetInfo.rating.tooltipNeedWCT"></span>
<a href="/dex?assetId2=DHgwrRvVyqJsepd32YbBqUeDH4GJ1N984X8QoekjgH8J&assetId1=WAVES"> WCT </a>
<span w-i18n="modal.assetInfo.rating.tooltipNeedWAVES"></span>
</span>
</div>
</div>
146 changes: 146 additions & 0 deletions src/modules/ui/directives/ratingStars/ratingStars.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
(function () {
'use strict';

const controller = function (Base,
user,
$scope,
RatingStarsFactory,
$element,
waves,
modalManager,
balanceWatcher) {

const { SIGN_TYPE } = require('@waves/signature-adapter');
const WCT_ID = 'DHgwrRvVyqJsepd32YbBqUeDH4GJ1N984X8QoekjgH8J';
const WAVES_ID = 'WAVES';
const NEED_WCT = 1;

class RatingStars extends Base {

/**
* @type JQuery
*/
$container;
/**
* @type boolean
*/
hasBalance = false;
/**
* @type number
*/
rating;
/**
* @type string
*/
size;
/**
* @type boolean
*/
canRate = false;

$postLink() {
const ratingStars = new RatingStarsFactory({
$container: $element.find('.rating-stars-wrapper'),
rating: this.rating,
size: this.size,
canRate: this.canRate,
hasBalance: this.hasBalance
});

this.observe('rating', () => {
ratingStars.update(this.rating);
});

if (this.canRate) {
this.observe('hasBalance', () => {
ratingStars.updateStatus(this.hasBalance);
$scope.$apply();
});

waves.node.getFee({ type: SIGN_TYPE.DATA })
.then(money => {
this.fee = money;
this._checkBalance();
this.receive(ratingStars.vote, this._onVote, this);
});
}

}

_checkBalance() {
const balance = balanceWatcher.getBalance();
this.wavesBalance = balance[WAVES_ID];
this.wctBalance = balance[WCT_ID];
if (this.wavesBalance.gte(this.fee) && this.wctBalance.getTokens().gte(NEED_WCT)) {
this.hasBalance = true;
$scope.$apply();
}
}

_onVote(rating) {
waves.node.getFee({ type: SIGN_TYPE.DATA })
.then(money => {
this.fee = money;

const tx = waves.node.transactions.createTransaction({
type: SIGN_TYPE.DATA,
data: {
data: [
{
key: 'tokenRating',
type: 'string',
value: 'tokenRating'
}, {
key: 'assetId',
type: 'string',
value: this.assetId
}, {
key: 'score',
type: 'integer',
value: rating
}
],
fee: this.fee,
type: SIGN_TYPE.DATA
}
});
this.signable = ds.signature.getSignatureApi().makeSignable(tx);

this._generate(this.signable);
});

}

_generate(signable) {
return modalManager.showConfirmTx(signable)
.then(() => this._reset());
}

}

return new RatingStars();
};

controller.$inject = [
'Base',
'user',
'$scope',
'RatingStarsFactory',
'$element',
'waves',
'modalManager',
'balanceWatcher'];

angular.module('app.ui').component('wRatingStars', {
bindings: {
rating: '<',
size: '<',
canRate: '<',
assetId: '<'
},
// scope: false,
templateUrl: 'modules/ui/directives/ratingStars/ratingStars.html',
controller
});

})();
Loading