diff --git a/gulpfile.ts b/gulpfile.ts index dc8f0818e9..5ae6620ed6 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -82,6 +82,11 @@ function createBuildTask(args?: { platform: TPlatform; env: TBuild; config: stri ? ['(function () {\nvar module = undefined;\n', '})();'] : null ), + createConcatTask( + getFileName('not-wrapped-vendors.js', env as TBuild), + meta.vendorsNotWrapped, + join(outputPath, 'js') + ), createConcatTask( getFileName('vendor-styles.css', env as TBuild), meta.stylesheets, diff --git a/package-lock.json b/package-lock.json index 5bb98990a2..5eedcf4439 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "waves-client", - "version": "1.3.13", + "version": "1.3.14", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -18245,9 +18245,9 @@ "dev": true }, "worker-wrapper": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/worker-wrapper/-/worker-wrapper-1.3.1.tgz", - "integrity": "sha512-EtZrJ+CSqGVkd/2VPMKlVI6zQznrw9H7l7fdM/x2irVoNLugeg8nmUpFvDahV3rbN85GmlH/NAhgHnxxHdGCEQ==" + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/worker-wrapper/-/worker-wrapper-1.3.2.tgz", + "integrity": "sha512-Sjj8D8915GlsxDItQxXYo/P9X19YNT5tVrroVsHFdP+S3kvCE+q8P+8tJTTRqKlsSSqTE3QV6FzGdR9eaLE0xA==" }, "wrap-ansi": { "version": "2.1.0", diff --git a/package.json b/package.json index 999bf19e3c..3f8b533a62 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "waves-client", - "version": "1.3.14", + "version": "1.3.16", "description": "The official client application for the Waves platform", "private": true, "repository": { @@ -137,7 +137,7 @@ "ramda": "^0.25.0", "ts-api-validator": "2.1.2", "ts-utils": "^6.0.6", - "worker-wrapper": "^1.3.1" + "worker-wrapper": "^1.3.2" }, "husky": { "hooks": { diff --git a/scripts/htmlTask.ts b/scripts/htmlTask.ts index 4974fbb838..b5b3a55b73 100644 --- a/scripts/htmlTask.ts +++ b/scripts/htmlTask.ts @@ -13,6 +13,7 @@ function getScriptsList(input: string) { return [ filesMap['vendors'], + filesMap['not-wrapped-vendors'], filesMap['bundle'], filesMap['templates'] ]; diff --git a/src/modules/app/services/User.js b/src/modules/app/services/User.js index 26b7adf2f0..0243104350 100644 --- a/src/modules/app/services/User.js +++ b/src/modules/app/services/User.js @@ -426,6 +426,7 @@ if (stateName) { this.logoutSignal.dispatch({}); this._resetFields(); + this.changeTheme(themes.getDefaultTheme()); $state.go(stateName, undefined, { custom: { logout: true } }); } else if (WavesApp.isDesktop()) { transfer('reload'); diff --git a/src/modules/app/services/waves/WavesUtils.js b/src/modules/app/services/waves/WavesUtils.js index 9a74a0ac9e..4ce6f37a6b 100644 --- a/src/modules/app/services/waves/WavesUtils.js +++ b/src/modules/app/services/waves/WavesUtils.js @@ -142,9 +142,18 @@ * @param pair * @returns {Promise} */ - @decorators.cachable(60) getVolume(pair) { - return ds.api.pairs.info(matcher.currentMatcherAddress, [pair]) + return this._getVolume(pair, matcher.currentMatcherAddress); + } + + /** + * @param pair + * @param {string} currentMatcherAddress + * @returns {Promise} + */ + @decorators.cachable(60) + _getVolume(pair, currentMatcherAddress) { + return ds.api.pairs.info(currentMatcherAddress, [pair]) .then((data) => { const [pair = {}] = data.filter(Boolean); return pair && String(pair.volume) || '0'; diff --git a/src/modules/app/services/waves/matcher/Matcher.js b/src/modules/app/services/waves/matcher/Matcher.js index b1c6ad635d..6a156c4aa8 100644 --- a/src/modules/app/services/waves/matcher/Matcher.js +++ b/src/modules/app/services/waves/matcher/Matcher.js @@ -97,15 +97,11 @@ } /** + * @param options * @return {Promise>} */ - @decorators.cachable(1) getOrders(options) { - if (user.address) { - return ds.api.matcher.getOrders(options).then(ds.processOrdersWithStore); - } else { - return Promise.resolve([]); - } + return this._getOrders(options, user.address); } /** @@ -285,6 +281,21 @@ }); } + /** + * @param {any} [options] + * @param {string} [address] + * @return {Promise>} + * @private + */ + @decorators.cachable(1) + _getOrders(options, address) { + if (address) { + return ds.api.matcher.getOrders(options).then(ds.processOrdersWithStore); + } else { + return Promise.resolve([]); + } + } + /** * @param {string} asset1 * @param {string} asset2 diff --git a/src/modules/app/services/waves/node/content/Transactions.js b/src/modules/app/services/waves/node/content/Transactions.js index 87fc088a4a..a79d904d0e 100644 --- a/src/modules/app/services/waves/node/content/Transactions.js +++ b/src/modules/app/services/waves/node/content/Transactions.js @@ -65,28 +65,26 @@ /** * Get transactions list by user - * @param {number} [limit] - * @param {string} [after] + * @param {number} limit + * @param {string} after * @return {Promise} */ - @decorators.cachable(1) list(limit = 1000, after) { - return ds.api.transactions.list(user.address, limit, after) - .then(list => list.map(this._pipeTransaction())); + return this._list(limit, after, user.address); } /** * @return {Promise} */ - @decorators.cachable(120) getActiveLeasingTx() { - return ds.fetch(`${this.node}/leasing/active/${user.address}`) - .then(R.uniqBy(R.prop('id'))) - .then(R.map(item => ({ ...item, status: 'active' }))) - .then(list => ds.api.transactions.parseTx(list, false)) - .then(list => list.map(this._pipeTransaction())); + return this._getActiveLeasingTx(user.address); } + /** + * @param {string} address + * @return {Promise} + */ + /** * Get transactions list by user from utx * @return {Promise} @@ -137,6 +135,29 @@ return this._pipeTransaction(false)(tx); } + @decorators.cachable(120) + _getActiveLeasingTx(address) { + return ds.fetch(`${this.node}/leasing/active/${address}`) + .then(R.uniqBy(R.prop('id'))) + .then(R.map(item => ({ ...item, status: 'active' }))) + .then(list => ds.api.transactions.parseTx(list, false)) + .then(list => list.map(this._pipeTransaction())); + } + + /** + * @private + * Get transactions list by user + * @param {number} [limit] + * @param {string} [after] + * @param {string} [address] + * @return {Promise} + */ + @decorators.cachable(1) + _list(limit, after, address) { + return ds.api.transactions.list(address, limit, after) + .then(list => list.map(this._pipeTransaction())); + } + /** * @return {function(*=)} * @private diff --git a/src/modules/ui/directives/footer/Footer.js b/src/modules/ui/directives/footer/Footer.js index 11cfd04cd7..8a0bd54338 100644 --- a/src/modules/ui/directives/footer/Footer.js +++ b/src/modules/ui/directives/footer/Footer.js @@ -1,6 +1,8 @@ (function () { 'use strict'; + const analytics = require('@waves/event-sender'); + const controller = function (Base, $scope, $element, utils, storage) { class FooterCtrl extends Base { @@ -48,6 +50,12 @@ storage.load(this._toasterMobilesStorageKey).then(wasHidden => { this.isToasterMobilesVisible = !wasHidden; + if (!wasHidden) { + analytics.send({ + name: 'Download Mobile Display', + target: 'all' + }); + } utils.safeApply($scope); }); } @@ -56,8 +64,11 @@ * @public */ hideToaster() { + analytics.send({ + name: 'Download Mobile Close', + target: 'all' + }); $element.find('.toaster-mobiles').addClass('hidden-toaster'); - storage.save(this._toasterMobilesStorageKey, true); } diff --git a/src/modules/ui/directives/footer/footer.html b/src/modules/ui/directives/footer/footer.html index 2ebec9e71b..5f418fa84e 100644 --- a/src/modules/ui/directives/footer/footer.html +++ b/src/modules/ui/directives/footer/footer.html @@ -2,11 +2,13 @@
@@ -19,7 +21,7 @@ class="footer__link" target="_blank" rel="noopener noreferrer" href="https://wavesplatform.com/products-wallet">
@@ -73,28 +75,37 @@
+ class="footer__link" w-i18n="welcome.privacyPolicy" target="_blank" + rel="noopener noreferrer" + href="https://wavesplatform.com/files/docs/Privacy%20Policy_SW.pdf">
+ event-target="'ui'" class="footer__link" w-i18n="welcome.termsOfUse" target="_blank" + rel="noopener noreferrer" + href="https://wavesplatform.com/files/docs/Waves_terms_and_conditions.pdf">
+ class="footer__link" w-i18n="welcome.blog" target="_blank" rel="noopener noreferrer" + href="https://blog.wavesplatform.com/">
+ class="footer__link" w-i18n="welcome.twitter" target="_blank" rel="noopener noreferrer" + href="https://twitter.com/Waves_DEX">
+ class="footer__link" w-i18n="welcome.telegram" target="_blank" rel="noopener noreferrer" + href="{{::$ctrl.telegramLink}}">
+ class="footer__link" w-i18n="welcome.forum" target="_blank" rel="noopener noreferrer" + href="https://forum.wavesplatform.com">
- +
diff --git a/src/modules/ui/directives/footer/footer.less b/src/modules/ui/directives/footer/footer.less index a84d4a6981..53efdb3a63 100644 --- a/src/modules/ui/directives/footer/footer.less +++ b/src/modules/ui/directives/footer/footer.less @@ -123,12 +123,6 @@ } } -body.welcome { - .toaster-mobiles { - display: none; - } -} - @media screen and (max-width: 1174px) { .footer { .section-wrapper { diff --git a/src/modules/utils/modals/ModalManager.js b/src/modules/utils/modals/ModalManager.js index e9bdaff2ce..811d3fa961 100644 --- a/src/modules/utils/modals/ModalManager.js +++ b/src/modules/utils/modals/ModalManager.js @@ -10,9 +10,11 @@ * @param {$injector} $injector * @param {State} state * @param {Storage} storage + * @param {User} user * @return {ModalManager} */ - const factory = function ($mdDialog, utils, decorators, $templateRequest, $rootScope, $injector, state, storage) { + const factory = function ($mdDialog, utils, decorators, $templateRequest, $rootScope, $injector, state, storage, + user) { const tsUtils = require('ts-utils'); const ds = require('data-service'); @@ -50,13 +52,8 @@ */ this._counter = 0; - state.signals.changeRouterStateStart.on(() => { - const counter = this._counter; - - for (let i = 0; i < counter; i++) { - $mdDialog.cancel(); - } - }); + state.signals.changeRouterStateStart.on(this.closeModals, this); + user.logoutSignal.on(this.closeModals, this); } showScriptModal() { @@ -544,6 +541,14 @@ return this._getModal(tsUtils.merge({}, DEFAULT_OPTIONS, options)); } + closeModals() { + const counter = this._counter; + + for (let i = 0; i < counter; i++) { + $mdDialog.cancel(); + } + } + /** * @return {User} * @private @@ -782,7 +787,8 @@ '$rootScope', '$injector', 'state', - 'storage']; + 'storage', + 'user']; angular.module('app.utils') .factory('modalManager', factory); diff --git a/src/modules/utils/modals/importAccounts/ImportAccountsCtrl.js b/src/modules/utils/modals/importAccounts/ImportAccountsCtrl.js index 19b345eb8f..34f46ac11e 100644 --- a/src/modules/utils/modals/importAccounts/ImportAccountsCtrl.js +++ b/src/modules/utils/modals/importAccounts/ImportAccountsCtrl.js @@ -14,7 +14,7 @@ const controller = function (Base, $scope, utils, user, storage, $state, $mdDialog) { const { find, propEq, uniqBy, filter, pipe, prop } = require('ramda'); - const { utils: generatorUtils } = require('@waves/signature-generator'); + const { isValidAddress } = require('@waves/signature-adapter'); const OLD_ORIGIN = 'https://client.wavesplatform.com'; @@ -73,7 +73,8 @@ .catch(() => []) .then(list => { this.pending = false; - const filteredList = list.filter(user => generatorUtils.crypto.isValidAddress(user.address)); + const networkByte = WavesApp.network.code.charCodeAt(0); + const filteredList = list.filter(user => isValidAddress(user.address, networkByte)); this._addAccountList(filteredList); }); } diff --git a/src/modules/utils/modals/receive/receiveCryptocurrency/ReceiveCryptocurrency.js b/src/modules/utils/modals/receive/receiveCryptocurrency/ReceiveCryptocurrency.js index db4fa99c5f..346e91f599 100644 --- a/src/modules/utils/modals/receive/receiveCryptocurrency/ReceiveCryptocurrency.js +++ b/src/modules/utils/modals/receive/receiveCryptocurrency/ReceiveCryptocurrency.js @@ -1,6 +1,8 @@ (function () { 'use strict'; + const { Money } = require('@waves/data-entities'); + /** * @param {typeof Base} Base * @param {ng.IScope} $scope @@ -79,8 +81,10 @@ if (depositDetails) { depositDetails.then((details) => { this.gatewayAddress = details.address; + this.minAmount = Money.fromTokens(details.details.in_min || 0.001, this.asset); $scope.$apply(); }, () => { + this.minAmount = Money.fromTokens(0.001, this.asset); this.gatewayAddress = null; this.gatewayServerError = true; $scope.$apply(); diff --git a/src/modules/utils/modals/receive/receiveCryptocurrency/receive-cryptocurrency.html b/src/modules/utils/modals/receive/receiveCryptocurrency/receive-cryptocurrency.html index f8a37310be..d0bbe83872 100644 --- a/src/modules/utils/modals/receive/receiveCryptocurrency/receive-cryptocurrency.html +++ b/src/modules/utils/modals/receive/receiveCryptocurrency/receive-cryptocurrency.html @@ -41,8 +41,14 @@
-
-
+
+
diff --git a/src/modules/utils/services/TimeLine.js b/src/modules/utils/services/TimeLine.js index 0ff588a9f6..3dc9e4d66a 100644 --- a/src/modules/utils/services/TimeLine.js +++ b/src/modules/utils/services/TimeLine.js @@ -121,6 +121,10 @@ const now = Date.now(); for (let i = this._listeners.list.length - 1; i >= 0; i--) { const item = this._listeners.list[i]; + if (!item) { + continue; + } + if (now - item.start >= item.timeout) { try { if (item.handler) { diff --git a/src/modules/utils/services/gateways/CoinomatService.js b/src/modules/utils/services/gateways/CoinomatService.js index a8f146cf40..66238d5b71 100644 --- a/src/modules/utils/services/gateways/CoinomatService.js +++ b/src/modules/utils/services/gateways/CoinomatService.js @@ -44,7 +44,7 @@ const from = GATEWAYS[asset.id].gateway; const to = GATEWAYS[asset.id].waves; return this._loadPaymentDetails(from, to, wavesAddress).then((details) => { - return { address: details.tunnel.wallet_from }; + return { address: details.tunnel.wallet_from, details: details.tunnel }; }); } diff --git a/src/modules/wallet/modules/portfolio/directives/portfolioRow/PortfolioRow.js b/src/modules/wallet/modules/portfolio/directives/portfolioRow/PortfolioRow.js index 26a9435b16..62307c41c7 100644 --- a/src/modules/wallet/modules/portfolio/directives/portfolioRow/PortfolioRow.js +++ b/src/modules/wallet/modules/portfolio/directives/portfolioRow/PortfolioRow.js @@ -182,8 +182,10 @@ this.isSmart = balance.asset.hasScript; const firstAssetChar = this.balance.asset.name.slice(0, 1); const canPayFee = list.find(item => item.asset.id === this.balance.asset.id) && !this._isWaves; - const { isVerified, isGateway, - isTokenomica, logo, isGatewaySoon } = utils.getDataFromOracles(this.balance.asset.id); + const { + isVerified, isGateway, + isTokenomica, logo, isGatewaySoon + } = utils.getDataFromOracles(this.balance.asset.id); this.isVerifiedOrGateway = isVerified || isGateway; @@ -232,14 +234,13 @@ */ this._poll = createPoll(this, this._initSponsorShips, angular.noop, 5000); this._onUpdateBalance(); - // this._initSponsorShips(); this._setHandlers(); this.changeLanguageHandler(); }); } $onDestroy() { - i18next.off('languageChanged', this.changeLanguageHandler); + super.$onDestroy(); this.$node.off(); } @@ -256,6 +257,7 @@ 'app.wallet.portfolio'); }); } + /** * @return {boolean} * @private @@ -274,13 +276,13 @@ const isAssetLockedInDex = utils.isLockedInDex(this.balance.asset.id); return !isAssetLockedInDex && (this.balance.isPinned || - this._isMyAsset || - this.balance.asset.isMyAsset || - this.balance.asset.id === WavesApp.defaultAssets.WAVES || - this.gatewayService.getPurchasableWithCards()[this.balance.asset.id] || - this.gatewayService.getCryptocurrencies()[this.balance.asset.id] || - this.gatewayService.getFiats()[this.balance.asset.id] || - path(statusPath, ds.dataManager.getOracleData('oracleWaves')) === STATUS_LIST.VERIFIED); + this._isMyAsset || + this.balance.asset.isMyAsset || + this.balance.asset.id === WavesApp.defaultAssets.WAVES || + this.gatewayService.getPurchasableWithCards()[this.balance.asset.id] || + this.gatewayService.getCryptocurrencies()[this.balance.asset.id] || + this.gatewayService.getFiats()[this.balance.asset.id] || + path(statusPath, ds.dataManager.getOracleData('oracleWaves')) === STATUS_LIST.VERIFIED); } @@ -415,7 +417,7 @@ _setHandlers() { this._initActions(); - i18next.on('languageChanged', this.changeLanguageHandler); + this.listenEventEmitter(i18next, 'languageChanged', this.changeLanguageHandler); this.$node.on('click', `.${SELECTORS.BUTTONS.SEND}`, () => { analytics.send({ diff --git a/ts-scripts/interface.d.ts b/ts-scripts/interface.d.ts index f1e6e9cef6..72dfa40909 100644 --- a/ts-scripts/interface.d.ts +++ b/ts-scripts/interface.d.ts @@ -2,6 +2,7 @@ import { Stream } from 'stream'; export interface IMetaJSON { vendors: Array; + vendorsNotWrapped: Array; exportPageVendors: Array; stylesheets: Array; domain: string; diff --git a/ts-scripts/meta.json b/ts-scripts/meta.json index f671995860..066fbb5f54 100644 --- a/ts-scripts/meta.json +++ b/ts-scripts/meta.json @@ -2,10 +2,8 @@ "vendors": [ "node_modules/@waves/bignumber/dist/bignumber.umd.js", "node_modules/@waves/waves-transactions/dist/min/waves-transactions.min.js", - "node_modules/@sentry/browser/build/bundle.min.js", "node_modules/@waves/oracle-data/dist/oracle-data.min.js", "node_modules/parse-json-bignumber/dist/parse-json-bignumber.min.js", - "node_modules/worker-wrapper/dist/worker-wrapper.js", "node_modules/handlebars/dist/handlebars.min.js", "node_modules/ramda/dist/ramda.min.js", "node_modules/mobile-detect/mobile-detect.min.js", @@ -38,6 +36,10 @@ "node_modules/i18next/dist/umd/i18next.js", "node_modules/n3-charts/build/LineChart.min.js" ], + "vendorsNotWrapped": [ + "node_modules/@sentry/browser/build/bundle.min.js", + "node_modules/worker-wrapper/dist/worker-wrapper.js" + ], "exportPageVendors": [ "node_modules/ts-utils/dist/ts-utils.min.js", "node_modules/@waves/waves-browser-bus/dist/browser-bus.min.js" @@ -165,6 +167,7 @@ ], "developmentScripts": [ "dist/dev/js/vendors.js", + "dist/dev/js/not-wrapped-vendors.js", "dist/dev/js/bundle.js", "dist/dev/js/templates.js" ], diff --git a/ts-scripts/utils.ts b/ts-scripts/utils.ts index 9f20e573e0..3c05fb349d 100644 --- a/ts-scripts/utils.ts +++ b/ts-scripts/utils.ts @@ -158,8 +158,9 @@ export function getScripts(param: IPrepareHTMLOptions, pack, meta) { const sourceFiles = getFilesFrom(join(__dirname, '../src'), '.js', function (name, path) { return !name.includes('.spec') && !path.includes('/test/'); }); + const sentryScripts = meta.vendorsNotWrapped.map((i) => join(__dirname, '..', i)); const cacheKiller = `?v${pack.version}`; - scripts = meta.vendors.map((i) => join(__dirname, '..', i)).concat(sourceFiles); + scripts = meta.vendors.map((i) => join(__dirname, '..', i)).concat(sentryScripts).concat(sourceFiles); meta.debugInjections.forEach((path) => { scripts.unshift(join(__dirname, '../', path)); }); @@ -579,7 +580,7 @@ export function route(connectionType: TConnection, buildType: TBuild, type: TPla return null; } - if (url.indexOf('export') !== -1) { + if (url.indexOf('/export.html') !== -1) { prepareExport().then((file) => { res.end(file); });