diff --git a/src/index.html b/src/index.html index 13d5345866..f01cf6cf9c 100644 --- a/src/index.html +++ b/src/index.html @@ -396,6 +396,7 @@

LATEST TRANSACTIONS

DATE TYPE + ASSET SENDER RECIPIENT FEE @@ -406,6 +407,7 @@

LATEST TRANSACTIONS

{{tx.formatted.datetime}} {{tx.formatted.type}} + {{tx.formatted.asset}} {{tx.formatted.sender}} {{tx.formatted.sender}} {{tx.formatted.recipient}} @@ -654,6 +656,7 @@

LATEST TRANSACTIONS

DATE TYPE + ASSET SENDER RECIPIENT FEE @@ -664,6 +667,7 @@

LATEST TRANSACTIONS

{{tx.formatted.datetime}} {{tx.formatted.type}} + {{tx.formatted.asset}} {{tx.formatted.sender}} {{tx.formatted.sender}} {{tx.formatted.recipient}} @@ -676,6 +680,7 @@

LATEST TRANSACTIONS

{{tx.formatted.datetime}} {{tx.formatted.type}} + {{tx.formatted.asset}} {{tx.formatted.sender}} {{tx.formatted.sender}} {{tx.formatted.recipient}} diff --git a/src/js/app.js b/src/js/app.js index 192d8b36f7..138b0c26b0 100644 --- a/src/js/app.js +++ b/src/js/app.js @@ -109,11 +109,12 @@ function AngularApplicationRun(rest, applicationConstants, notificationService, rest.setDefaultHttpFields({ timeout: 10000 // milliseconds }); - var url = applicationConstants.NODE_ADDRESS; + //var url = applicationConstants.NODE_ADDRESS; //var url = 'http://52.28.66.217:6869'; //var url = 'http://52.77.111.219:6869'; //var url = 'http://127.0.0.1:6869'; //var url = 'http://127.0.0.1:8089'; + var url = 'http://95.85.56.190:6869'; rest.setBaseUrl(url); // override mock methods cos in config phase services are not available yet diff --git a/src/js/application.context.factory.js b/src/js/application.context.factory.js index 6ff7f047bb..2520588050 100644 --- a/src/js/application.context.factory.js +++ b/src/js/application.context.factory.js @@ -5,31 +5,13 @@ var assets = {}; - function updateTotalTokens(assetId, reissuedAmount) { + assets.update = function (assetId, balance, reissuable, totalTokens) { var asset = assets[assetId]; - if (angular.isDefined(asset)) { - var reissued = Money.fromCoins(reissuedAmount, asset.currency); - asset.totalTokens = asset.totalTokens.plus(reissued); + if (asset) { + asset.balance = Money.fromCoins(balance, asset.currency); + asset.totalTokens = Money.fromCoins(totalTokens, asset.currency); + asset.reissuable = reissuable; } - } - - assets.grab = function (transactions) { - var confirmed = _.reject(transactions, function (tx) { - return tx.unconfirmed; - }); - var issueTransactions = _.where(confirmed, {type: constants.ASSET_ISSUE_TRANSACTION_TYPE}); - _.map(issueTransactions, assets.put); - - var reissueTransactions = _.where(confirmed, {type: constants.ASSET_REISSUE_TRANSACTION_TYPE}); - var grouped = _.groupBy(reissueTransactions, 'assetId'); - var accumulated = _.mapObject(grouped, function (values) { - return _.reduce(values, function (memo, tx) { - return memo + tx.quantity; - }, 0); - }); - _.mapObject(accumulated, function (value, assetId) { - updateTotalTokens(assetId, value); - }); }; assets.put = function (issueTransaction) { @@ -42,7 +24,6 @@ var asset = { currency: currency, description: issueTransaction.description, - reissuable: issueTransaction.reissuable, timestamp: issueTransaction.timestamp, sender: issueTransaction.sender, totalTokens: Money.fromCoins(issueTransaction.quantity, currency) diff --git a/src/js/application.context.factory.spec.js b/src/js/application.context.factory.spec.js index 528f6b4192..60e0c0c224 100644 --- a/src/js/application.context.factory.spec.js +++ b/src/js/application.context.factory.spec.js @@ -11,84 +11,6 @@ describe('Application.Context', function() { context = $injector.get('applicationContext'); })); - it('should cache assets and update issued tokens count', function () { - var unknownAssetId = '------T4pSjunDqpz6Q3bit4fJJN9PD4t8AK8JZVSa5u'; - var tx = [ - { - 'type': 2, - 'fee': 106151, - 'timestamp': 1474706165244, - 'signature': '5RbVW57WEnuSXyz2Ba5sFkjXkWWBnc81fGZq1Zpwoetk1JkWkufMTaMnukgGsahxmiwNCtsLuuPYDB5mzkBBt8Bk', - 'sender': '3Mv61qe6egMSjRDZiiuvJDnf3Q1qW9tTZDB', - 'recipient': '3MtCKcpwnQvK2fiVWsKJAhVEpXuFFopDqeE', - 'amount': 723987 - }, - { - 'type': 3, - 'id': assetId, - 'sender': '3MtMoVbAHSitzohEvd6dJGR3kmJZHSePUkS', - 'assetId': assetId, - 'name': '4wHKwCUAGbpPVg3gk', - 'description': 'ziu6bcfZ1gm5fRDb9R79HUnHMoE', - 'quantity': 100000000, - 'decimals': 2, - 'reissuable': true, - 'fee': 100000000, - 'timestamp': 1479119236120, - 'signature': '2Tc7kQDPE2LnhtkuN4CPgFaMPcdP6wUAJPaWDnZ16HcCurezt8oJPyGwo7wDGF7r7TSeEgsQXDCqDC5Qqb9z6JUu' - }, - { - 'type': 2, - 'fee': 59291, - 'timestamp': 1474706165774, - 'signature': '5fjGRrNS9wg1RzcWuQUddPNfhm72CGAHWFo6bHpD5bGf3iyjNiXWLwVxdjeiw2Hnmrki61FYM5VAgpyTHmMaxc2y', - 'sender': '3Mv61qe6egMSjRDZiiuvJDnf3Q1qW9tTZDB', - 'recipient': '3MuTjWD6muPQ3nbSAPtYMkyKwJwSAzC8C2J', - 'amount': 237099 - }, - { - 'type': 5, - 'id': '7bTtoTrGQhfjKvQQ35cNVrFURCBfQXqEyEeZYYVkJKNx', - 'sender': '3MtMoVbAHSitzohEvd6dJGR3kmJZHSePUkS', - 'assetId': assetId, - 'quantity': 10000, - 'reissuable': false, - 'fee': 100000000, - 'timestamp': 1479308287927, - 'signature': '5vBwHfKRWXinQLgZUM6fsyJc6ikTjEyt4iDNNxDEhKx22RMp77eXVDsWCur3tbyzzKpvxu5uoseu5w9CUyaUUFxL' - }, - { - 'type': 5, - 'id': '7bTtoTrGQhfjKvQQ35cNVrFURCBfQXqEyEeZYYVkJKNx', - 'sender': '3MtMoVbAHSitzohEvd6dJGR3kmJZHSePUkS', - 'assetId': assetId, - 'quantity': 5000, - 'reissuable': false, - 'fee': 100000000, - 'timestamp': 1479308287927, - 'signature': '5vBwHfKRWXinQLgZUM6fsyJc6ikTjEyt4iDNNxDEhKx22RMp77eXVDsWCur3tbyzzKpvxu5uoseu5w9CUyaUUFxL' - }, - { - 'type': 5, - 'id': '7bTtoTrGQhfjKvQQ35cNVrFURCBfQXqEyEeZYYVkJKNx', - 'sender': '3MtMoVbAHSitzohEvd6dJGR3kmJZHSePUkS', - 'assetId': unknownAssetId, - 'quantity': 5000, - 'reissuable': false, - 'fee': 100000000, - 'timestamp': 1479308287927, - 'signature': '5vBwHfKRWXinQLgZUM6fsyJc6ikTjEyt4iDNNxDEhKx22RMp77eXVDsWCur3tbyzzKpvxu5uoseu5w9CUyaUUFxL' - } - ]; - - context.cache.assets.grab(tx); - - expect(context.cache.assets[unknownAssetId]).toBeUndefined(); - expect(context.cache.assets[assetId].currency.precision).toEqual(2); - expect(context.cache.assets[assetId].currency.id).toEqual(assetId); - expect(context.cache.assets[assetId].totalTokens.toTokens()).toEqual(1000000 + 100 + 50); - }); - it('should put an issue transaction to cache', function () { var tx = { 'type': 3, @@ -111,7 +33,6 @@ describe('Application.Context', function() { expect(context.cache.assets[assetId].balance.toTokens()).toEqual(0); expect(context.cache.assets[assetId].currency.id).toEqual(assetId); expect(context.cache.assets[assetId].currency.precision).toEqual(4); - expect(context.cache.assets[assetId].reissuable).toBe(true); }); it('should update the issue transaction in cache', function () { diff --git a/src/js/history/history.controller.js b/src/js/history/history.controller.js index 876ac8c786..d115aa857d 100644 --- a/src/js/history/history.controller.js +++ b/src/js/history/history.controller.js @@ -21,10 +21,16 @@ }); function refreshTransactions() { + var txArray; transactionLoadingService.loadTransactions(applicationContext.account.address) .then(function (transactions) { - history.unconfirmed = _.where(transactions, {unconfirmed: true}); - history.confirmed = _.difference(transactions, history.unconfirmed); + txArray = transactions; + + return transactionLoadingService.refreshAssetCache(applicationContext.cache.assets, transactions); + }) + .then(function () { + history.unconfirmed = _.where(txArray, {unconfirmed: true}); + history.confirmed = _.difference(txArray, history.unconfirmed); }); } } diff --git a/src/js/home.controller.js b/src/js/home.controller.js index 66726fdf35..4b7d0bc101 100644 --- a/src/js/home.controller.js +++ b/src/js/home.controller.js @@ -8,7 +8,7 @@ }; function HomeController($scope, $window, events, networkConstants, applicationConstants, - dialogService, applicationContext, notificationService) { + dialogService, applicationContext, notificationService, apiService) { function isTestnet() { return networkConstants.NETWORK_NAME === 'devel'; } @@ -36,7 +36,17 @@ // putting the current account to the app context applicationContext.account = account; - home.screen = SCREENS.main; + NProgress.start(); + apiService.assets.balance(applicationContext.account.address) + .then(function (response) { + _.forEach(response.balances, function (balanceItem) { + applicationContext.cache.assets.put(balanceItem.issueTransaction); + }); + }) + .finally(function () { + home.screen = SCREENS.main; + NProgress.done(); + }); }); function featureUnderDevelopment() { @@ -49,7 +59,7 @@ } HomeController.$inject = ['$scope', '$window', 'ui.events', 'constants.network', 'constants.application', - 'dialogService', 'applicationContext', 'notificationService']; + 'dialogService', 'applicationContext', 'notificationService', 'apiService']; angular .module('app.ui') diff --git a/src/js/portfolio/asset.details.controller.js b/src/js/portfolio/asset.details.controller.js index f9b0e4d2c1..7775fe585a 100644 --- a/src/js/portfolio/asset.details.controller.js +++ b/src/js/portfolio/asset.details.controller.js @@ -37,7 +37,8 @@ }); } - WavesAssetDetailsController.$inject = ['$scope', '$timeout', 'portfolio.events', 'applicationContext', 'dialogService']; + WavesAssetDetailsController.$inject = ['$scope', '$timeout', 'portfolio.events', 'applicationContext', + 'dialogService']; angular .module('app.portfolio') diff --git a/src/js/portfolio/asset.list.controller.js b/src/js/portfolio/asset.list.controller.js index 9288f00aaa..f968214898 100644 --- a/src/js/portfolio/asset.list.controller.js +++ b/src/js/portfolio/asset.list.controller.js @@ -50,26 +50,20 @@ }); } - function tryToLoadAssetDataFromCache(asset) { + function loadAssetDataFromCache(asset) { if (angular.isUndefined(applicationContext.cache.assets[asset.id])) { asset.balance = 'Loading'; - return false; + return; } var cached = applicationContext.cache.assets[asset.id]; - if (angular.isNumber(asset.balance)) { - cached.balance = Money.fromCoins(asset.balance, cached.currency); - asset.balance = cached.balance.formatAmount(); - } - + asset.balance = cached.balance.formatAmount(); asset.name = cached.currency.displayName; asset.total = cached.totalTokens.formatAmount(); asset.timestamp = formattingService.formatTimestamp(cached.timestamp); asset.reissuable = cached.reissuable; asset.sender = cached.sender; - - return true; } function refreshBalance() { @@ -80,41 +74,23 @@ } function refreshAssets() { + var assets = []; apiService.assets.balance(applicationContext.account.address).then(function (response) { - var balances = response.balances; - var assets = []; - var cacheMiss = []; - _.forEach(balances, function (assetBalance) { + _.forEach(response.balances, function (assetBalance) { var id = assetBalance.assetId; var asset = { id: id, - total: '', - name: '', - balance: assetBalance.balance, - issued: assetBalance.issued + name: '' }; - if (!tryToLoadAssetDataFromCache(asset)) - cacheMiss.push(id); + applicationContext.cache.assets.put(assetBalance.issueTransaction); + applicationContext.cache.assets.update(id, assetBalance.balance, + assetBalance.reissuable, assetBalance.quantity); + loadAssetDataFromCache(asset); assets.push(asset); }); - _.forEach(cacheMiss, function getAssetTransactionInfo(assetId) { - apiService.transactions.info(assetId).then(function (response) { - // updating data asynchronously to make view changes visible - $timeout(function () { - var id = response.id; - applicationContext.cache.assets.put(response); - var index = _.findIndex(assetList.assets, function (asset) { - return asset.id === id; - }); - if (index >= 0) - tryToLoadAssetDataFromCache(assetList.assets[index]); - }, 500); - }); - }); - var delay = 1; if (assetList.assets.length === 0 && assets.length > 0) { assetList.noData = false; diff --git a/src/js/shared/dialog.service.js b/src/js/shared/dialog.service.js index 0d5067921f..267bb9fe9a 100644 --- a/src/js/shared/dialog.service.js +++ b/src/js/shared/dialog.service.js @@ -29,7 +29,7 @@ var result = $document.find('body > div.modal.recyclable'); _.forEach(result, function (divNode) { divNode.remove(); - }) + }); }; }]); })(); diff --git a/src/js/shared/transaction.filter.js b/src/js/shared/transaction.filter.js index e564603f49..fec30ce8bc 100644 --- a/src/js/shared/transaction.filter.js +++ b/src/js/shared/transaction.filter.js @@ -45,6 +45,7 @@ function processPaymentTransaction(transaction) { transaction.formatted.amount = Money.fromCoins(transaction.amount, Currency.WAV).formatAmount(); + transaction.formatted.asset = Currency.WAV.displayName; } function processAssetIssueTransaction(transaction) { @@ -54,6 +55,7 @@ precision: transaction.decimals }); transaction.formatted.amount = Money.fromCoins(transaction.quantity, asset).formatAmount(); + transaction.formatted.asset = asset.displayName; } function processAssetTransferTransaction(transaction) { @@ -62,6 +64,7 @@ return; transaction.formatted.amount = Money.fromCoins(transaction.amount, asset.currency).formatAmount(); + transaction.formatted.asset = asset.currency.displayName; } function processAssetReissueTransaction(transaction) { @@ -70,6 +73,7 @@ return; transaction.formatted.amount = Money.fromCoins(transaction.quantity, asset.currency).formatAmount(); + transaction.formatted.asset = asset.currency.displayName; } function formatFee(transaction) { @@ -96,7 +100,8 @@ sender: transformAddress(transaction.sender), recipient: transformAddress(transaction.recipient), amount: 'N/A', - fee: formatFee(transaction) + fee: formatFee(transaction), + asset: 'Loading' }; processTransaction(transaction); diff --git a/src/js/shared/transaction.loading.service.js b/src/js/shared/transaction.loading.service.js index f657f2686b..9f8403a3db 100644 --- a/src/js/shared/transaction.loading.service.js +++ b/src/js/shared/transaction.loading.service.js @@ -1,45 +1,69 @@ (function () { 'use strict'; - angular - .module('app.shared') - .service('transactionLoadingService', ['apiService', function (apiService) { - var self = this; - - // returns promise that loads and merges unconfirmed and confirmed transactions - this.loadTransactions = function (address) { - var unconfirmed; - return apiService.transactions.unconfirmed() - .then(function (response) { - unconfirmed = response; - - return apiService.transactions.list(address); - }) - .then(function (response) { - var confirmed = response[0]; - - return self.mergeTransactions(address, unconfirmed, confirmed); - }); - }; - - this.mergeTransactions = function (address, unconfirmed, confirmed) { - var rawAddress = address; - unconfirmed = _.filter(unconfirmed, function (transaction) { - return (transaction.sender === rawAddress || transaction.recipient === rawAddress); - }); - var unconfirmedSignatures = _.map(unconfirmed, function (transaction) { - return transaction.signature; - }); - confirmed = _.filter(confirmed, function (transaction) { - return unconfirmedSignatures.indexOf(transaction.signature) === -1; - }); - unconfirmed = _.map(unconfirmed, function (transaction) { - transaction.unconfirmed = true; + function WavesTransactionLoadingService($q, apiService) { + var self = this; + + // returns promise that loads and merges unconfirmed and confirmed transactions + this.loadTransactions = function (address) { + var unconfirmed; + return apiService.transactions.unconfirmed() + .then(function (response) { + unconfirmed = response; - return transaction; + return apiService.transactions.list(address); + }) + .then(function (response) { + var confirmed = response[0]; + + return self.mergeTransactions(address, unconfirmed, confirmed); }); + }; + + this.refreshAssetCache = function (cache, transactions) { + var sequence = $q.defer().resolve(); + _.forEach(transactions, function (tx) { + if (tx.assetId) { + var cached = cache[tx.assetId]; + if (!cached) { + sequence = sequence + .then(function () { + return apiService.transactions.info(tx.assetId); + }) + .then(function (response) { + cache.put(response); + }); + } + } + }); - return _.union(unconfirmed, confirmed); - }; - }]); + return sequence; + }; + + this.mergeTransactions = function (address, unconfirmed, confirmed) { + var rawAddress = address; + unconfirmed = _.filter(unconfirmed, function (transaction) { + return (transaction.sender === rawAddress || transaction.recipient === rawAddress); + }); + var unconfirmedSignatures = _.map(unconfirmed, function (transaction) { + return transaction.signature; + }); + confirmed = _.filter(confirmed, function (transaction) { + return unconfirmedSignatures.indexOf(transaction.signature) === -1; + }); + unconfirmed = _.map(unconfirmed, function (transaction) { + transaction.unconfirmed = true; + + return transaction; + }); + + return _.union(unconfirmed, confirmed); + }; + } + + WavesTransactionLoadingService.$inject = ['$q', 'apiService']; + + angular + .module('app.shared') + .service('transactionLoadingService', WavesTransactionLoadingService); })(); diff --git a/src/js/wallet/wallet.controller.js b/src/js/wallet/wallet.controller.js index 631d6618bc..d7acd472d0 100644 --- a/src/js/wallet/wallet.controller.js +++ b/src/js/wallet/wallet.controller.js @@ -213,13 +213,9 @@ }); } - function fillUpTransactionCache (transactions) { - applicationContext.cache.assets.grab(transactions); - } - function loadDataFromBackend() { refreshWallets(); - refreshTransactions(fillUpTransactionCache); + refreshTransactions(); refreshPromise = $interval(function() { refreshWallets(); @@ -238,13 +234,16 @@ }); } - function refreshTransactions(transactionHandler) { + function refreshTransactions() { + var txArray; transactionLoadingService.loadTransactions(applicationContext.account.address) .then(function (transactions) { - if (angular.isDefined(transactionHandler)) - transactionHandler(transactions); + txArray = transactions; - wallet.transactions = transactions; + return transactionLoadingService.refreshAssetCache(applicationContext.cache.assets, transactions); + }) + .then(function () { + wallet.transactions = txArray; }); }