diff --git a/data-service/api/transactions/interface.d.ts b/data-service/api/transactions/interface.d.ts index e2ebde1bd9..5f6f447d1e 100644 --- a/data-service/api/transactions/interface.d.ts +++ b/data-service/api/transactions/interface.d.ts @@ -17,7 +17,8 @@ export type T_API_TX = txApi.IData | txApi.ISponsorship | txApi.ISetScript | - txApi.ISetAssetScript; + txApi.ISetAssetScript | + tx.Api.IScriptInvocation; export type T_TX = IIssue | @@ -158,6 +159,14 @@ export module txApi { script: string; } + export interface IScriptInvocation extends IBaseTransaction { + type: 16; + version?: number; + call?: ICall; + dApp: string; + payment?: Array<{ amount: number; assetId: string; }>; + } + export interface IExchangeOrder { amount: string; assetPair: IAssetPair; @@ -318,6 +327,18 @@ export interface IExchangeOrder { timestamp: number; } +export interface IScriptInvocation extends IBaseTransaction { + version?: number; + call?: ICall; + dApp: string; + payment?: Array; +} + +export interface ICall { + args: Array; + function: string; +} + export type TDataEntry = TDataEntryInteger | TDataEntryBoolean | TDataEntryBinary | TDataEntryString; export interface TDataEntryInteger { @@ -343,3 +364,25 @@ export interface TDataEntryString { key: string; value: string; } + +export type TCallArgs = TCallArgsInteger | TCallArgsBoolean | TCallArgsBinary | TCallArgsString; + +export interface TCallArgsInteger { + type: 'integer'; + value: number; +} + +export interface TCallArgsBoolean { + type: 'boolean'; + value: boolean; +} + +export interface TCallArgsBinary { + type: 'binary'; + value: string; // base64 +} + +export interface TCallArgsString { + type: 'string'; + value: string; +} diff --git a/data-service/api/transactions/parse.ts b/data-service/api/transactions/parse.ts index b8bbbe34f9..4a9f7d743e 100644 --- a/data-service/api/transactions/parse.ts +++ b/data-service/api/transactions/parse.ts @@ -15,6 +15,7 @@ import { ISetScript, ISponsorship, ISetAssetScript, + IScriptInvocation, ITransfer, T_API_TX, T_TX, @@ -100,6 +101,8 @@ export function parseTx(transactions: Array, isUTX: boolean, isTokens? return parseScriptTx(transaction, hash, isUTX); case TRANSACTION_TYPE_NUMBER.SET_ASSET_SCRIPT: return parseAssetScript(transaction, hash, isUTX); + case 16: + return parseInvocationTx(transaction, hash, isUTX); default: return transaction; } @@ -265,6 +268,12 @@ export function parseDataTx(tx: txApi.IData, assetsHash: IHash, isUTX: bo return { ...tx, stringifiedData, fee, isUTX }; } +export function parseInvocationTx(tx: txApi.IScriptInvocation, assetsHash: IHash, isUTX: boolean): IScriptInvocation { + const fee = new Money(tx.fee, assetsHash[WAVES_ID]); + const payment = tx.payment.map(payment => new Money(payment.amount, assetsHash[normalizeAssetId(payment.assetId)])); + return { ...tx, fee, payment, isUTX }; +} + function parseSponsorshipTx(tx: txApi.ISponsorship, assetsHash: IHash, isUTX: boolean): ISponsorship { const minSponsoredAssetFee = new Money(tx.minSponsoredAssetFee || 0, assetsHash[tx.assetId]); const fee = new Money(tx.fee, assetsHash[WAVES_ID]); diff --git a/data-service/api/transactions/transactions.ts b/data-service/api/transactions/transactions.ts index 234053834e..f2e047869f 100644 --- a/data-service/api/transactions/transactions.ts +++ b/data-service/api/transactions/transactions.ts @@ -22,13 +22,13 @@ import { pipe, prop, uniqBy, tap } from 'ramda'; import { ExchangeTxFilters } from '@waves/data-service-client-js'; -export function list(address: string, limit = 100): Promise> { - return request({ url: `${configGet('node')}/transactions/address/${address}/limit/${limit}` }) - .then(pipe( - prop('0'), - uniqBy(prop('id')) as any, - )) - .then(transactions => parseTx(transactions as any, false)); +export function list(address: string, limit = 100, after: string): Promise> { + return request({ + url: `${configGet('node')}/transactions/address/${address}/limit/${limit}${after ? `?after=${after}` : ''}` + }).then(pipe( + prop('0'), + uniqBy(prop('id')) as any, + )).then(transactions => parseTx(transactions as any, false)); } export function getExchangeTxList(options: ExchangeTxFilters = Object.create(null)): Promise> { diff --git a/data-service/broadcast/broadcast.ts b/data-service/broadcast/broadcast.ts index bb9e4edbbd..942efb1023 100644 --- a/data-service/broadcast/broadcast.ts +++ b/data-service/broadcast/broadcast.ts @@ -1,7 +1,8 @@ import { request } from '../utils/request'; import { parse } from '../api/matcher/getOrders'; import { get } from '../config'; -import { stringifyJSON } from "../utils/utils"; +import { addOrderToStore, removeOrderFromStore } from '../store'; +import { stringifyJSON } from '../utils/utils'; export function broadcast(data) { @@ -38,6 +39,7 @@ export function createOrderSend(txData) { filled: 0 }]); }) + .then(addOrderToStore); } export function cancelOrderSend(txData, amountId, priceId, type: 'cancel' | 'delete' = 'cancel') { @@ -52,6 +54,7 @@ export function cancelOrderSend(txData, amountId, priceId, type: 'cancel' | 'del body: stringifyJSON(txData) } }).then((data) => { + removeOrderFromStore({ id: txData.orderId }); return data; }); } diff --git a/data-service/classes/DataManager.ts b/data-service/classes/DataManager.ts index f5e611b83b..bf8812f471 100644 --- a/data-service/classes/DataManager.ts +++ b/data-service/classes/DataManager.ts @@ -60,11 +60,10 @@ export class DataManager { return this.pollControl.getPollHash().aliases.lastData || []; } - public getOracleAssetData(id: string): TProviderAsset & { provider: string } { + public getOracleAssetDataByOracleName(id: string, oracleName: string = 'oracleWaves'): TProviderAsset & { provider: string } { let pollHash = this.pollControl.getPollHash(); - const lastData = path(['oracle', 'lastData'], pollHash); + const lastData = path([oracleName, 'lastData'], pollHash); const assets = lastData && lastData.assets || Object.create(null); - const WavesApp = (window as any).WavesApp; const gateways = { @@ -108,8 +107,14 @@ export class DataManager { return assets[id] ? { ...assets[id], provider: lastData.oracle.name } : null; } - public getOracleData() { - return this.pollControl.getPollHash().oracle.lastData; + public getOraclesAssetData (id: string) { + const dataOracleWaves = this.getOracleAssetDataByOracleName(id, 'oracleWaves'); + const dataOracleTokenomica = this.getOracleAssetDataByOracleName(id, 'oracleTokenomica'); + return dataOracleWaves || dataOracleTokenomica; + } + + public getOracleData(oracleName: string) { + return this.pollControl.getPollHash()[oracleName].lastData; } private _getPollBalanceApi(): IPollAPI> { @@ -135,10 +140,9 @@ export class DataManager { }; } - private _getPollOracleApi(): IPollAPI { + private _getPollOracleApi(address: string): IPollAPI { return { get: () => { - const address = get('oracleAddress'); return address ? getOracleData(address) : Promise.resolve({ assets: Object.create(null) }) as any; }, set: () => null @@ -149,15 +153,16 @@ export class DataManager { const balance = new Poll(this._getPollBalanceApi(), 1000); const orders = new Poll(this._getPollOrdersApi(), 1000); const aliases = new Poll(this._getPollAliasesApi(), 10000); - const oracle = new Poll(this._getPollOracleApi(), 30000); + const oracleWaves = new Poll(this._getPollOracleApi(get('oracleWaves')), 30000); + const oracleTokenomica = new Poll(this._getPollOracleApi(get('oracleTokenomica')), 30000); change.on((key) => { - if (key === 'oracleAddress') { - oracle.restart(); + if (key === 'oracleWaves') { + oracleWaves.restart(); } }); - return { balance, orders, aliases, oracle }; + return { balance, orders, aliases, oracleWaves, oracleTokenomica }; } } @@ -166,7 +171,8 @@ type TPollHash = { balance: Poll>; orders: Poll>; aliases: Poll>; - oracle: Poll + oracleWaves: Poll + oracleTokenomica: Poll } export interface IOracleAsset { diff --git a/data-service/config.ts b/data-service/config.ts index e0412abfde..3904d36fab 100644 --- a/data-service/config.ts +++ b/data-service/config.ts @@ -69,5 +69,7 @@ export interface IConfigParams { assets: IHash; minimalSeedLength: number; remappedAssetNames: IHash; - oracleAddress: string; + // oracleAddress: string; + oracleWaves: string; + oracleTokenomica: string; } diff --git a/data-service/index.ts b/data-service/index.ts index f9a47ef253..1df44601d8 100644 --- a/data-service/index.ts +++ b/data-service/index.ts @@ -21,6 +21,8 @@ import { TTimeType } from './utils/utils'; export { getAdapterByType, getAvailableList } from '@waves/signature-adapter'; export { Seed } from './classes/Seed'; export { assetStorage } from './utils/AssetStorage'; +export * from './store'; + export const wavesDataEntities = { ...wavesDataEntitiesModule }; diff --git a/data-service/store.ts b/data-service/store.ts new file mode 100644 index 0000000000..79cfd000f4 --- /dev/null +++ b/data-service/store.ts @@ -0,0 +1,66 @@ +import { toArray } from './utils/utils'; +import { IOrder } from './api/matcher/interface'; +import { pipe, concat, eqProps, uniqBy, prop, differenceWith, tap } from 'ramda'; + +export type TStore = Array>; + +const ordersStore: Array> = []; +const toRemoveOrders: Array> = []; + +function createAddStore(container: TStore, timeout: number) { + return (item: T | Array) => { + toArray(item).forEach((item) => { + const storeItem = { + data: item, + expiration: window.setTimeout(() => { + container.splice(container.indexOf(storeItem), 1); + }, timeout) + }; + container.push(storeItem); + }); + return item; + }; +} + +function removeFromStoreById(container: TStore, idKey: keyof T, item: Partial) { + const id = item[idKey]; + for (let i = container.length - 1; i >= 0; i--) { + if (container[i].data[idKey] === id) { + window.clearTimeout(container[i].expiration); + container.splice(i, 1); + break; + } + } +} + +function createClearStore(addContainer: TStore, addRemoveF: IRemoveOrderFunc>, idKey: keyof T) { + return (item: Partial | Array>) => { + toArray(item).forEach((item) => { + removeFromStoreById(addContainer, idKey, item); + }); + addRemoveF(item); + return item; + }; +} + +function createProcessStore(toAddContainer: TStore, toRemoveContainer: TStore, idKey: string): (list: Array) => Array { + return pipe( + list => concat(toAddContainer.map(prop('data')), list), + list => differenceWith(eqProps(idKey), list, toRemoveContainer.map(prop('data'))) as any, + uniqBy(prop(idKey) as any) + ); +} + +const addToRemoveStore = createAddStore(toRemoveOrders, 3000); +export const addOrderToStore = createAddStore(ordersStore, 3000); +export const removeOrderFromStore = createClearStore(ordersStore, addToRemoveStore, 'id'); +export const processOrdersWithStore = createProcessStore(ordersStore, toRemoveOrders, 'id'); + +export interface IStoreContainerItem { + data: T; + expiration: number; +} + +interface IRemoveOrderFunc { + (item: T | Array): T | Array; +} diff --git a/gulpfile.ts b/gulpfile.ts index d15af099e7..4207f103ed 100644 --- a/gulpfile.ts +++ b/gulpfile.ts @@ -12,7 +12,7 @@ import { getScripts, getStyles, getInitScript, - getLocales + loadLocales } from './ts-scripts/utils'; import { basename, extname, join, sep } from 'path'; import { @@ -292,7 +292,7 @@ task('concat-develop-vendors', function () { task('downloadLocales', ['concat-develop-sources'], function (done) { const dist = join(__dirname, 'dist'); - getLocales(dist).then(() => done()); + loadLocales(dist).then(() => done()); }); task('clean', function () { @@ -431,7 +431,7 @@ task('electron-debug', function (done) { .then(excludeTypeScrip) .then(list => Promise.all(list.map(copyItem))) .then(makePackageJSON) - .then(() => getLocales(root)) + .then(() => loadLocales(root)) .then(() => renameLocaleDirectory()) .then(copyNodeModules) .then(copyI18next) diff --git a/mocks/waves-client-config/master/config.json b/mocks/waves-client-config/master/config.json index 074120b618..cbad80d33d 100644 --- a/mocks/waves-client-config/master/config.json +++ b/mocks/waves-client-config/master/config.json @@ -24,7 +24,8 @@ "CAN_CREATE_ORDER": true, "CAN_CANCEL_ORDER": true, "CAN_PAIRING_WITH_MOBILE": true, - "CAN_ANY_TRANSACTION": true + "CAN_ANY_TRANSACTION": true, + "CAN_SET_ASSET_SCRIPT": true }, "NOTIFICATIONS": [ { diff --git a/package-lock.json b/package-lock.json index 33d178b039..a6a302bbf7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "waves-client", - "version": "1.2.0", + "version": "1.2.4", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -114,6 +114,27 @@ } } }, + "@babel/polyfill": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.3.tgz", + "integrity": "sha512-rkv8WIvJshA5Ev8iNMGgz5WZkRtgtiPexiT7w5qevGTuT7ZBfM3de9ox1y9JR5/OXb/sWGBbWlHNa7vQKqku3Q==", + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "core-js": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==" + }, + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==" + } + } + }, "@babel/template": { "version": "7.0.0-beta.44", "resolved": "http://registry.npmjs.org/@babel/template/-/template-7.0.0-beta.44.tgz", @@ -172,22 +193,18 @@ "to-fast-properties": "^2.0.0" } }, - "@ledgerhq/hw-transport": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-4.35.0.tgz", - "integrity": "sha512-o8ekdoCkHMvOByIKDmAMNDjm8Q5cu+sbqmebPtGrHAPbgIZBUbNA5UupY/Om+xypdxXYnuBw+MF8FyIVOjnIsg==", + "@ledgerhq/devices": { + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/devices/-/devices-4.54.0.tgz", + "integrity": "sha512-v6E4PK6bej/CmMSMVasFWWy1iyh42XaHmUpp5i992/n+PiVQQL5qnQlgXpCq2ZoFinfpnFc7y2lv3qSxAqQimQ==", "requires": { - "events": "^3.0.0" + "@ledgerhq/errors": "^4.54.0" } }, - "@ledgerhq/hw-transport-u2f": { - "version": "4.35.0", - "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-4.35.0.tgz", - "integrity": "sha512-cVPH0SNRrIKVZz9zHvulHGPSdDQiV1hCK634KZa2M2+fMVhQxUi4YRBQz7QpI88CwRyEy+sBfTfSahPWjQUN2Q==", - "requires": { - "@ledgerhq/hw-transport": "^4.35.0", - "u2f-api": "0.2.7" - } + "@ledgerhq/errors": { + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/errors/-/errors-4.54.0.tgz", + "integrity": "sha512-BbAiJHzw/EtIp/HBhDUTbAGj+1cYGGmnrlXSccIxt/MFwcgrX2KgPFbTIAiJJYmPkUSdY4eucyrB9YohzfGCkw==" }, "@types/babel-core": { "version": "6.25.2", @@ -245,6 +262,11 @@ "@types/babel-types": "*" } }, + "@types/base64-js": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/@types/base64-js/-/base64-js-1.2.5.tgz", + "integrity": "sha1-WCskdhaabLpGCiFNR2x0REHYc9U=" + }, "@types/chokidar": { "version": "1.7.5", "resolved": "http://registry.npmjs.org/@types/chokidar/-/chokidar-1.7.5.tgz", @@ -441,6 +463,11 @@ "integrity": "sha1-fjbMv8cwJ43DOrS5CxEcoy5TJBA=", "dev": true }, + "@types/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", + "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==" + }, "@types/mime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-2.0.0.tgz", @@ -593,20 +620,77 @@ } }, "@waves/event-sender": { - "version": "0.5.0-a4", - "resolved": "https://registry.npmjs.org/@waves/event-sender/-/event-sender-0.5.0-a4.tgz", - "integrity": "sha512-3ihnNmxG6iulOwYtvypr1FgKGrfSTMOC1DAvPTcareimL8hLI+ROBdEHa2vAZg5HFLvMeqReXpna8G1fTRnVQw==", + "version": "0.5.4", + "resolved": "https://registry.npmjs.org/@waves/event-sender/-/event-sender-0.5.4.tgz", + "integrity": "sha512-hKnx0mwz6i3+3vitm6hTPPOTXsZwUmUNxtR2ptF3NpJwu1HWm8reOqptGt7UGYnNyiZOqabQZ/1shVQO5aCMAQ==", "requires": { - "@waves/waves-browser-bus": "^0.1.4" + "@waves/waves-browser-bus": "^0.1.5" + }, + "dependencies": { + "@types/node": { + "version": "11.13.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.10.tgz", + "integrity": "sha512-leUNzbFTMX94TWaIKz8N15Chu55F9QSH+INKayQr5xpkasBQBRF3qQXfo3/dOnMU/dEIit+Y/SU8HyOjq++GwA==" + }, + "@waves/waves-browser-bus": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@waves/waves-browser-bus/-/waves-browser-bus-0.1.5.tgz", + "integrity": "sha512-K7iAF2jqSxkEW1DdCAa4Qda21LDuN1MPP5zV/aHJjsO40MvFgMiLcpYSV9xw8OqXzYdZyk1omb9bBOA7r69aIQ==", + "requires": { + "@types/node": "^11.9.4", + "typed-ts-events": "^1.0.5" + } + } } }, "@waves/ledger": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/@waves/ledger/-/ledger-3.2.0.tgz", - "integrity": "sha512-kT0NeAWwe59vRcsJjxdsbUO45Z6/dg7HcjQnMuZLbDKZD3CXF7vuQeRLUX16N4L7QwM4FH1Yv0HH9Rs+DlecnQ==", + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/@waves/ledger/-/ledger-3.3.3.tgz", + "integrity": "sha512-WOdVaPltzkF7hd1IMyLHIvfJgzGYsrrLeTihV+ML1dAu6yM84kdFI34J4eOciX9m2WAlaVFK1syKsu/t2aKF5g==", + "requires": { + "@babel/polyfill": "^7.4.3", + "@ledgerhq/hw-transport-u2f": "^4.54.0" + }, + "dependencies": { + "@ledgerhq/hw-transport": { + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport/-/hw-transport-4.54.0.tgz", + "integrity": "sha512-9UCr35O0Fn7ib0R9BsgY9jXHL/bGCQF66GYOD2GCwLWDVnK5eVewS6J+ljxhWOIsV75OcqJtylRO0mAGOD6tWg==", + "requires": { + "@ledgerhq/devices": "^4.54.0", + "@ledgerhq/errors": "^4.54.0", + "events": "^3.0.0" + } + }, + "@ledgerhq/hw-transport-u2f": { + "version": "4.54.0", + "resolved": "https://registry.npmjs.org/@ledgerhq/hw-transport-u2f/-/hw-transport-u2f-4.54.0.tgz", + "integrity": "sha512-vF0Fiv+UQPfUUl1gLG2RlKjW4BuyKsLMLe8+gcOplUgzguA04LQfv3LC4qoBLG5ByNb32jsJkp38uE4moE87LA==", + "requires": { + "@ledgerhq/errors": "^4.54.0", + "@ledgerhq/hw-transport": "^4.54.0", + "u2f-api": "0.2.7" + } + } + } + }, + "@waves/marshall": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@waves/marshall/-/marshall-0.7.2.tgz", + "integrity": "sha512-rZnIM92R7wY/vpmG0ZoArlyYGddyAL/fI3z/u6thFmekR44S+UDeSmQjHVB9+QKTtyRdMejpAwL0aZPj+DsJmw==", "requires": { - "@ledgerhq/hw-transport-u2f": "^4.24.0", - "babel-polyfill": "^6.26.0" + "@types/base64-js": "^1.2.5", + "@types/long": "^4.0.0", + "base64-js": "^1.3.0", + "long": "^4.0.0", + "parse-json-bignumber": "^0.1.2" + }, + "dependencies": { + "parse-json-bignumber": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/parse-json-bignumber/-/parse-json-bignumber-0.1.3.tgz", + "integrity": "sha512-eE2NSq0PNe3yrtGVTuxrJSpP1pm2/NTRhfhsKA8oy2jDiYAK8BETabTFSymvw3pz6uuu8c4GpWRCCuVEdDFr8g==" + } } }, "@waves/oracle-data": { @@ -615,14 +699,15 @@ "integrity": "sha512-1qxL22a8LRA38xxzmmJktdVdGTfz2d9SXr9SI2gPpCJSKYrKb7SNGbOE3TgIyCRY0fquOHMtkwXuKGRw+LsJoA==" }, "@waves/signature-adapter": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/@waves/signature-adapter/-/signature-adapter-4.2.1.tgz", - "integrity": "sha512-Vmkx1EVJmdhU+Iol3EbKgnG7TpDwlSjVTKVk2pJ5781GVNWH1dSxs/yv9ni3jTDpWFND7OsfU9br/2/mm/WiKw==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/@waves/signature-adapter/-/signature-adapter-4.5.1.tgz", + "integrity": "sha512-bVJqFVRkKivkkkwgLfhwgyp8hnKFZIp0vvvZlBmMOctbp6Tqt1jUTBOTWdo7r7u2I6RbtyrAzGx6SfpQ7h9yjA==", "requires": { "@types/ramda": "^0.25.46", "@waves/data-entities": "^1.6.3", - "@waves/ledger": "^3.0.1", - "@waves/signature-generator": "^5.0.0", + "@waves/ledger": "^3.3.3", + "@waves/marshall": "^0.7.2", + "@waves/signature-generator": "^5.0.1", "@waves/ts-types": "^0.2.0-beta-1", "ramda": "^0.25.0" }, @@ -632,10 +717,38 @@ "resolved": "https://registry.npmjs.org/@types/ramda/-/ramda-0.25.51.tgz", "integrity": "sha512-xcmtfHIgF9SYjhGdsZR1nQslxG4hu0cIpFfLQ4CWdw3KzHvl7ki1AzFLQUkbDTG42ZN3ZsQfdRzXRlkAvbIy5Q==" }, + "@waves/marshall": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/@waves/marshall/-/marshall-0.7.2.tgz", + "integrity": "sha512-rZnIM92R7wY/vpmG0ZoArlyYGddyAL/fI3z/u6thFmekR44S+UDeSmQjHVB9+QKTtyRdMejpAwL0aZPj+DsJmw==", + "requires": { + "@types/base64-js": "^1.2.5", + "@types/long": "^4.0.0", + "base64-js": "^1.3.0", + "long": "^4.0.0", + "parse-json-bignumber": "^0.1.2" + } + }, + "@waves/signature-generator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@waves/signature-generator/-/signature-generator-5.0.1.tgz", + "integrity": "sha512-uYT0X1yl//joz7skzwsw2Z0QWn3s+Zm6pqWUtapnMg1AehZr1HqMi5Qgnx6X/oExDDnb/ot6T2D6KjJAHJ0TKg==", + "requires": { + "@types/crypto-js": "^3.1.43", + "@waves/data-entities": "^1.6.0", + "base64-js": "1.3.0", + "crypto-js": "3.1.9-1" + } + }, "@waves/ts-types": { - "version": "0.2.0-beta-1", - "resolved": "https://registry.npmjs.org/@waves/ts-types/-/ts-types-0.2.0-beta-1.tgz", - "integrity": "sha512-IYEV2NenNfja8rGVtaFiCu7l0KniKgVBcIaUqrdHX7ISGlL+HtRMo7PFn85wMjxhZ9Ulu8CSmLlQYP4nMP9z/w==" + "version": "0.2.0-beta-4", + "resolved": "https://registry.npmjs.org/@waves/ts-types/-/ts-types-0.2.0-beta-4.tgz", + "integrity": "sha512-a3MNk0cLlTB/cULOpv4/C4InCHucQJqCkkv7iqniDkeP60QPaYCohfGkPaF2T/9gVc6ODozJxZnPQg9coSs74A==" + }, + "parse-json-bignumber": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/parse-json-bignumber/-/parse-json-bignumber-0.1.3.tgz", + "integrity": "sha512-eE2NSq0PNe3yrtGVTuxrJSpP1pm2/NTRhfhsKA8oy2jDiYAK8BETabTFSymvw3pz6uuu8c4GpWRCCuVEdDFr8g==" } } }, @@ -656,18 +769,18 @@ "integrity": "sha512-jXbEnZ8dwy4bOZgumFv/9BTjpcCRP/oGAWcOh5pFMoeA/LShDGm2NwIds+4tDf3sEJu+nLD8UjK6aueM0s87RA==" }, "@waves/waves-browser-bus": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/@waves/waves-browser-bus/-/waves-browser-bus-0.1.4.tgz", - "integrity": "sha512-aCqF03qKIsBbd7YACpayB8EdjB/kIZ4Iar6UPu9ubQ0ypBz8UsvtuGPxaGHsGumR2ppF00w/9O4h2MzN8ciaUw==", + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@waves/waves-browser-bus/-/waves-browser-bus-0.1.5.tgz", + "integrity": "sha512-K7iAF2jqSxkEW1DdCAa4Qda21LDuN1MPP5zV/aHJjsO40MvFgMiLcpYSV9xw8OqXzYdZyk1omb9bBOA7r69aIQ==", "requires": { "@types/node": "^11.9.4", "typed-ts-events": "^1.0.5" }, "dependencies": { "@types/node": { - "version": "11.10.4", - "resolved": "https://registry.npmjs.org/@types/node/-/node-11.10.4.tgz", - "integrity": "sha512-wa09itaLE8L705aXd8F80jnFpxz3Y1/KRHfKsYL2bPc0XF+wEWu8sR9n5bmeu8Ba1N9z2GRNzm/YdHcghLkLKg==" + "version": "11.13.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.13.10.tgz", + "integrity": "sha512-leUNzbFTMX94TWaIKz8N15Chu55F9QSH+INKayQr5xpkasBQBRF3qQXfo3/dOnMU/dEIit+Y/SU8HyOjq++GwA==" } } }, @@ -2145,6 +2258,7 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "dev": true, "requires": { "babel-runtime": "^6.26.0", "core-js": "^2.5.0", @@ -2219,6 +2333,7 @@ "version": "6.26.0", "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, "requires": { "core-js": "^2.4.0", "regenerator-runtime": "^0.11.0" @@ -2227,7 +2342,8 @@ "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true } } }, @@ -3595,7 +3711,8 @@ "core-js": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.0.tgz", - "integrity": "sha512-kLRC6ncVpuEW/1kwrOXYX6KQASCVtrh1gQr/UiaVgFlf9WE5Vp+lNe5+h3LuMr5PAucWnnEXwH0nQHRH/gpGtw==" + "integrity": "sha512-kLRC6ncVpuEW/1kwrOXYX6KQASCVtrh1gQr/UiaVgFlf9WE5Vp+lNe5+h3LuMr5PAucWnnEXwH0nQHRH/gpGtw==", + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -8661,9 +8778,9 @@ "dev": true }, "jquery": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.2.1.tgz", - "integrity": "sha1-XE2d5lKvbNCncBVKYxu6ErAVx4c=" + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.4.0.tgz", + "integrity": "sha512-ggRCXln9zEqv6OqAGXFEcshF5dSBvCkzj6Gm2gzuR5fWawaX8t7cxKVkkygKODrDAzKdoYw3l/e3pm3vlT4IbQ==" }, "js-cookie": { "version": "2.2.0", @@ -9147,6 +9264,11 @@ "chalk": "^2.0.1" } }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, "longest": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", @@ -10273,9 +10395,9 @@ } }, "parse-json-bignumber": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/parse-json-bignumber/-/parse-json-bignumber-0.1.2.tgz", - "integrity": "sha512-iW8sZTHi0Ozsi15vKZMCZi5qrkohYW1Z5BrSZ3GPO/EwWcfH0uUozlOBuS/SL6n/mBzSMgxNQj46WiN1oVKDUg==" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-json-bignumber/-/parse-json-bignumber-1.0.0.tgz", + "integrity": "sha512-iUBAXzuCH4NQG5hTe/6nCCe1+u4HBF2yCrrbtOjUAk1qaEVaEOFaR/TXoZuG1FhNWmIIDOrw03V9PQ+/TBpIYA==" }, "parse-node-version": { "version": "1.0.0", @@ -11229,7 +11351,8 @@ "regenerator-runtime": { "version": "0.10.5", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", + "dev": true }, "regenerator-transform": { "version": "0.10.1", diff --git a/package.json b/package.json index 180f4513d8..8f95aca254 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "waves-client", - "version": "1.2.2", + "version": "1.2.6", "description": "The official client application for the Waves platform", "private": true, "repository": { @@ -95,13 +95,14 @@ "@waves/assets-pairs-order": "4.0.0", "@waves/data-entities": "^1.10.1", "@waves/data-service-client-js": "^2.0.0", - "@waves/event-sender": "^0.5.0-a4", - "@waves/ledger": "^3.2.0", + "@waves/event-sender": "^0.5.4", + "@waves/ledger": "^3.3.3", + "@waves/marshall": "^0.7.2", "@waves/oracle-data": "^0.0.6", - "@waves/signature-adapter": "^4.2.1", + "@waves/signature-adapter": "^4.5.1", "@waves/signature-generator": "^5.0.0", "@waves/ts-types": "0.0.2", - "@waves/waves-browser-bus": "^0.1.4", + "@waves/waves-browser-bus": "^0.1.5", "angular": "1.6.6", "angular-animate": "1.6.6", "angular-aria": "1.6.6", @@ -112,14 +113,14 @@ "i18next": "9.1.0", "i18next-locize-backend": "1.2.1", "identity-img": "1.0.0", - "jquery": "3.2.1", + "jquery": "^3.4.0", "js-cookie": "2.2.0", "mobile-detect": "^1.4.1", "mousetrap": "1.6.1", "n3-charts": "2.0.28", "ng-i18next": "1.0.5", "papaparse": "4.3.7", - "parse-json-bignumber": "^0.1.2", + "parse-json-bignumber": "^1.0.0", "qrcode": "1.3.2", "qrcode-reader": "1.0.4", "ramda": "^0.25.0", diff --git a/server.ts b/server.ts index f35f9f54f9..2cfe1d9ad4 100644 --- a/server.ts +++ b/server.ts @@ -1,6 +1,6 @@ import { createSecureServer } from 'http2'; import { createServer } from 'https'; -import { route, parseArguments, stat, getLocales } from './ts-scripts/utils'; +import { route, parseArguments, stat, loadLocales } from './ts-scripts/utils'; import { readFileSync, existsSync,mkdirSync } from 'fs'; import { serialize, parse as parserCookie } from 'cookie'; import { compile } from 'handlebars'; @@ -76,14 +76,7 @@ function createMyServer(port) { if (!existsSync(cachePath)){ mkdirSync(cachePath); } - getLocales(cachePath).then(() => { - const localesTimer = setInterval(function() { - getLocales(cachePath) - .catch(err => console.log(err)) - }, 60 * 10000); - - localesTimer.unref(); - }); + loadLocales(cachePath); if (args.openUrl) { opn(url); diff --git a/src/img/assets/dash.svg b/src/img/assets/dash.svg index 3978488386..5b78121bf3 100644 --- a/src/img/assets/dash.svg +++ b/src/img/assets/dash.svg @@ -1,8 +1,6 @@ - - - - - + + + diff --git a/src/img/icons/transaction-icons-30.svg b/src/img/icons/transaction-icons-30.svg index fc6d382c77..6918471889 100644 --- a/src/img/icons/transaction-icons-30.svg +++ b/src/img/icons/transaction-icons-30.svg @@ -1,158 +1,164 @@ - - - icons-30 + + + Group 2 Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/img/icons/transaction-icons-80.svg b/src/img/icons/transaction-icons-80.svg index d23528cbcd..3c6bf0c1b0 100644 --- a/src/img/icons/transaction-icons-80.svg +++ b/src/img/icons/transaction-icons-80.svg @@ -1,158 +1,174 @@ - - - icons-80 + + + Group 2 Created with Sketch. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/index.hbs b/src/index.hbs index 53e3706c3d..8e1dce9707 100644 --- a/src/index.hbs +++ b/src/index.hbs @@ -366,7 +366,10 @@ defaultResolution: '60' }, modules: [], - oracle: config.oracle, + oracles: { + waves: config.oracles.waves, + tokenomica: config.oracles.tokenomica + }, minAliasLength: 4, maxAliasLength: 30, maxAddressLength: 45, @@ -394,6 +397,7 @@ SPONSORSHIP_STOP: 'sponsorship-stop', SPONSORSHIP_FEE: 'sponsorship-fee', SET_ASSET_SCRIPT: 'set-asset-script', + SCRIPT_INVOCATION: 'script-invocation', UNKNOWN: 'unknown' }, NODE: { @@ -409,7 +413,8 @@ DATA: 'data', SET_SCRIPT: 'setScript', SPONSORSHIP: 'sponsorship', - SET_ASSET_SCRIPT: 'set-asset-script' + SET_ASSET_SCRIPT: 'set-asset-script', + SCRIPT_INVOCATION: 'script-invocation' } }, getLocaleData: config.getLocaleData, diff --git a/src/modules/app/app.js b/src/modules/app/app.js index e256f9c831..c6ae86f9bf 100644 --- a/src/modules/app/app.js +++ b/src/modules/app/app.js @@ -136,7 +136,7 @@ /** * @typedef {object} IWavesApp * @property {string} name - * @property {string} oracle + * @property {object} oracles * @property {string} version * @property {string} type * @property {string} origin diff --git a/src/modules/app/directives/containerAlertNotification/containerAlertNotification.less b/src/modules/app/directives/containerAlertNotification/containerAlertNotification.less index 3620f0f290..90b075f657 100644 --- a/src/modules/app/directives/containerAlertNotification/containerAlertNotification.less +++ b/src/modules/app/directives/containerAlertNotification/containerAlertNotification.less @@ -101,6 +101,13 @@ w-container-alert-notification { } } +.notifications { + position: absolute; + right: 10px; + bottom: 10px; + z-index: 10000; +} + // Top notifications .notifications-top { width: 100%; diff --git a/src/modules/app/initialize/AppConfig.js b/src/modules/app/initialize/AppConfig.js index ce2249d42d..16a835d1b1 100644 --- a/src/modules/app/initialize/AppConfig.js +++ b/src/modules/app/initialize/AppConfig.js @@ -2,11 +2,12 @@ 'use strict'; const config = function ($urlRouterProvider, $stateProvider, $locationProvider) { - + const TransportU2F = require('@ledgerhq/hw-transport-u2f'); const tsUtils = require('ts-utils'); ds.config.setConfig(WavesApp.network); ds.config.set('remappedAssetNames', WavesApp.remappedAssetNames); + ds.config.set('oracleTokenomica', WavesApp.oracles.tokenomica); class AppConfig { @@ -19,7 +20,7 @@ _initAdapters() { - const Transport = window.TransportNodeHid; + const Transport = window.TransportNodeHid || TransportU2F; ds.signAdapters.adapterList.forEach((Adapter) => Adapter.initOptions({ networkCode: WavesApp.network.code.charCodeAt(0), diff --git a/src/modules/app/less/app-icons.less b/src/modules/app/less/app-icons.less index adf2a99204..fc6afd7844 100644 --- a/src/modules/app/less/app-icons.less +++ b/src/modules/app/less/app-icons.less @@ -305,6 +305,14 @@ background-color: rgba(90, 129, 234, 0.1); } +.icon-tx-script-invocation { + &::before { + display: block; + background-position-x: -@tx-icon-size * 22; + } + background-color: rgba(90, 129, 234, 0.1); +} + .icon-info { width: 20px; height: 20px; @@ -412,4 +420,3 @@ .keeper-icon { background: url(/img/icons/keeper-icon.svg) center no-repeat; } - diff --git a/src/modules/app/less/app.less b/src/modules/app/less/app.less index f8df0d089a..ea80c70801 100644 --- a/src/modules/app/less/app.less +++ b/src/modules/app/less/app.less @@ -2,6 +2,14 @@ @import (reference) 'app-icons'; @import (reference) '../../app/less/typography'; +* { + box-sizing: border-box; +} + +*:focus { + outline: none; +} + html, body { width: 100%; @@ -10,53 +18,6 @@ body { overflow: auto; color: @color-disabled-900; background-color: @color-basic-100; - - .notifications { - position: absolute; - right: 10px; - bottom: 10px; - z-index: 10000; - } -} - -::selection { - background: @selection-bg; -} - -::-moz-selection { - background: @selection-bg; -} - -body.welcome, -body.create, -body.restore, -body.import, -body.ledger, -body.tokens, -body.wallet { - .scroll(); -} -body.tokens, - -body.dex, -body.dex-demo { - .scroll-dex(); -} - -ui-view[name="main"] { - display: block; - width: 100%; - height: 100%; - overflow: auto; - background-color: @color-white; -} - -html body .hidden { - display: none !important; -} - -.text-center { - text-align: center; } a { @@ -80,294 +41,102 @@ select:-webkit-autofill:focus { transition: background-color 5000s ease-in-out 0s; } -.waves-logo { - width: 100px; - height: 21px; - background-image: @waves-logo-icon; - background-repeat: no-repeat; - display: block; - margin: 40px auto 80px auto; -} - -md-input-container { - transform: translate3d(0, 0, 0); -} - -* { - box-sizing: border-box; -} - -*:focus { - outline: none; -} - -pre { - margin: 0; - font-family: 'Arial', sans-serif; - font-size: 14px; -} - -.break-all { - word-break: break-all; -} - -.no-user-select { - user-select: none; -} - -w-error-block, -w-empty-block { - width: 100%; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - text-align: center; - - .icon { - background-image: @empty-icon; - background-repeat: no-repeat; - background-position: center center; - width: 100px; - height: 100px; - margin: 0 auto 10px auto; - } -} - -w-error-block { - .icon { - background-image: @error-icon; - } -} - -.ghost { - opacity: 0 !important; -} - -.link { - .footnote-1(); - color: @color-submit-300; - cursor: pointer; -} - -.center { - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - height: 100%; - width: 100%; -} - -.relative { - position: relative; -} - -.absolute { - position: absolute; +::selection { + background: @selection-bg; } -w-scroll-box { - display: flex; - flex-direction: column; - overflow: auto; - height: 100%; - background: @color-white; +::-moz-selection { + background: @selection-bg; } -.status-label, -.status-label-min { - width: auto; - padding: 4px 11px; - border-radius: @border-radius; - text-transform: uppercase; - color: @color-submit-400; - background-color: @color-bluebar-200; - margin: -1px 0 0 6px; - white-space: nowrap; - - &.success, - &.confirmed { - background: @color-success-50; - color: @color-success-400; - } - - &.warning, - &.unconfirmed { - background: rgba(255, 175, 0, 0.1); - color: @color-warning-500; - } - - &.error, - &.cancelled { - background: rgba(239, 72, 41, 0.1); - color: @color-error-500; +body.welcome, +body.create, +body.restore, +body.import, +body.ledger, +body.tokens, +body.wallet, +body.stand { + ::-webkit-scrollbar { + width: 4px; + height: 4px; } - &.active { - color: @color-submit-400; - background-color: @color-bluebar-200; + :hover::-webkit-scrollbar { + display: block; } - &.inactive { - background-color: @asset-label-suspicious; - color: @color-black; + ::-webkit-scrollbar-track { + -webkit-box-shadow: inset 0 0 3px @color-basic-100; + -webkit-border-radius: 0; + border-radius: 0; } -} - -.status-label-min { - .caption-3(); - padding: 3px 6px; - margin-top: 4px; - border-radius: @border-radius / 2; - text-transform: uppercase; -} -.qr-wrapper { - transition: all .3s; - height: auto; - - w-qr-code { - display: block; - margin: @qr-margin; - text-align: center; - width: 200px; - height: 200px; - overflow: hidden; - transition: all .3s; - box-shadow: 0 0 0 5px #FFF; - border-radius: 1px; - - .qr-code-wrap, - img { - width: 200px; - height: 200px; - transition: all .3s; - cursor: pointer; - } + ::-webkit-scrollbar-thumb { + -webkit-border-radius: 0; + border-radius: 0; + background: @color-basic-100; + -webkit-box-shadow: inset 0 0 3px @color-basic-500; } - &.zoomed-in { - w-qr-code { - width: 400px; - height: 400px; - - .qr-code-wrap, - img { - width: 400px; - height: 400px; - } - } + ::-webkit-scrollbar-thumb:window-inactive { + background: @color-basic-200; } } -.code-wrapper { - border: 1px dashed @color-basic-200; - border-radius: @border-radius; - background: @color-basic-50; - height: auto; - max-height: 300px; - word-break: break-all; - padding: 17px; - display: block; - overflow: scroll; - - &-vertical { - overflow-y: auto; - overflow-x: hidden; - pre { - white-space: normal; - } +body.tokens, +body.dex, +body.dex-demo { + ::-webkit-scrollbar { + width: 5px; + height: 5px; + border-radius: 50%; } -} - -.input-toggle { - display: flex; - align-items: center; - w-checkbox-submit { - display: none; + :hover::-webkit-scrollbar { + display: block; } - w-checkbox-submit + label { - width: 40px; - height: 20px; - border: 1px solid @color-basic-200; + ::-webkit-scrollbar-thumb { + border-radius: 6px; background: @color-basic-200; - border-radius: 10px; - display: block; - position: relative; - transition: .3s; - - &:hover { - border: 1px solid @input-toggle-bg-hover; - background: @input-toggle-bg-hover; - } - - &::before { - transition: .3s; - background: @color-white; - width: 18px; - height: 18px; - content: ''; - position: absolute; - left: 0; - top: 0; - border-radius: 50%; - display: block; - } + box-shadow: inset -1px 0 0px 1px @color-white; } - &.active { - w-checkbox-submit + label { - border: 1px solid @color-submit-400; - background: @color-submit-400; - - &::before { - transform: translateX(20px); - } - } + ::-webkit-scrollbar-thumb:window-inactive { + background: @color-basic-200; } } -w-sign-button, -.block { +ui-view[name="main"] { display: block; -} - -.overflow-h { - overflow: hidden; -} - -.flex-column-center { width: 100%; height: 100%; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; + overflow: auto; + background-color: @color-white; } -.flex-column-center-min { - width: 100%; +.waves-logo { + width: 100px; + height: 21px; + background-image: @waves-logo-icon; + background-repeat: no-repeat; + display: block; + margin: 40px auto 80px auto; +} + +w-scroll-box { display: flex; flex-direction: column; - justify-content: center; - align-items: center; + overflow: auto; + height: 100%; + background: @color-white; } -.sleep-block { - width: 100%; - height: 100%; - position: absolute; - left: 0; - top: 0; - bottom: 0; - right: 0; - background-color: @color-black; - opacity: 0; - transition: opacity 2s; - z-index: 100000; +.btn-active() { + cursor: default; + background-color: @color-disabled-100; + color: @color-black; } .main-content { @@ -387,186 +156,6 @@ w-sign-button, } } -.wallet.assets { - .main-content .content { - width: calc(100% ~'- 70px'); - height: calc(100% ~'- 70px'); - padding: @padding-main-layout; - overflow-y: auto; - top: 70px; - right: 0; - bottom: 0; - } -} - -.asset-modal { - height: 100%; - - &__head { - padding-top: @padding-main-layout * 4; - height: 170px; - position: relative; - } - - &__head-content { - display: flex; - } - - &__logo { - position: relative; - margin: 0 20px 0 0; - left: 0; - z-index: 1; - } - - &__name { - display: flex; - align-items: center; - margin: 0; - font-weight: normal; - } - - &__data { - display: flex; - flex-direction: column; - min-height: 65px; - justify-content: center; - } - - .chart-wrapper { - position: absolute; - opacity: 0.2; - height: 76px; - width: calc(100% ~'+ 80px'); - left: -40px; - bottom: 0; - border-bottom: 1px solid @color-submit-300; - - .interactive-stop { - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - } - - .chart-tooltip, - .chart-legend { // Lib ng3-charts - display: none !important; - } - } -} - -.md-dialog-backdrop:nth-of-type(even) { - z-index: 81; -} - -.md-dialog-backdrop:nth-of-type(odd) { - z-index: 79; - opacity: 0.7; -} - -.md-dialog-container:first-child:nth-of-type(even) { - z-index: 75; -} - -.md-dialog-container:nth-of-type(odd) { - z-index: 82; -} - -._internal-error { - display: none; -} - -svg.chart { - .axis { - .tick line { - display: none; - } - .domain { - stroke: transparent; - } - - & > .tick > text { - fill: @color-disabled-700; - font-size: 13px; - } - } -} - -.md-dialog-container { - md-dialog { - box-shadow: none; - position: absolute; - max-height: 90%; - width: 540px; - background: @color-white; - color: @color-disabled-900; - - md-dialog-actions { - display: flex; - flex-direction: row; - justify-content: center; - } - } -} - -md-toolbar.md-default-theme:not(.md-menu-toolbar), -md-toolbar:not(.md-menu-toolbar) { - background-color: @color-white; - color: @color-black; - border-bottom: 1px solid @color-basic-200; -} - -.chart-legend { - display: none; - margin-left: 40px; - - .legend-item { - display: block; - height: 38px; - } -} - -.btn-wrap.btn-group { - box-sizing: border-box; - padding: 0; - display: flex; - flex-direction: row; - justify-content: center; - - .btn-active { - cursor: default; - background-color: @color-disabled-100; - color: @color-black; - } - - & > *:first-child .btn, & > .btn:first-child { - border-left: 1px solid @color-disabled-100; - border-bottom-left-radius: 5px; - border-top-left-radius: 5px; - } - - & > *:last-child .btn, & > .btn:last-child { - border-bottom-right-radius: 5px; - border-top-right-radius: 5px; - } - - .btn { - display: block; - box-sizing: border-box; - cursor: pointer; - padding: 4px 10px; - border-bottom: 1px solid @color-disabled-100; - border-top: 1px solid @color-disabled-100; - border-right: 1px solid @color-disabled-100; - - &:active { - .btn-active(); - } - } -} - .main { .main-content { background-color: @app-background; @@ -579,12 +168,36 @@ md-toolbar:not(.md-menu-toolbar) { } } -.flex { - display: flex; -} +@media screen and (max-width: 768px) { -.flex-between { - justify-content: space-between; + .main-content { + display: flex; + flex-direction: column; + + & > w-header { + order: 1; + } + & > w-left-menu { + order: 0; + } + & > div.content { + order: 2; + } + + .content { + overflow: auto; + height: 100%; + width: 100%; + position: relative; + right: auto; + left: 0; + top: 0; + bottom: auto; + margin: 0; + padding: 10px; + margin-top: 60px; + } + } } .content ui-view[name="mainContent"], @@ -633,247 +246,3 @@ md-toolbar:not(.md-menu-toolbar) { background: none transparent; } } - -w-permit { - display: block; -} - -.buttons-wrapper { - width: 100%; - display: flex; - justify-content: space-between; - align-items: center; - - w-button, - .fake-button { - flex-basis: 48%; - max-width: 48%; - } -} - -.hide-selection() { - background: none transparent; -} - -.nowrap { - white-space: nowrap; -} - -.ellipsis { - text-overflow: ellipsis; - overflow: hidden; - white-space: nowrap; -} - -.pointer { - cursor: pointer; -} - -.assets-wrapper { - height: 100%; - min-height: 210px; -} - -.portfolio-list w-scroll-box { - overflow: auto; - min-height: calc(~'100vh - 207px'); - max-height: calc(~'100vh - 207px'); -} - -.info-block { - position: relative; - padding-left: 30px; - color: @color-basic-500; - - i { - position: absolute; - left: 0; - top: 2px; - } -} - -.unit-checkbox { - display: flex; - min-height: auto; - margin-bottom: 20px; - - w-checkbox-submit { - flex-grow: 0; - align-self: flex-start; - display: block; - } - - label { - flex-grow: 1; - } -} - -.asset { - &__wrapper { - display: flex; - align-items: center; - @media screen and (max-width: 768px) { - flex-direction: row; - } - } -} - -.scroll { - ::-webkit-scrollbar { - width: 4px; - height: 4px; - } - - :hover::-webkit-scrollbar { - display: block; - } - - ::-webkit-scrollbar-track { - -webkit-box-shadow: inset 0 0 3px @color-basic-100; - -webkit-border-radius: 0; - border-radius: 0; - } - - ::-webkit-scrollbar-thumb { - -webkit-border-radius: 0; - border-radius: 0; - background: @color-basic-100; - -webkit-box-shadow: inset 0 0 3px @color-basic-500; - } - - ::-webkit-scrollbar-thumb:window-inactive { - background: @color-basic-200; - } -} - -.scroll-dex { - ::-webkit-scrollbar { - width: 5px; - height: 5px; - border-radius: 50%; - } - - :hover::-webkit-scrollbar { - display: block; - } - - ::-webkit-scrollbar-thumb { - border-radius: 6px; - background: @color-basic-200; - box-shadow: inset -1px 0 0px 1px @color-white; - } - - ::-webkit-scrollbar-thumb:window-inactive { - background: @color-basic-200; - } -} - -@media screen and (min-width: 1024px) { - w-left-menu w-responsive-menu { - min-height: 270px; - } -} - -@media screen and (max-width: 768px) { - - body { - - &.wallet.assets { - .main-content .content { - top: 0; - padding: 10px; - width: 100%; - height: calc(100% ~'- 50px'); - } - } - - &.wallet { - min-width: 100%; - } - - &.portfolio { - .portfolio-list { - w-scroll-box { - min-height: calc(100vh ~'- 130px'); - max-height: 100%; - } - } - } - } - - // end body - .assets-wrapper { - max-height: 100%; - overflow-y: visible; - overflow-x: visible; - } - - .main-content { - display: flex; - flex-direction: column; - - & > w-header { - order: 1; - } - & > w-left-menu { - order: 0; - } - & > div.content { - order: 2; - } - - .content { - overflow: auto; - height: 100%; - width: 100%; - position: relative; - right: auto; - left: 0; - top: 0; - bottom: auto; - margin: 0; - padding: 10px; - margin-top: 60px; - } - } -} - -@media screen and (max-width: 600px) { - .qr-wrapper { - &.zoomed-in { - w-qr-code { - width: 340px; - height: 340px; - - .qr-code-wrap, - img { - width: 340px; - height: 340px; - } - } - } - } -} - -@media screen and (max-width: 540px) { - .md-dialog-container { - md-dialog { - width: 100%; - max-width: 100%; - min-width: 360px; - height: 100%; - max-height: 100%; - left: 0; - top: 0; - transform-origin: center; - transform: translateY(0) translateX(0); - border-radius: 0; - - md-dialog-content { - padding: 20px 20px 0; - height: 100%; - color: @color-disabled-900; - } - } - } -} diff --git a/src/modules/app/less/classes.less b/src/modules/app/less/classes.less new file mode 100644 index 0000000000..d1ab508cb2 --- /dev/null +++ b/src/modules/app/less/classes.less @@ -0,0 +1,116 @@ +@import (reference) '../../app/less/typography'; + +.hidden { + display: none !important; +} + +.text-center { + text-align: center; +} + +.pre { + margin: 0; + font-family: 'Arial', sans-serif; + font-size: 14px; +} + +.break-all { + word-break: break-all; +} + +.no-user-select { + user-select: none; +} + +.ghost { + opacity: 0 !important; +} + +.link { + .footnote-1(); + color: @color-submit-300; + cursor: pointer; +} + +.center { + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; + height: 100%; + width: 100%; +} + +.relative { + position: relative; +} + +.absolute { + position: absolute; +} +.overflow-h { + overflow: hidden; +} + +.overflow { + overflow: auto; +} + +.flex-column-center { + width: 100%; + height: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +.flex-column-center-min { + width: 100%; + display: flex; + flex-direction: column; + justify-content: center; + align-items: center; +} + +._internal-error { + display: none; +} + +.flex { + display: flex; +} + +.flex-between { + justify-content: space-between; +} + +.nowrap { + white-space: nowrap; +} + +.ellipsis { + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; +} + +.pointer { + cursor: pointer; +} + +.info-block { + position: relative; + padding-left: 30px; + color: @color-basic-500; + + i { + position: absolute; + left: 0; + top: 2px; + } +} + +.hide-selection { + background: none transparent; +} diff --git a/src/modules/app/services/DefaultSettings.js b/src/modules/app/services/DefaultSettings.js index cbc8b29857..09ae614c1e 100644 --- a/src/modules/app/services/DefaultSettings.js +++ b/src/modules/app/services/DefaultSettings.js @@ -42,7 +42,7 @@ needReadNewTerms: false, lastInterval: WavesApp.dex.defaultResolution, baseAssetId: WavesApp.defaultAssets.USD, - assetsOracle: WavesApp.oracle, + oracleWaves: WavesApp.oracles.waves, events: Object.create(null), lng: 'en', send: { diff --git a/src/modules/app/services/User.js b/src/modules/app/services/User.js index 93b55f1f5a..4c4e34b6e5 100644 --- a/src/modules/app/services/User.js +++ b/src/modules/app/services/User.js @@ -555,7 +555,7 @@ ds.config.set(key, this._settings.get(`network.${key}`)); }); - ds.config.set('oracleAddress', this.getSetting('assetsOracle')); + ds.config.set('oracleWaves', this.getSetting('oracleWaves')); ds.app.login(data.address, data.api); diff --git a/src/modules/app/services/state/state.less b/src/modules/app/services/state/state.less new file mode 100644 index 0000000000..04037499ba --- /dev/null +++ b/src/modules/app/services/state/state.less @@ -0,0 +1,15 @@ +@import (reference) 'config'; + +.sleep-block { + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; + bottom: 0; + right: 0; + background-color: @color-black; + opacity: 0; + transition: opacity 2s; + z-index: 100000; +} \ No newline at end of file diff --git a/src/modules/app/services/waves/node/content/Transactions.js b/src/modules/app/services/waves/node/content/Transactions.js index 4275001600..738c60b785 100644 --- a/src/modules/app/services/waves/node/content/Transactions.js +++ b/src/modules/app/services/waves/node/content/Transactions.js @@ -61,11 +61,12 @@ /** * Get transactions list by user * @param {number} [limit] + * @param {string} [after] * @return {Promise} */ @decorators.cachable(1) - list(limit = 1000) { - return ds.api.transactions.list(user.address, limit) + list(limit = 1000, after) { + return ds.api.transactions.list(user.address, limit, after) .then(list => list.map(this._pipeTransaction())); } @@ -100,7 +101,6 @@ } createTransaction(txData) { - const tx = { sender: user.address, timestamp: Date.now(), @@ -120,7 +120,6 @@ */ _pipeTransaction() { return (tx) => { - tx.timestamp = new Date(tx.timestamp); tx.typeName = utils.getTransactionTypeName(tx); tx.templateType = Transactions._getTemplateType(tx); @@ -180,6 +179,8 @@ return 13; case WavesApp.TRANSACTION_TYPES.NODE.SPONSORSHIP: return 14; + case WavesApp.TRANSACTION_TYPES.NODE.SCRIPT_INVOCATION: + return 16; default: throw new Error('Wrong tx name!'); } @@ -215,6 +216,8 @@ return 'sponsorship'; case TYPES.SPONSORSHIP_FEE: return 'sponsorship_fee'; + case TYPES.SCRIPT_INVOCATION: + return 'script-invocation'; case TYPES.UNKNOWN: return 'unknown'; default: diff --git a/src/modules/create/less/confirm-backup.less b/src/modules/create/less/confirm-backup.less index 514db68802..7ce0d3eeb9 100644 --- a/src/modules/create/less/confirm-backup.less +++ b/src/modules/create/less/confirm-backup.less @@ -3,10 +3,6 @@ margin: auto; text-align: center; - .description { - margin: 10px 0 50px 0; - } - .seed-error { margin-top: -40px; } diff --git a/src/modules/create/templates/confirmBackup.html b/src/modules/create/templates/confirmBackup.html index d9bbd03791..9046a8d6b4 100644 --- a/src/modules/create/templates/confirmBackup.html +++ b/src/modules/create/templates/confirmBackup.html @@ -5,7 +5,7 @@ -
+
diff --git a/src/modules/create/templates/create.html b/src/modules/create/templates/create.html index 9771a03c50..bd194289d2 100644 --- a/src/modules/create/templates/create.html +++ b/src/modules/create/templates/create.html @@ -1,8 +1,5 @@ - - - + + + diff --git a/src/modules/desktop/less/desktop.less b/src/modules/desktop/less/desktop.less index a53d137a96..13c9526dbd 100644 --- a/src/modules/desktop/less/desktop.less +++ b/src/modules/desktop/less/desktop.less @@ -30,7 +30,6 @@ w-checkbox-submit { vertical-align: top; - margin-right: 10px; } &__button { diff --git a/src/modules/desktop/templates/desktop.html b/src/modules/desktop/templates/desktop.html index 86446c3bc7..ea53138875 100644 --- a/src/modules/desktop/templates/desktop.html +++ b/src/modules/desktop/templates/desktop.html @@ -1,12 +1,9 @@
- - - + + +
@@ -27,6 +24,6 @@ - +
diff --git a/src/modules/dex/directives/createOrder/createOrder.less b/src/modules/dex/directives/createOrder/createOrder.less index 9381af744c..699ecdc7ea 100644 --- a/src/modules/dex/directives/createOrder/createOrder.less +++ b/src/modules/dex/directives/createOrder/createOrder.less @@ -422,7 +422,6 @@ w-create-order { } } } - } } } diff --git a/src/modules/dex/directives/dexBlock/dexBlock.html b/src/modules/dex/directives/dexBlock/dexBlock.html index d7a254a8bc..87ab1c2ed2 100644 --- a/src/modules/dex/directives/dexBlock/dexBlock.html +++ b/src/modules/dex/directives/dexBlock/dexBlock.html @@ -1,11 +1,15 @@
diff --git a/src/modules/dex/directives/dexMyOrders/DexMyOrders.js b/src/modules/dex/directives/dexMyOrders/DexMyOrders.js index 3ccab74218..7b9970eaef 100644 --- a/src/modules/dex/directives/dexMyOrders/DexMyOrders.js +++ b/src/modules/dex/directives/dexMyOrders/DexMyOrders.js @@ -68,6 +68,10 @@ * @type {boolean} */ loadingError = false; + /** + * @type {boolean} + */ + showAnims = false; constructor() { @@ -156,6 +160,84 @@ } } + /** + * @return {Promise | never>} + * @private + */ + static _getAllOrders() { + return waves.matcher.getOrders() + .then(filter(whereEq({ isActive: true }))) + .catch(() => (this.loadingError = true)); + } + + static _animateNotification($element) { + return utils.animate($element, { t: 100 }, { + duration: 1200, + step: function (tween) { + const progress = ease.bounceOut(tween / 100); + $element.css('transform', `translate(0, ${-100 + progress * 100}%)`); + } + }) + .then(() => utils.wait(700)) + .then(() => { + return utils.animate($element, { t: 0 }, { + duration: 500, + step: function (tween) { + const progress = ease.linear(tween / 100); + $element.css('transform', `translate(0, ${(-((1 - progress) * 100))}%)`); + } + }); + }); + } + + static _getTransactionsByOrderIdHash(txList) { + const uniqueList = uniqBy(prop('id'), txList); + const transactionsByOrderHash = Object.create(null); + uniqueList.forEach((tx) => { + ['order1', 'order2'].forEach((orderFieldName) => { + if (!transactionsByOrderHash[tx[orderFieldName].id]) { + transactionsByOrderHash[tx[orderFieldName].id] = []; + } + transactionsByOrderHash[tx[orderFieldName].id].push(DexMyOrders._remapTx(tx)); + }); + }); + return transactionsByOrderHash; + } + + static _remapTx(tx) { + const fee = (tx, order) => order.orderType === 'sell' ? tx.sellMatcherFee : tx.buyMatcherFee; + const emptyFee = new Money(0, tx.fee.asset); + const userFee = [tx.order1, tx.order2] + .filter((order) => order.sender === user.address) + .reduce((acc, order) => acc.add(fee(tx, order)), emptyFee); + + return { ...tx, userFee }; + } + + /** + * @param {IOrder} order + * @private + */ + static _remapOrders(matcherPublicKey) { + return order => { + const assetPair = order.assetPair; + const pair = `${assetPair.amountAsset.displayName} / ${assetPair.priceAsset.displayName}`; + const isNew = DexMyOrders._isNewOrder(order.timestamp.getTime()); + const percent = new BigNumber(order.progress * 100).dp(2).toFixed(); + return waves.matcher.getCreateOrderFee({ ...order, matcherPublicKey }) + .then(fee => ({ ...order, isNew, percent, pair, fee })); + }; + } + + /** + * @param {number} timestamp + * @return {boolean} + * @private + */ + static _isNewOrder(timestamp) { + return ds.utils.normalizeTime(Date.now()) < timestamp + 1000 * 8; + } + /** * @param {IOrder} order */ @@ -218,7 +300,6 @@ * @param order */ dropOrder(order) { - if (!permissionManager.isPermitted('CAN_CANCEL_ORDER')) { const $notify = $element.find('.js-order-notification'); DexMyOrders._animateNotification($notify); @@ -227,9 +308,22 @@ const dataPromise = this.dropOrderGetSignData(order); + const classNameToOrder = (className, isRemove = false) => { + const $row = $element.find(`.order_${order.id}`).closest('.order-row'); + + if (isRemove) { + $row.removeClass(className); + } else { + $row.addClass(className); + } + }; + + classNameToOrder('pre-leave'); + dataPromise .then((signedTxData) => ds.cancelOrder(signedTxData, order.amount.asset.id, order.price.asset.id)) .then(() => { + classNameToOrder('force-leave'); const canceledOrder = this.orders.find(whereEq({ id: order.id })); canceledOrder.state = 'Canceled'; notification.info({ @@ -242,6 +336,7 @@ } }) .catch(e => { + classNameToOrder('pre-leave', true); const error = utils.parseError(e); notification.error({ ns: 'app.dex', @@ -271,7 +366,7 @@ if (needApply) { $scope.$apply(); } - + this.showAnims = true; return null; } @@ -306,84 +401,6 @@ }); } - /** - * @return {Promise | never>} - * @private - */ - static _getAllOrders() { - return waves.matcher.getOrders() - .then(filter(whereEq({ isActive: true }))) - .catch(() => (this.loadingError = true)); - } - - static _animateNotification($element) { - return utils.animate($element, { t: 100 }, { - duration: 1200, - step: function (tween) { - const progress = ease.bounceOut(tween / 100); - $element.css('transform', `translate(0, ${-100 + progress * 100}%)`); - } - }) - .then(() => utils.wait(700)) - .then(() => { - return utils.animate($element, { t: 0 }, { - duration: 500, - step: function (tween) { - const progress = ease.linear(tween / 100); - $element.css('transform', `translate(0, ${(-((1 - progress) * 100))}%)`); - } - }); - }); - } - - static _getTransactionsByOrderIdHash(txList) { - const uniqueList = uniqBy(prop('id'), txList); - const transactionsByOrderHash = Object.create(null); - uniqueList.forEach((tx) => { - ['order1', 'order2'].forEach((orderFieldName) => { - if (!transactionsByOrderHash[tx[orderFieldName].id]) { - transactionsByOrderHash[tx[orderFieldName].id] = []; - } - transactionsByOrderHash[tx[orderFieldName].id].push(DexMyOrders._remapTx(tx)); - }); - }); - return transactionsByOrderHash; - } - - static _remapTx(tx) { - const fee = (tx, order) => order.orderType === 'sell' ? tx.sellMatcherFee : tx.buyMatcherFee; - const emptyFee = new Money(0, tx.fee.asset); - const userFee = [tx.order1, tx.order2] - .filter((order) => order.sender === user.address) - .reduce((acc, order) => acc.add(fee(tx, order)), emptyFee); - - return { ...tx, userFee }; - } - - /** - * @param {IOrder} order - * @private - */ - static _remapOrders(matcherPublicKey) { - return order => { - const assetPair = order.assetPair; - const pair = `${assetPair.amountAsset.displayName} / ${assetPair.priceAsset.displayName}`; - const isNew = DexMyOrders._isNewOrder(order.timestamp.getTime()); - const percent = new BigNumber(order.progress * 100).dp(2).toFixed(); - return waves.matcher.getCreateOrderFee({ ...order, matcherPublicKey }) - .then(fee => ({ ...order, isNew, percent, pair, fee })); - }; - } - - /** - * @param {number} timestamp - * @return {boolean} - * @private - */ - static _isNewOrder(timestamp) { - return ds.utils.normalizeTime(Date.now()) < timestamp + 1000 * 8; - } - } return new DexMyOrders(); diff --git a/src/modules/dex/directives/dexMyOrders/myOrders.html b/src/modules/dex/directives/dexMyOrders/myOrders.html index ca67f7298f..f5d3f96d1b 100644 --- a/src/modules/dex/directives/dexMyOrders/myOrders.html +++ b/src/modules/dex/directives/dexMyOrders/myOrders.html @@ -19,7 +19,8 @@
-
+
@@ -76,6 +77,7 @@
diff --git a/src/modules/dex/directives/dexMyOrders/myOrders.less b/src/modules/dex/directives/dexMyOrders/myOrders.less index 80b7c7a52d..4de2f55623 100644 --- a/src/modules/dex/directives/dexMyOrders/myOrders.less +++ b/src/modules/dex/directives/dexMyOrders/myOrders.less @@ -8,6 +8,56 @@ w-dex-my-orders { overflow: hidden; overflow-x: auto; + /* ngRepeat animation*/ + + .repeatItemTransition.ng-enter, + .repeatItemTransition.ng-leave { + transition: ease-in-out 0.4s; + } + + + .repeatItemTransition.ng-enter, + .repeatItemTransition.ng-leave.ng-leave-active { + opacity: 0; + max-height: 0; + } + + .repeatItemTransition.ng-leave, + .repeatItemTransition.ng-enter.ng-enter-active { + opacity: 1; + max-height: 30px; + pointer-events: none; + + &.pre-leave { + opacity: 0.3; + } + + @media screen and (max-width: 1024px) { + max-height: 69px; + } + } + + .repeatItemTransition.pre-leave { + transition: opacity 0.4s; + opacity: 0.3; + max-height: 30px; + pointer-events: none; + + @media screen and (max-width: 1024px) { + max-height: 69px; + } + + &.force-leave { + transition: ease-in-out 0.4s; + opacity: 0; + max-height: 0; + @media screen and (max-width: 1024px) { + max-height: 0 !important; + } + } + } + + //end .centered { position: absolute; width: 100%; diff --git a/src/modules/dex/directives/dexWatchlist/DexWatchlist.html b/src/modules/dex/directives/dexWatchlist/DexWatchlist.html index c1eee60f97..43acf45cd8 100644 --- a/src/modules/dex/directives/dexWatchlist/DexWatchlist.html +++ b/src/modules/dex/directives/dexWatchlist/DexWatchlist.html @@ -20,11 +20,15 @@
- + + + diff --git a/src/modules/dex/directives/dexWatchlist/DexWatchlist.less b/src/modules/dex/directives/dexWatchlist/DexWatchlist.less index 75673dd19d..01eba05d97 100644 --- a/src/modules/dex/directives/dexWatchlist/DexWatchlist.less +++ b/src/modules/dex/directives/dexWatchlist/DexWatchlist.less @@ -19,6 +19,7 @@ body.dex-demo .dex-wrapper { display: inline-block; width: 100%; z-index: 4; + height: 35px; w-help-icon { position: absolute; @@ -43,19 +44,12 @@ body.dex-demo .dex-wrapper { } } - input { - background: @input-search-icon 8px 50% no-repeat; - border: 0 none; - width: 100%; - padding-left: 31px; - height: 35px; - color: @color-disabled-900; - font-size: @font-size-caption-1; - border-bottom: 1px solid @color-basic-100; + .search-input { + border-bottom-color: @color-basic-100; &:focus { - box-shadow: 0 0 0 1px @color-submit-400 inset; position: relative; + border-color: @color-submit-300; z-index: 2; } diff --git a/src/modules/dex/directives/myBalance/myBalance.less b/src/modules/dex/directives/myBalance/myBalance.less index 1347c7aca1..7d43b95859 100644 --- a/src/modules/dex/directives/myBalance/myBalance.less +++ b/src/modules/dex/directives/myBalance/myBalance.less @@ -87,6 +87,11 @@ body.dex-demo .dex-wrapper { background: @dex-copybalance-icon no-repeat right center; } } + + .search-input { + background-position: 4px center; + padding-left: 24px; + } } w-asset-logo { @@ -134,7 +139,7 @@ body.dex-demo .dex-wrapper { } } - &__search-container input { + &__search-container .search-input { height: 36px; } diff --git a/src/modules/dex/less/dex.less b/src/modules/dex/less/dex.less index c1344c96c8..76e9f12041 100644 --- a/src/modules/dex/less/dex.less +++ b/src/modules/dex/less/dex.less @@ -97,16 +97,6 @@ body.dex, body.dex-demo { } .smart-table { - &__search-container { - input { - background: @input-search-icon left 48% no-repeat; - border: 0 none; - width: 100%; - padding-left: 20px; - color: @color-disabled-900; - } - } - &__row { height: 28px; width: 100%; diff --git a/src/modules/dex/services/CandlesService.js b/src/modules/dex/services/CandlesService.js index de3d7487e8..b9b3e956b6 100644 --- a/src/modules/dex/services/CandlesService.js +++ b/src/modules/dex/services/CandlesService.js @@ -50,19 +50,20 @@ const { options, config: candleConfig } = utils.getValidCandleOptions(from, to, interval); const promises = options.map(option => config.getDataService().getCandles(amountId, priceId, option)); - const convertBigNumber = (num) => num.isNaN() ? null : num.toNumber(); + const convertBigNumber = num => num.isNaN() ? null : num.toNumber(); const candles = Promise.all(promises) .then(pipe(map(prop('data')), flatten)) - .then(list => list.map(candle => ({ - txsCount: candle.txsCount || 0, - high: convertBigNumber(candle.high), - low: convertBigNumber(candle.low), - close: convertBigNumber(candle.close), - open: convertBigNumber(candle.open), - volume: convertBigNumber(candle.volume), - time: new Date(candle.time).getTime() - }))); + .then(list => list + .map(candle => ({ + txsCount: candle.txsCount || 0, + high: convertBigNumber(candle.high), + low: convertBigNumber(candle.low), + close: convertBigNumber(candle.close), + open: convertBigNumber(candle.open), + volume: convertBigNumber(candle.volume), + time: new Date(candle.time).getTime() + }))); const lastTrade = ds.api.pairs.get(amountId, priceId) .then(pair => waves.matcher.getLastPrice(pair) @@ -71,15 +72,12 @@ return Promise.all([candles, lastTrade]) .then(([candles, lastTrade]) => { if (candles.length === 1 && lastTrade) { - const lastCandle = candles[candles.length - 1]; - - if (lastCandle.open != null) { - lastCandle.close = Number(lastTrade.price.toTokens()); - } + candles[candles.length - 1].close = Number(lastTrade.price.toTokens()); } else { candles = candleConfig.converter(candles); } - return candles; + return candles + .filter(candle => candle.open != null); }).catch(() => utils.wait(5000).then(() => [])); } diff --git a/src/modules/import/templates/import.html b/src/modules/import/templates/import.html index d6cc073713..4b425e1396 100644 --- a/src/modules/import/templates/import.html +++ b/src/modules/import/templates/import.html @@ -39,7 +39,7 @@ diff --git a/src/modules/ledger/templates/ledger.html b/src/modules/ledger/templates/ledger.html index c295bccb68..48d7bf2819 100644 --- a/src/modules/ledger/templates/ledger.html +++ b/src/modules/ledger/templates/ledger.html @@ -21,7 +21,7 @@

-
+
diff --git a/src/modules/restore/less/restore.less b/src/modules/restore/less/restore.less index 56c0811cb4..4726101462 100644 --- a/src/modules/restore/less/restore.less +++ b/src/modules/restore/less/restore.less @@ -28,28 +28,13 @@ body.restore { resize: vertical; } - .address-block-info { - background-color: @color-disabled-50; - border-top: 1px solid @color-basic-200; - height: 76px; - display: flex; - flex-direction: row; - padding: 18px 14px; - - .avatar-fake { - width: 40px; - height: 40px; - border-radius: 100%; - background-color: @color-basic-100; - } - - .address-block { + .address { + &-block { height: 30px; position: relative; top: -5px; .address { - &.empty { position: relative; top: 3px; @@ -60,9 +45,24 @@ body.restore { } } } + + &-block-info { + background-color: @color-disabled-50; + border-top: 1px solid @color-basic-200; + height: 76px; + display: flex; + flex-direction: row; + padding: 18px 14px; + } + + .avatar-fake { + width: 40px; + height: 40px; + border-radius: 100%; + background-color: @color-basic-100; + } } } - } } diff --git a/src/modules/restore/templates/restore.html b/src/modules/restore/templates/restore.html index 8634ffd90c..82c5cb0546 100644 --- a/src/modules/restore/templates/restore.html +++ b/src/modules/restore/templates/restore.html @@ -1,10 +1,7 @@
- - - + + + diff --git a/src/modules/stand/controller/StandCtrl.js b/src/modules/stand/controller/StandCtrl.js index 9593518432..615dfccb4b 100644 --- a/src/modules/stand/controller/StandCtrl.js +++ b/src/modules/stand/controller/StandCtrl.js @@ -1,3 +1,4 @@ +/* eslint-disable max-len */ (function () { 'use strict'; @@ -6,22 +7,105 @@ * @param $scope * @return {StandCtrl} */ - const controller = function (Base, $scope) { + const controller = function (Base, $scope, userNotification, notification) { class StandCtrl extends Base { constructor() { + super($scope); + + const seed = 'merry evil keep lost fox tech absent trololo both field get input div cosmic'; + /** + * @type {string} + */ + this.tab = 'info'; + this.qrData = 'Keep on waving, we`ll take care of the bad guys'; + this.info = this.dataCopy = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'; + /** + * @type {boolean} + */ this.invalid = true; this.warning = true; this.success = true; this.error = true; this.active = true; this.inactive = true; + this.seedConfirmWasFilled = false; + this.seedIsValid = false; + /** + * @type {string} + */ + this.seed = seed; + + const loop = (index) => { + userNotification.info({ + body: { + literal: index + 1 + } + }).then(() => loop(index + 1)); + }; + + loop(0); + + const loop2 = (index) => { + userNotification.error({ + body: { + literal: index + 1 + } + }).then(() => loop2(index + 1)); + }; + + loop2(0); + + const loop3 = (index) => { + userNotification.success({ + body: { + literal: index + 1 + } + }).then(() => loop3(index + 1)); + }; + + loop3(0); + + const loop4 = (index) => { + userNotification.warn({ + body: { + literal: index + 1 + } + }).then(() => loop4(index + 1)); + }; + + loop4(0); + + const loop0 = (index) => { + notification.info({ + title: { + literal: 'Title info' + }, + body: { + literal: 'Text body info' + } + }).then(() => loop0(index + 1)); + }; + + loop0(0); + + + const loop5 = (index) => { + notification.error({ + title: { + literal: 'Title error' + }, + body: { + literal: 'Text body error' + } + }).then(() => loop5(index + 1)); + }; + + loop5(0); + - // this.observeOnce('form', () => { - // this.form.invalid.$setTouched(true); - // }); } } @@ -29,7 +113,7 @@ return new StandCtrl(); }; - controller.$inject = ['Base', '$scope']; + controller.$inject = ['Base', '$scope', 'userNotification', 'notification']; angular.module('app.stand').controller('StandCtrl', controller); })(); diff --git a/src/modules/stand/less/stand.less b/src/modules/stand/less/stand.less index 43214ef44a..72e5d6a810 100644 --- a/src/modules/stand/less/stand.less +++ b/src/modules/stand/less/stand.less @@ -1,14 +1,27 @@ @import (reference) 'config'; -html body .stand .hidden { - display: block !important; -} +html body.stand { + .hidden { + display: block !important; + } -.stand { - h1 { + h1 { color: grey; } + w-seed-read[type="read"] { + position: relative; + &:before { + position: absolute; + z-index: 1; + width: 100%; + height: 135px; + content: ''; + opacity: 0; + display: block; + } + } + w-change-language w-select { position: relative; top: 0; @@ -55,17 +68,47 @@ html body .stand .hidden { border-right: 1px dashed @color-basic-200; } + .column2 { + background: @color-basic-50; + .relative-wrapper { + background: @color-white; + } + } + .unit-checkbox { width: 300px !important; } + .qr-wrapper, .relative-wrapper { + background: @color-white; position: relative; border: 1px dashed @color-basic-200; - height: 140px; + min-height: 100px; + padding: 20px 0; + border-radius: @border-radius; } ._internal-error { display: block !important; } + + w-tabs { + box-shadow: 0 0 3px #ccc; + max-height: 190px; + h4 { + + } + .tab-body-wrap { + } + + .tab-content { + display: flex; + align-items: center; + font-size: 100px; + padding: 20px; + min-height: 140px; + justify-content: center; + } + } } diff --git a/src/modules/stand/templates/stand.html b/src/modules/stand/templates/stand.html index 226c0cca3e..22a9e1664c 100644 --- a/src/modules/stand/templates/stand.html +++ b/src/modules/stand/templates/stand.html @@ -1,10 +1,3 @@ - -
@@ -29,17 +22,18 @@

Buttons

- - Small + + Tiny
- - Tiny + + Small
+ Medium @@ -80,7 +74,7 @@

Selects

Select title
- + Default Value 1 Value 2 @@ -167,6 +161,14 @@

Inputs

+ + {{$ctrl.dataCopy}} + + + +
+
@@ -208,6 +210,12 @@

Inputs

OFF
+
+ +

Range

+ + +
@@ -225,7 +233,7 @@

Errors

ng-model="$ctrl.inputModel" w-validator-custom="{{$ctrl.invalid}}" required> - This field is requied +
This field is requied
@@ -263,7 +271,6 @@

Errors

-

Empty block

@@ -280,6 +287,17 @@

Loader

+

Tooltip

+ +
+ Important information + + Hi, I'm Tooltip. I need a relative container + +
+ +
+

Helpers

@@ -302,6 +320,39 @@

Helpers

+
+ +

QR Code

+
+
Отсканируйте QR код
+ +
Нажмите чтобы увеличить/уменьшить
+ +
+ +
+ +

Expandable block

+ + + 🙈 + + +
+ +

Close modal button

+ +
+ +
+
@@ -397,6 +448,63 @@

Actions

+ +

Seed Backup

+ +
Seed previrew
+ + +
Seed confirmation
+ + + + +
+ +

Tabs

+ + + +
🙉
+
+ +
🙈
+
+ +
🙊
+
+
+ +
+ + +

Search

+ +
+ + + +
+ +
+ +

Notifications

+ +
+
+ +
+
+ +
+ +
+ +
+
diff --git a/src/modules/tokens/less/tokens.less b/src/modules/tokens/less/tokens.less index dcbc3be16c..b52e243e81 100644 --- a/src/modules/tokens/less/tokens.less +++ b/src/modules/tokens/less/tokens.less @@ -42,7 +42,6 @@ body.tokens { } textarea { - resize: vertical; min-height: 77px; max-height: 300px; } diff --git a/src/modules/tokens/templates/tokens.html b/src/modules/tokens/templates/tokens.html index 3b8a1aab3b..a13c74b5c1 100644 --- a/src/modules/tokens/templates/tokens.html +++ b/src/modules/tokens/templates/tokens.html @@ -187,7 +187,7 @@
+ w-i18n="fee">
diff --git a/src/modules/ui/directives/assetInfoHead/AssetInfoHead.js b/src/modules/ui/directives/assetInfoHead/AssetInfoHead.js new file mode 100644 index 0000000000..cd956f7af0 --- /dev/null +++ b/src/modules/ui/directives/assetInfoHead/AssetInfoHead.js @@ -0,0 +1,56 @@ +(function () { + 'use strict'; + + /** + * @param Base + * @param $scope + * @param user + * @param waves + * @param utils + * @return {AssetInfoHead} + */ + const controller = function (Base, $scope, user, waves, utils) { + + class AssetInfoHead extends Base { + + /** + * @type {string} + */ + assetName; + + $postLink() { + this._getAssetInfo(); + this.observe('assetId', this._getAssetInfo); + } + + /** + * @private + */ + _getAssetInfo() { + waves.node.assets.getAsset(this.assetId).then(asset => { + this.assetName = asset.name; + this.ticker = asset.ticker; + const { hasLabel } = utils.getDataFromOracles(asset.id); + this.hasLabel = hasLabel; + $scope.$apply(); + }); + + this.state = { assetId: this.assetId }; + } + + } + + return new AssetInfoHead(); + }; + + controller.$inject = ['Base', '$scope', 'user', 'waves', 'utils']; + + angular.module('app.ui') + .component('wAssetInfoHead', { + controller: controller, + templateUrl: 'modules/ui/directives/assetInfoHead/asset-info-head.html', + bindings: { + assetId: '<' + } + }); +})(); diff --git a/src/modules/ui/directives/assetInfoHead/asset-info-head.html b/src/modules/ui/directives/assetInfoHead/asset-info-head.html new file mode 100644 index 0000000000..7a62a4b3fb --- /dev/null +++ b/src/modules/ui/directives/assetInfoHead/asset-info-head.html @@ -0,0 +1,22 @@ +
+
+ + +
+

+ {{$ctrl.assetName}} + +

+ +
{{$ctrl.ticker}}
+
+ +
+ +
+
+ +
+
diff --git a/src/modules/ui/directives/assetLogo/AssetLogo.js b/src/modules/ui/directives/assetLogo/AssetLogo.js index 129a7def7a..7c3468f2cb 100644 --- a/src/modules/ui/directives/assetLogo/AssetLogo.js +++ b/src/modules/ui/directives/assetLogo/AssetLogo.js @@ -128,11 +128,12 @@ */ _addLogo() { if (this.assetId) { - const data = ds.dataManager.getOracleAssetData(this.assetId); - if (data && data.logo) { + const { logo } = utils.getDataFromOracles(this.assetId); + + if (logo) { $element.find('.asset__logo') .addClass('custom') - .css('backgroundImage', `url(${data.logo})`); + .css('backgroundImage', `url(${logo})`); return null; } waves.node.assets.getAsset(this.assetId) diff --git a/src/modules/ui/directives/assetLogo/assetLogo.less b/src/modules/ui/directives/assetLogo/assetLogo.less index 33786f5596..e6b7a68ebe 100644 --- a/src/modules/ui/directives/assetLogo/assetLogo.less +++ b/src/modules/ui/directives/assetLogo/assetLogo.less @@ -79,8 +79,7 @@ w-asset-logo { } } -.change-token, -.asset-modal { +.change-token { .sponsored-asset, .smart-asset { .marker { diff --git a/src/modules/ui/directives/assetStatus/AssetStatus.js b/src/modules/ui/directives/assetStatus/AssetStatus.js new file mode 100644 index 0000000000..55591b77cf --- /dev/null +++ b/src/modules/ui/directives/assetStatus/AssetStatus.js @@ -0,0 +1,54 @@ +(function () { + 'use strict'; + + /** + * @param Base + * @param $scope + * @param user + * @param waves + * @param utils + * @return {AssetInfoHead} + */ + const controller = function (Base, $scope, user, waves, utils) { + + class AssetInfoHead extends Base { + + $postLink() { + this._getAssetInfo(); + this.observe('assetId', this._getAssetInfo); + } + + /** + * @private + */ + _getAssetInfo() { + const { + isVerified, + isGateway, + isTokenomica, + isSuspicious, + hasLabel + } = utils.getDataFromOracles(this.assetId); + this.isGateway = isGateway; + this.isTokenomica = isGateway ? false : isTokenomica; + this.isVerified = isTokenomica ? false : isVerified; + this.isSuspicious = isVerified ? false : isSuspicious; + this.hasLabel = hasLabel; + } + + } + + return new AssetInfoHead(); + }; + + controller.$inject = ['Base', '$scope', 'user', 'waves', 'utils']; + + angular.module('app.ui') + .component('wAssetStatus', { + controller: controller, + templateUrl: 'modules/ui/directives/assetStatus/asset-status.html', + bindings: { + assetId: '<' + } + }); +})(); diff --git a/src/modules/ui/directives/assetStatus/asset-status.html b/src/modules/ui/directives/assetStatus/asset-status.html new file mode 100644 index 0000000000..9e0943a362 --- /dev/null +++ b/src/modules/ui/directives/assetStatus/asset-status.html @@ -0,0 +1,16 @@ + + + + diff --git a/src/modules/ui/directives/assetStatus/assetStatus.less b/src/modules/ui/directives/assetStatus/assetStatus.less new file mode 100644 index 0000000000..afc20720e9 --- /dev/null +++ b/src/modules/ui/directives/assetStatus/assetStatus.less @@ -0,0 +1,3 @@ +w-asset-status { + display: inline-flex; +} diff --git a/src/modules/ui/directives/button/button.less b/src/modules/ui/directives/button/button.less index 4b51b7a60c..75c21deae9 100644 --- a/src/modules/ui/directives/button/button.less +++ b/src/modules/ui/directives/button/button.less @@ -1,5 +1,6 @@ @import (reference) 'config'; @import (reference) 'icons'; +@import (reference) '../../../app/less/app'; @candy-animation: candyDotsAnimation 1.6s infinite ease-in-out; @candy-size: 10px; @@ -215,6 +216,20 @@ w-button { } } +.buttons-wrapper { + width: 100%; + display: flex; + justify-content: space-between; + align-items: center; + + w-button, + .fake-button { + display: block; + flex-basis: 48%; + max-width: 48%; + } +} + //Candy effect w-button { w-loader { @@ -302,3 +317,37 @@ w-button > button { } } } + + +.btn-wrap.btn-group { + box-sizing: border-box; + padding: 0; + display: flex; + flex-direction: row; + justify-content: center; + + & > *:first-child .btn, & > .btn:first-child { + border-left: 1px solid @color-disabled-100; + border-bottom-left-radius: 5px; + border-top-left-radius: 5px; + } + + & > *:last-child .btn, & > .btn:last-child { + border-bottom-right-radius: 5px; + border-top-right-radius: 5px; + } + + .btn { + display: block; + box-sizing: border-box; + cursor: pointer; + padding: 4px 10px; + border-bottom: 1px solid @color-disabled-100; + border-top: 1px solid @color-disabled-100; + border-right: 1px solid @color-disabled-100; + + &:active { + .btn-active(); + } + } +} \ No newline at end of file diff --git a/src/modules/ui/directives/chart/chart.less b/src/modules/ui/directives/chart/chart.less new file mode 100644 index 0000000000..6714679cec --- /dev/null +++ b/src/modules/ui/directives/chart/chart.less @@ -0,0 +1,27 @@ +@import (reference) 'config'; + +.chart-legend { + display: none; + margin-left: 40px; + + .legend-item { + display: block; + height: 38px; + } +} + +svg.chart { + .axis { + .tick line { + display: none; + } + .domain { + stroke: transparent; + } + + & > .tick > text { + fill: @color-disabled-700; + font-size: 13px; + } + } +} \ No newline at end of file diff --git a/src/modules/ui/directives/checkbox/checkbox.less b/src/modules/ui/directives/checkbox/checkbox.less index eb2b30b4c3..fd5d328819 100644 --- a/src/modules/ui/directives/checkbox/checkbox.less +++ b/src/modules/ui/directives/checkbox/checkbox.less @@ -64,3 +64,68 @@ w-checkbox-switcher { height: 30px; overflow: hidden; } + +.unit-checkbox { + display: flex; + min-height: auto; + margin-bottom: 20px; + + w-checkbox-submit { + flex-grow: 0; + align-self: flex-start; + display: block; + } + + label { + flex-grow: 1; + } +} + +.input-toggle { + display: flex; + align-items: center; + + w-checkbox-submit { + display: none; + } + + w-checkbox-submit + label { + width: 40px; + height: 20px; + border: 1px solid @color-basic-200; + background: @color-basic-200; + border-radius: 10px; + display: block; + position: relative; + transition: .3s; + + &:hover { + border: 1px solid @input-toggle-bg-hover; + background: @input-toggle-bg-hover; + } + + &::before { + transition: .3s; + background: @color-white; + width: 18px; + height: 18px; + content: ''; + position: absolute; + left: 0; + top: 0; + border-radius: 50%; + display: block; + } + } + + &.active { + w-checkbox-submit + label { + border: 1px solid @color-submit-400; + background: @color-submit-400; + + &::before { + transform: translateX(20px); + } + } + } +} diff --git a/src/modules/ui/directives/copyWrap/copyWrap.less b/src/modules/ui/directives/copyWrap/copyWrap.less index 48dcf34248..a604338e9a 100644 --- a/src/modules/ui/directives/copyWrap/copyWrap.less +++ b/src/modules/ui/directives/copyWrap/copyWrap.less @@ -22,6 +22,12 @@ w-copy-wrap { max-width: calc(100% ~'- 45px'); } + &.overflow { + .container { + overflow: auto; + } + } + .copy-icon { border-left: 1px solid @color-basic-200; flex-basis: 40px; diff --git a/src/modules/ui/directives/emptyBlock/emptyBlock.less b/src/modules/ui/directives/emptyBlock/emptyBlock.less index e69de29bb2..1dd93e9f4b 100644 --- a/src/modules/ui/directives/emptyBlock/emptyBlock.less +++ b/src/modules/ui/directives/emptyBlock/emptyBlock.less @@ -0,0 +1,19 @@ +@import (reference) 'icons'; + +w-empty-block { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + + .icon { + background-image: @empty-icon; + background-repeat: no-repeat; + background-position: center center; + width: 100px; + height: 100px; + margin: 0 auto 10px auto; + } +} \ No newline at end of file diff --git a/src/modules/ui/directives/errorBlock/errorBlock.less b/src/modules/ui/directives/errorBlock/errorBlock.less index e69de29bb2..3ce702d3b6 100644 --- a/src/modules/ui/directives/errorBlock/errorBlock.less +++ b/src/modules/ui/directives/errorBlock/errorBlock.less @@ -0,0 +1,25 @@ +@import (reference) 'icons'; + +w-error-block { + width: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + text-align: center; + + .icon { + background-image: @empty-icon; + background-repeat: no-repeat; + background-position: center center; + width: 100px; + height: 100px; + margin: 0 auto 10px auto; + } +} + +w-error-block { + .icon { + background-image: @error-icon; + } +} \ No newline at end of file diff --git a/src/modules/ui/directives/expandableBlock/ExpandableBlock.js b/src/modules/ui/directives/expandableBlock/ExpandableBlock.js new file mode 100644 index 0000000000..8036787aec --- /dev/null +++ b/src/modules/ui/directives/expandableBlock/ExpandableBlock.js @@ -0,0 +1,11 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wExpandableBlock', { + bindings: { + title: '<' + }, + templateUrl: 'modules/ui/directives/expandableBlock/expandableBlock.html', + transclude: true + }); +})(); diff --git a/src/modules/ui/directives/expandableBlock/expandableBlock.html b/src/modules/ui/directives/expandableBlock/expandableBlock.html new file mode 100644 index 0000000000..f18ec9ba5d --- /dev/null +++ b/src/modules/ui/directives/expandableBlock/expandableBlock.html @@ -0,0 +1,7 @@ +
+ +
+ +
+
diff --git a/src/modules/ui/directives/expandableBlock/expandableBlock.less b/src/modules/ui/directives/expandableBlock/expandableBlock.less new file mode 100644 index 0000000000..0d5871617e --- /dev/null +++ b/src/modules/ui/directives/expandableBlock/expandableBlock.less @@ -0,0 +1,63 @@ +@import (reference) "../../../app/less/app-icons"; +@import (reference) '../../../app/less/typography'; +@import (reference) 'config'; + +w-expandable-block { + .expandable-block { + position: relative; + overflow: hidden; + border-radius: @border-radius; + background-color: @color-white; + box-shadow: @shadow-type-1; + + &__title { + display: flex; + width: 100%; + height: 39px; + align-items: center; + color: @color-basic-700; + padding: 0 20px; + font-family: @font-roboto-medium; + } + + &__trigger { + .icon-dex-arrow(); + background-color: @color-basic-50; + top: 10px; + width: 20px; + height: 20px; + cursor: pointer; + transition: transform 0.3s ease-in-out, all 0.3s; + border-radius: 2px; + position: absolute; + z-index: 3; + right: 12px; + + &:hover { + background-color: @color-basic-100; + } + } + + &__container { + height: 0; + transition: .4s; + overflow: hidden; + padding: 0 20px; + border-color: transparent; + } + + &.active { + .expandable-block { + &__container { + height: auto; + border-top: 1px solid @color-basic-100; + padding: 20px; + } + + &__trigger { + transform: rotate(-180deg) + } + } + } + } +} diff --git a/src/modules/ui/directives/header/header.html b/src/modules/ui/directives/header/header.html index 6c4d6a5d42..b4def28ce1 100644 --- a/src/modules/ui/directives/header/header.html +++ b/src/modules/ui/directives/header/header.html @@ -6,7 +6,7 @@ - - + + diff --git a/src/modules/ui/directives/header/header.less b/src/modules/ui/directives/header/header.less index 855bc7764a..247a3113c9 100644 --- a/src/modules/ui/directives/header/header.less +++ b/src/modules/ui/directives/header/header.less @@ -14,33 +14,35 @@ w-header { display: block; height: 100%; } +} + +@media screen and (max-width:768px) { + w-header { + display: none; + } +} - w-search { +.header-search { + &-wrapper { line-height: 70px; border-left: 1px solid @color-disabled-100; margin-left: 40px; padding-left: 46px; display: none; - & input { - border: 1px transparent solid; - font-family: @font-roboto-regular; - font-size: 15px; - letter-spacing: -0.3px; - text-align: left; - width: 200px; - color: @color-disabled-600; - transition: 0.3s all; - cursor: pointer; - } - & input:focus { - border-bottom: 1px @color-disabled-600 solid; - cursor: text; - } } -} - -@media screen and (max-width:768px) { - w-header { - display: none; - } + &-input { + border: 1px transparent solid; + font-family: @font-roboto-regular; + font-size: 15px; + letter-spacing: -0.3px; + text-align: left; + width: 200px; + color: @color-disabled-600; + transition: 0.3s all; + cursor: pointer; + } + &-input:focus { + border-bottom: 1px @color-disabled-600 solid; + cursor: text; + } } diff --git a/src/modules/ui/directives/helpIcon/helpIcon.less b/src/modules/ui/directives/helpIcon/helpIcon.less index 20c6ee73bc..1b7e03216f 100644 --- a/src/modules/ui/directives/helpIcon/helpIcon.less +++ b/src/modules/ui/directives/helpIcon/helpIcon.less @@ -40,7 +40,7 @@ top: 21px; position: absolute; content: ''; - z-index: 0; + z-index: 1; } &.hovered::before, diff --git a/src/modules/ui/directives/infoTooltip/InfoTooltip.js b/src/modules/ui/directives/infoTooltip/InfoTooltip.js new file mode 100644 index 0000000000..42fb1489b6 --- /dev/null +++ b/src/modules/ui/directives/infoTooltip/InfoTooltip.js @@ -0,0 +1,48 @@ +(function () { + 'use strict'; + + const controller = function (Base, $scope, $element) { + + class InfoTooltipController extends Base { + + constructor() { + super(); + this.hovered = false; + } + + hoverIn() { + this.hovered = true; + clearTimeout(this.timer); + $scope.$apply(); + } + + hoverOut() { + clearTimeout(this.timer); + this.timer = setTimeout(() => { + this.hovered = false; + $scope.$apply(); + }, Number(this.delay) || 1000); + } + + $postLink() { + $element.find('i').on('mouseover', () => this.hoverIn()); + $element.find('i').on('mouseout', () => this.hoverOut()); + } + + } + + return new InfoTooltipController(); + }; + + controller.$inject = ['Base', '$scope', '$element']; + + angular.module('app.ui').component('wInfoTooltip', { + templateUrl: 'modules/ui/directives/infoTooltip/infoTooltip.html', + transclude: true, + bindings: { + delay: '=' + }, + controller + }); + +})(); diff --git a/src/modules/ui/directives/infoTooltip/infoTooltip.html b/src/modules/ui/directives/infoTooltip/infoTooltip.html new file mode 100644 index 0000000000..65dbf78b40 --- /dev/null +++ b/src/modules/ui/directives/infoTooltip/infoTooltip.html @@ -0,0 +1,2 @@ + +
diff --git a/src/modules/ui/directives/infoTooltip/infoTooltip.less b/src/modules/ui/directives/infoTooltip/infoTooltip.less new file mode 100644 index 0000000000..f77830a53d --- /dev/null +++ b/src/modules/ui/directives/infoTooltip/infoTooltip.less @@ -0,0 +1,62 @@ +@import (reference) 'config'; +@import (reference) 'icons'; +@import (reference) '../../../app/less/typography'; + +w-info-tooltip { + .information-icon { + width: 16px; + height: 16px; + display: block; + background: @information-icon center no-repeat; + cursor: pointer; + + &.hovered, + &:hover { + & + .tooltip { + display: flex; + align-items: center; + } + } + } + + .tooltip { + min-height: 30px; + display: none; + position: absolute; + bottom: 100%; + padding: 5px 0 5px 10px; + transform: translate(calc(-50%~'+ 8px'), -8px); + z-index: 2; + cursor: pointer; + border-radius: @border-radius; + background: @color-basic-700; + + &__content { + color: @color-white; + font-size: @font-size-caption-2; + max-width: 240px; + max-height: 150px; + width: max-content; + overflow: auto; + display: block; + padding-right: 10px; + } + + &::before { + position: absolute; + bottom: -3px; + left: calc(50% ~'- 5px'); + width: 10px; + height: 10px; + content: ''; + transform-origin: center; + transform: rotate(45deg); + background: @color-basic-700; + z-index: -1; + } + + &:hover { + display: flex; + } + } +} diff --git a/src/modules/ui/directives/input/input.less b/src/modules/ui/directives/input/input.less index 6eab58ca45..c145696c7f 100644 --- a/src/modules/ui/directives/input/input.less +++ b/src/modules/ui/directives/input/input.less @@ -165,7 +165,7 @@ w-input { } &.ng-touched { - &.ng-valid:not(:focus):not(.focus) { + &.ng-valid:not(:focus):not(.focus):not(.ng-empty) { border-color: @color-success-300; } &.ng-invalid:not(:focus):not(.focus) { @@ -186,6 +186,7 @@ w-input { } &[textarea="true"] { + resize: vertical; &.large textarea { min-height: 300px; @@ -250,7 +251,7 @@ w-input { form.ng-submitted { input[type="text"], input[type="password"], input[type="number"], textarea { - &.ng-invalid:not(.embed):not(:focus):not(.focus):not(.no-validate) { + &.ng-touched.ng-invalid:not(.embed):not(:focus):not(.focus):not(.no-validate) { border-color: @color-error-200; } } diff --git a/src/modules/ui/directives/inputContainer/inputContainer.less b/src/modules/ui/directives/inputContainer/inputContainer.less index 5eda8aa7b5..acbed109e0 100644 --- a/src/modules/ui/directives/inputContainer/inputContainer.less +++ b/src/modules/ui/directives/inputContainer/inputContainer.less @@ -61,3 +61,7 @@ w-input-container { } } } + +md-input-container { + transform: translate3d(0, 0, 0); +} diff --git a/src/modules/ui/directives/leftMenu/leftMenu.less b/src/modules/ui/directives/leftMenu/leftMenu.less index 65d399094d..53a9cf3df6 100644 --- a/src/modules/ui/directives/leftMenu/leftMenu.less +++ b/src/modules/ui/directives/leftMenu/leftMenu.less @@ -441,6 +441,10 @@ w-left-menu { } @media screen and (max-width: 1024px) { + w-left-menu w-responsive-menu { + min-height: 270px; + } + body.dex, body.dex-demo { w-left-menu { diff --git a/src/modules/ui/directives/permit/permit.less b/src/modules/ui/directives/permit/permit.less new file mode 100644 index 0000000000..574a8dcca3 --- /dev/null +++ b/src/modules/ui/directives/permit/permit.less @@ -0,0 +1,3 @@ +w-permit { + display: block; +} \ No newline at end of file diff --git a/src/modules/ui/directives/qrCode/qrCode.less b/src/modules/ui/directives/qrCode/qrCode.less index 2065602504..efab696f78 100644 --- a/src/modules/ui/directives/qrCode/qrCode.less +++ b/src/modules/ui/directives/qrCode/qrCode.less @@ -3,6 +3,12 @@ .qr-wrapper { transition: all .3s; height: auto; + position: relative; + min-height: 240px; + + .center { + height: auto; + } w-qr-code { display: block; @@ -37,3 +43,20 @@ } } } + +@media screen and (max-width: 600px) { + .qr-wrapper { + &.zoomed-in { + w-qr-code { + width: 340px; + height: 340px; + + .qr-code-wrap, + img { + width: 340px; + height: 340px; + } + } + } + } +} \ No newline at end of file diff --git a/src/modules/ui/directives/qrCodeRead/qrCodeReader.less b/src/modules/ui/directives/qrCodeRead/qrCodeReader.less index 407d30930e..ccb6a6037d 100644 --- a/src/modules/ui/directives/qrCodeRead/qrCodeReader.less +++ b/src/modules/ui/directives/qrCodeRead/qrCodeReader.less @@ -18,15 +18,6 @@ w-qr-code-read { } } -.qr-wrapper { - position: relative; - min-height: 240px; - - .center { - height: auto; - } -} - .camera-popup { display: none; position: relative; diff --git a/src/modules/ui/directives/radio/radio.less b/src/modules/ui/directives/radio/radio.less index b3bd85fcdf..de76b1f8c7 100644 --- a/src/modules/ui/directives/radio/radio.less +++ b/src/modules/ui/directives/radio/radio.less @@ -8,7 +8,7 @@ w-radio { } input:checked ~ label.btn.btn-radio { - .btn-wrap.btn-group .btn-active(); + .btn-active(); } } diff --git a/src/modules/ui/directives/scriptTxForm/script-form.html b/src/modules/ui/directives/scriptTxForm/script-form.html index f7d0c4e0cd..904b5e0c2c 100644 --- a/src/modules/ui/directives/scriptTxForm/script-form.html +++ b/src/modules/ui/directives/scriptTxForm/script-form.html @@ -1,6 +1,6 @@
-
+
- + + +
diff --git a/src/modules/ui/directives/setAssetScriptForm/SetAssetScriptFrom.js b/src/modules/ui/directives/setAssetScriptForm/SetAssetScriptFrom.js index a4a0b3309f..ab56f41723 100644 --- a/src/modules/ui/directives/setAssetScriptForm/SetAssetScriptFrom.js +++ b/src/modules/ui/directives/setAssetScriptForm/SetAssetScriptFrom.js @@ -3,9 +3,6 @@ const { SIGN_TYPE } = require('@waves/signature-adapter'); const { signature } = require('data-service'); - const { STATUS_LIST } = require('@waves/oracle-data'); - const { path } = require('ramda'); - const ds = require('data-service'); const $ = require('jquery'); /** @@ -52,22 +49,6 @@ * @type {Money} */ fee; - /** - * @type {boolean} - */ - isVerified; - /** - * @type {boolean} - */ - isGateway; - /** - * @type {boolean} - */ - isSuspicious; - /** - * @type {boolean} - */ - hasLabel; /** * @type {function(data: {signable: Signable}): void} */ @@ -151,11 +132,6 @@ if (!asset.hasScript) { throw new Error('This asset has no script!'); } - const data = ds.dataManager.getOracleAssetData(asset.id); - this.isVerified = path(['status'], data) === STATUS_LIST.VERIFIED; - this.isGateway = path(['status'], data) === 3; - this.isSuspicious = user.scam[asset.id]; - this.hasLabel = this.isVerified || this.isGateway || this.isSuspicious; this.asset = asset; $scope.$apply(); }); diff --git a/src/modules/ui/directives/setAssetScriptForm/setAssetScriptFrom.html b/src/modules/ui/directives/setAssetScriptForm/setAssetScriptFrom.html index 94a49bfecc..fe9d3769d6 100644 --- a/src/modules/ui/directives/setAssetScriptForm/setAssetScriptFrom.html +++ b/src/modules/ui/directives/setAssetScriptForm/setAssetScriptFrom.html @@ -1,34 +1,6 @@ -
-
- - -
-

- {{::$ctrl.asset.name}} - - - -

- -
{{::$ctrl.ticker}}
-
- -
- -
-
-
-
+
diff --git a/src/modules/ui/directives/sign/sign.html b/src/modules/ui/directives/sign/sign.html index 44fc757172..43a992523e 100644 --- a/src/modules/ui/directives/sign/sign.html +++ b/src/modules/ui/directives/sign/sign.html @@ -25,7 +25,9 @@
-
-
+
+
+
+
diff --git a/src/modules/ui/directives/sign/sign.less b/src/modules/ui/directives/sign/sign.less index 8e41012f9c..c617877a3d 100644 --- a/src/modules/ui/directives/sign/sign.less +++ b/src/modules/ui/directives/sign/sign.less @@ -19,8 +19,6 @@ w-sign { } .sign-loader { - height: 60px; - w-loader { position: relative; margin: 0 auto; diff --git a/src/modules/ui/directives/signButton/sign-button.less b/src/modules/ui/directives/signButton/sign-button.less new file mode 100644 index 0000000000..7d86d5c45f --- /dev/null +++ b/src/modules/ui/directives/signButton/sign-button.less @@ -0,0 +1,4 @@ +w-sign-button, +.block { + display: block; +} \ No newline at end of file diff --git a/src/modules/ui/directives/smartTable/smart-table.less b/src/modules/ui/directives/smartTable/smart-table.less index 4d09b6a9ff..9b636907c0 100644 --- a/src/modules/ui/directives/smartTable/smart-table.less +++ b/src/modules/ui/directives/smartTable/smart-table.less @@ -5,6 +5,67 @@ @cell-height: 64px; @responsive-cell-height: auto; +.search { + &-wrapper { + height: 100%; + width: 100%; + display: inline-block; + } + + &-input { + background: @input-search-icon 8px center no-repeat @color-white; + height: 100%; + width: 100%; + padding-left: 31px; + cursor: pointer; + color: @color-disabled-900; + transition: .3s; + border: 1px solid transparent; + font-size: @font-size-caption-2; + + &:focus { + border-color: @color-submit-300; + cursor: default; + } + } +} + +.portfolio { + .smart-table { + .search-input { + width: 36px; + border-radius: @border-radius; + margin-right: 10px; + text-indent: -999px; + border-color: @color-basic-200; + z-index: 1; + background-position: 10px center; + padding-left: 35px; + .footnote-1(); + + &:focus { + width: 200px; + text-indent: 0; + border-color: @color-submit-300; + } + + &.not-empty { + border-color: @color-submit-300; + } + } + } +} + +.dex { + .smart-table { + .search-input { + &:focus { + border-color: transparent; + } + } + } +} + .smart-table { display: block; height: 100%; @@ -139,32 +200,7 @@ left: 20px; top: 13px; z-index: 1; - - input { - height: 36px; - width: 36px; - border-radius: @border-radius; - color: @color-disabled-900; - background: @input-search-icon 10px center no-repeat @color-white; - border: 1px solid @color-basic-200; - cursor: pointer; - margin-right: 10px; - transition: .3s; - font-size: 0; - z-index: 1; - - &:focus { - width: 200px; - padding-left: 35px; - cursor: default; - border-color: @color-submit-300; - .footnote-1(); - } - - &.not-empty { - border-color: @color-submit-300; - } - } + height: 36px; } } diff --git a/src/modules/ui/directives/smartTable/templates/headerCell.html b/src/modules/ui/directives/smartTable/templates/headerCell.html index 850085ec9e..26bed13628 100644 --- a/src/modules/ui/directives/smartTable/templates/headerCell.html +++ b/src/modules/ui/directives/smartTable/templates/headerCell.html @@ -1,11 +1,15 @@
- + + + diff --git a/src/modules/ui/directives/transaction/Transaction.js b/src/modules/ui/directives/transaction/Transaction.js index 89b6175d99..30e942f56e 100644 --- a/src/modules/ui/directives/transaction/Transaction.js +++ b/src/modules/ui/directives/transaction/Transaction.js @@ -1,10 +1,6 @@ (function () { 'use strict'; - const PATH = 'modules/ui/directives/transaction/types'; - const tsUtils = require('ts-utils'); - const { Money } = require('@waves/data-entities'); - /** * @param Base * @param $filter @@ -12,23 +8,15 @@ * @param {INotification} notification * @param {Waves} waves * @param {User} user - * @param {BaseAssetService} baseAssetService - * @param {app.utils} utils - * @param {$rootScope.Scope} $scope * @return {Transaction} */ const controller = function (Base, $filter, modalManager, notification, - waves, user, baseAssetService, utils, $scope) { + waves, user) { const { SIGN_TYPE } = require('@waves/signature-adapter'); - class Transaction extends Base { $postLink() { - - this.templateUrl = `${PATH}/${this.transaction.templateType}.html`; - this.time = $filter('date')(this.transaction.timestamp, this.datePattern || 'HH:mm'); - this.shownAddress = this.transaction.shownAddress; this.typeName = this.transaction.typeName; this.isScam = !!user.scam[this.transaction.assetId]; if (this.transaction.type === 7) { @@ -36,88 +24,6 @@ this.isScamPrice = !!user.scam[this.transaction.price.asset]; } - if (this.transaction.amount && this.transaction.amount instanceof ds.wavesDataEntities.Money) { - baseAssetService.convertToBaseAsset(this.transaction.amount) - .then((baseMoney) => { - this.mirrorBalance = baseMoney; - $scope.$digest(); - }); - } - - if (this.transaction.assetId) { - waves.node.assets.getAsset(this.transaction.assetId).then(asset => { - this.asset = asset; - $scope.$apply(); - }); - } - - const TYPES = waves.node.transactions.TYPES; - - switch (this.typeName) { - case TYPES.BURN: - case TYPES.ISSUE: - case TYPES.REISSUE: - this.tokens(); - break; - case TYPES.EXCHANGE_BUY: - case TYPES.EXCHANGE_SELL: - this.exchange(); - break; - case TYPES.SPONSORSHIP_START: - case TYPES.SPONSORSHIP_STOP: - this.sponsored(); - break; - case TYPES.SPONSORSHIP_FEE: - this.sponsoredFee(); - break; - default: - } - } - - sponsoredFee() { - this.isScam = false; - } - - sponsored() { - this.sponsorshipFee = this.transaction.minSponsoredAssetFee; - this.titleAssetName = this.getAssetName( - tsUtils.get(this.transaction, 'minSponsoredAssetFee.asset') - ); - } - - exchange() { - this.totalPrice = utils.getExchangeTotalPrice(this.transaction.amount, this.transaction.price); - } - - tokens() { - this.titleAssetName = this.getAssetName( - tsUtils.get(this.transaction, 'amount.asset') || - tsUtils.get(this.transaction, 'quantity.asset') || - this.transaction - ); - this.name = tsUtils.get( - this.transaction, 'amount.asset.name') || - tsUtils.get(this.transaction, 'quantity.asset.name' - ); - - const amount = tsUtils.get(this.transaction, 'amount') || tsUtils.get(this.transaction, 'quantity'); - if (amount instanceof Money) { - this.amount = amount.toFormat(); - } else { - this.amount = amount.div(Math.pow(10, this.transaction.precision)); - } - } - - /** - * @param {{id: string, name: string}} asset - * @return {string} - */ - getAssetName(asset) { - try { - return !user.scam[asset.id] ? asset.name : ''; - } catch (e) { - return ''; - } } cancelLeasing() { @@ -148,7 +54,6 @@ */ getCopyAllData() { const tx = this.transaction; - const id = `Transaction ID: ${tx.id}`; const type = `Type: ${tx.type} (${this.typeName})`; @@ -210,10 +115,7 @@ 'modalManager', 'notification', 'waves', - 'user', - 'baseAssetService', - 'utils', - '$scope' + 'user' ]; angular.module('app.ui') diff --git a/src/modules/ui/directives/transaction/TransactionIcon.js b/src/modules/ui/directives/transaction/TransactionIcon.js new file mode 100644 index 0000000000..055bef3690 --- /dev/null +++ b/src/modules/ui/directives/transaction/TransactionIcon.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wTransactionIcon', { + bindings: { + typeName: '<' + }, + templateUrl: 'modules/ui/directives/transaction/transaction-icon.html' + }); +})(); diff --git a/src/modules/ui/directives/transaction/TransactionInfoRow.js b/src/modules/ui/directives/transaction/TransactionInfoRow.js new file mode 100644 index 0000000000..342f4df15c --- /dev/null +++ b/src/modules/ui/directives/transaction/TransactionInfoRow.js @@ -0,0 +1,38 @@ +(function () { + 'use strict'; + + /** + * @param $filter + * @return {TransactionInfoRow} + */ + + const controller = function ($filter) { + + class TransactionInfoRow { + + $postLink() { + this.type = this.transaction.type; + this.props = { + ...this.transaction, + time: $filter('date')(this.transaction.timestamp, this.datePattern || 'HH:mm') + }; + } + + } + + return new TransactionInfoRow(); + }; + + controller.$inject = [ + '$filter' + ]; + + angular.module('app.ui').component('wTransactionInfoRow', { + bindings: { + transaction: '<', + datePattern: '<' + }, + templateUrl: 'modules/ui/directives/transaction/transaction-info-row.html', + controller + }); +})(); diff --git a/src/modules/ui/directives/transaction/transaction-icon.html b/src/modules/ui/directives/transaction/transaction-icon.html new file mode 100644 index 0000000000..3497176e38 --- /dev/null +++ b/src/modules/ui/directives/transaction/transaction-icon.html @@ -0,0 +1 @@ +
diff --git a/src/modules/ui/directives/transaction/transaction-info-row.html b/src/modules/ui/directives/transaction/transaction-info-row.html new file mode 100644 index 0000000000..cdb76c5cf3 --- /dev/null +++ b/src/modules/ui/directives/transaction/transaction-info-row.html @@ -0,0 +1,17 @@ +
+ + + + + + + + + + + + + + + +
diff --git a/src/modules/ui/directives/transaction/transaction.html b/src/modules/ui/directives/transaction/transaction.html index 7000ae2a27..2c13d9aac0 100644 --- a/src/modules/ui/directives/transaction/transaction.html +++ b/src/modules/ui/directives/transaction/transaction.html @@ -1,34 +1,34 @@
-
-
- -
- - - - + + + + + + + + +
+ + + -
- - - - - -
-
- - - - - -
- - - +
+
+ + + - +
+ + + + + +
diff --git a/src/modules/ui/directives/transaction/transactions.less b/src/modules/ui/directives/transaction/transactions.less index 6c798e90df..bcbfaf085a 100644 --- a/src/modules/ui/directives/transaction/transactions.less +++ b/src/modules/ui/directives/transaction/transactions.less @@ -3,6 +3,54 @@ @import (reference) 'config'; @import (reference) 'icons'; +.status-label, +.status-label-min { + width: auto; + padding: 4px 11px; + border-radius: @border-radius; + text-transform: uppercase; + color: @color-submit-400; + background-color: @color-bluebar-200; + margin: -1px 0 0 6px; + white-space: nowrap; + + &.success, + &.confirmed { + background: @color-success-50; + color: @color-success-400; + } + + &.warning, + &.unconfirmed { + background: rgba(255, 175, 0, 0.1); + color: @color-warning-500; + } + + &.error, + &.cancelled { + background: rgba(239, 72, 41, 0.1); + color: @color-error-500; + } + + &.active { + color: @color-submit-400; + background-color: @color-bluebar-200; + } + + &.inactive { + background-color: @asset-label-suspicious; + color: @color-black; + } +} + +.status-label-min { + .caption-3(); + padding: 3px 6px; + margin-top: 4px; + border-radius: @border-radius / 2; + text-transform: uppercase; +} + w-transaction .transaction { display: flex; flex-direction: row; @@ -129,6 +177,10 @@ w-transaction .transaction { &.set-asset-script { .icon-tx-set-asset-script(); } + + &.script-invocation { + .icon-tx-script-invocation(); + } } &.spam .icon { diff --git a/src/modules/ui/directives/transaction/types/burn/Burn.js b/src/modules/ui/directives/transaction/types/burn/Burn.js new file mode 100644 index 0000000000..317eb8821a --- /dev/null +++ b/src/modules/ui/directives/transaction/types/burn/Burn.js @@ -0,0 +1,64 @@ +(function () { + 'use strict'; + + const tsUtils = require('ts-utils'); + const { Money } = require('@waves/data-entities'); + + /** + * @param {User} user + * @return {Burn} + */ + + const controller = function (user) { + + class Burn { + + /** + * {object} + */ + props = null; + + $postLink() { + this.assetName = this.getAssetName( + tsUtils.get(this.props, 'amount.asset') || + tsUtils.get(this.props, 'quantity.asset') || + this.props + ); + this.name = tsUtils.get(this.props, 'amount.asset.name') || + tsUtils.get(this.props, 'quantity.asset.name'); + + const amount = tsUtils.get(this.props, 'amount') || tsUtils.get(this.props, 'quantity'); + this.amount = amount instanceof Money ? + amount.toFormat() : + amount.div(Math.pow(10, this.props.precision)); + } + + /** + * @param {{id: string, name: string}} asset + * @return {string} + */ + getAssetName(asset) { + try { + return !user.scam[asset.id] ? asset.name : ''; + } catch (e) { + return ''; + } + } + + } + + return new Burn(); + }; + + controller.$inject = [ + 'user' + ]; + + angular.module('app.ui').component('wBurn', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/burn/burn.html', + controller + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/burn/burn.html b/src/modules/ui/directives/transaction/types/burn/burn.html new file mode 100644 index 0000000000..c6b9791f75 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/burn/burn.html @@ -0,0 +1,20 @@ +
+
+
+ + +
+
+ +
+
+
+
+ + {{$ctrl.name}} +
+
+
diff --git a/src/modules/ui/directives/transaction/types/cancel-leasing.html b/src/modules/ui/directives/transaction/types/cancel-leasing.html deleted file mode 100644 index a60d919209..0000000000 --- a/src/modules/ui/directives/transaction/types/cancel-leasing.html +++ /dev/null @@ -1,22 +0,0 @@ -
-
-
-
- - -
-
- -
-
-
-
- -
-
-
diff --git a/src/modules/ui/directives/transaction/types/cancel-leasing/CancelLeasing.js b/src/modules/ui/directives/transaction/types/cancel-leasing/CancelLeasing.js new file mode 100644 index 0000000000..f5bff46b63 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/cancel-leasing/CancelLeasing.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wCancelLeasing', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/cancel-leasing/cancel-leasing.html' + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/cancel-leasing/cancel-leasing.html b/src/modules/ui/directives/transaction/types/cancel-leasing/cancel-leasing.html new file mode 100644 index 0000000000..f2b5358bbf --- /dev/null +++ b/src/modules/ui/directives/transaction/types/cancel-leasing/cancel-leasing.html @@ -0,0 +1,20 @@ +
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
diff --git a/src/modules/ui/directives/transaction/types/create-alias/CreateAlias.js b/src/modules/ui/directives/transaction/types/create-alias/CreateAlias.js new file mode 100644 index 0000000000..b6e8618f35 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/create-alias/CreateAlias.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wCreateAlias', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/create-alias/create-alias.html' + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/create-alias/create-alias.html b/src/modules/ui/directives/transaction/types/create-alias/create-alias.html new file mode 100644 index 0000000000..eb9dd8a344 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/create-alias/create-alias.html @@ -0,0 +1,12 @@ +
+
+
+ +
+
+ +
+
+
+
diff --git a/src/modules/ui/directives/transaction/types/data/Data.js b/src/modules/ui/directives/transaction/types/data/Data.js new file mode 100644 index 0000000000..df1cd690ca --- /dev/null +++ b/src/modules/ui/directives/transaction/types/data/Data.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wData', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/data/data.html' + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/data.html b/src/modules/ui/directives/transaction/types/data/data.html similarity index 86% rename from src/modules/ui/directives/transaction/types/data.html rename to src/modules/ui/directives/transaction/types/data/data.html index 08aed88a4a..5dc4e521ee 100644 --- a/src/modules/ui/directives/transaction/types/data.html +++ b/src/modules/ui/directives/transaction/types/data/data.html @@ -6,8 +6,8 @@
+ params="{time: $ctrl.props.time}">
- + \ No newline at end of file diff --git a/src/modules/ui/directives/transaction/types/exchange/Exchange.js b/src/modules/ui/directives/transaction/types/exchange/Exchange.js new file mode 100644 index 0000000000..3e29a9290d --- /dev/null +++ b/src/modules/ui/directives/transaction/types/exchange/Exchange.js @@ -0,0 +1,67 @@ +(function () { + 'use strict'; + + /** + * @param {User} user + * @param {app.utils} utils + * @return {Exchange} + */ + + const controller = function (user, utils) { + + class Exchange { + + /** + * {object} + */ + props = null; + + $postLink() { + this.typeName = this.props.typeName; + this.amountAssetName = this.getAssetName(this.props.amount.asset); + this.priceAssetName = this.getAssetName(this.props.price.asset); + this.isScamAmount = !!user.scam[this.props.amount.asset]; + this.isScamPrice = !!user.scam[this.props.price.asset]; + this.amountParams = { + sign: this.typeName === 'exchange-buy' ? '+' : '–', + amount: this.props.amount.toFormat(), + name: this.props.amount.asset.name + }; + this.priceParams = { + sign: this.typeName === 'exchange-buy' ? '-' : '+', + amount: utils.getExchangeTotalPrice(this.props.amount, this.props.price), + name: this.props.price.asset.name + }; + + } + + /** + * @param {{id: string, name: string}} asset + * @return {string} + */ + getAssetName(asset) { + try { + return !user.scam[asset.id] ? asset.name : ''; + } catch (e) { + return ''; + } + } + + } + + return new Exchange(); + }; + + controller.$inject = [ + 'user', + 'utils' + ]; + + angular.module('app.ui').component('wExchangeData', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/exchange/exchange.html', + controller + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/exchange.html b/src/modules/ui/directives/transaction/types/exchange/exchange.html similarity index 53% rename from src/modules/ui/directives/transaction/types/exchange.html rename to src/modules/ui/directives/transaction/types/exchange/exchange.html index 7ae73977d5..3b0e09e39d 100644 --- a/src/modules/ui/directives/transaction/types/exchange.html +++ b/src/modules/ui/directives/transaction/types/exchange/exchange.html @@ -3,17 +3,13 @@
- - {{$ctrl.getAssetName($ctrl.transaction.amount.asset)}} - + {{$ctrl.amountAssetName}} / - - {{$ctrl.getAssetName($ctrl.transaction.price.asset)}} - + {{$ctrl.priceAssetName}} @@ -22,25 +18,17 @@
+ params="{time: $ctrl.props.time}">
+ params="$ctrl.amountParams">
- +
diff --git a/src/modules/ui/directives/transaction/types/issue/Issue.js b/src/modules/ui/directives/transaction/types/issue/Issue.js new file mode 100644 index 0000000000..c2571b2405 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/issue/Issue.js @@ -0,0 +1,64 @@ +(function () { + 'use strict'; + + const tsUtils = require('ts-utils'); + const { Money } = require('@waves/data-entities'); + + /** + * @param {User} user + * @return {Issue} + */ + + const controller = function (user) { + + class Issue { + + /** + * {object} + */ + props = null; + + $postLink() { + this.assetName = this.getAssetName( + tsUtils.get(this.props, 'amount.asset') || + tsUtils.get(this.props, 'quantity.asset') || + this.props + ); + this.name = tsUtils.get(this.props, 'amount.asset.name') || + tsUtils.get(this.props, 'quantity.asset.name'); + + const amount = tsUtils.get(this.props, 'amount') || tsUtils.get(this.props, 'quantity'); + this.amount = amount instanceof Money ? + amount.toFormat() : + amount.div(Math.pow(10, this.props.precision)); + } + + /** + * @param {{id: string, name: string}} asset + * @return {string} + */ + getAssetName(asset) { + try { + return !user.scam[asset.id] ? asset.name : ''; + } catch (e) { + return ''; + } + } + + } + + return new Issue(); + }; + + controller.$inject = [ + 'user' + ]; + + angular.module('app.ui').component('wIssue', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/issue/issue.html', + controller + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/issue/issue.html b/src/modules/ui/directives/transaction/types/issue/issue.html new file mode 100644 index 0000000000..856fd0e932 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/issue/issue.html @@ -0,0 +1,23 @@ +
+
+
+ + +
+
+ +
+
+
+
+ + {{$ctrl.name}} +
+
+ +
+
+
diff --git a/src/modules/ui/directives/transaction/types/lease.html b/src/modules/ui/directives/transaction/types/lease.html deleted file mode 100644 index 6ce3eac90a..0000000000 --- a/src/modules/ui/directives/transaction/types/lease.html +++ /dev/null @@ -1,20 +0,0 @@ -
-
-
-
-
- - -
-
- -
-
-
-
- -
-
-
diff --git a/src/modules/ui/directives/transaction/types/lease/Lease.js b/src/modules/ui/directives/transaction/types/lease/Lease.js new file mode 100644 index 0000000000..2c91f7f99b --- /dev/null +++ b/src/modules/ui/directives/transaction/types/lease/Lease.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wLease', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/lease/lease.html' + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/lease/lease.html b/src/modules/ui/directives/transaction/types/lease/lease.html new file mode 100644 index 0000000000..4bca69d870 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/lease/lease.html @@ -0,0 +1,21 @@ +
+
+
+
+
+ +
+
+ +
+
+
+
+ +
+
+
+ diff --git a/src/modules/ui/directives/transaction/types/mass-transfer/MassTransfer.js b/src/modules/ui/directives/transaction/types/mass-transfer/MassTransfer.js new file mode 100644 index 0000000000..03473793e7 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/mass-transfer/MassTransfer.js @@ -0,0 +1,105 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wTransfer', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/transfer/transfer.html' + }); +})(); +(function () { + 'use strict'; + + /** + * @param {User} user + * @param {BaseAssetService} baseAssetService + * @param {Waves} waves + * @param {$rootScope.Scope} $scope + * @return {MassTransfer} + */ + + const controller = function (user, baseAssetService, waves, $scope) { + + class MassTransfer { + + /** + * {object} + */ + props = null; + + $postLink() { + this.typeName = this.props.typeName; + this.time = this.props.time; + this.address = this.props.shownAddress; + + const TYPES = waves.node.transactions.TYPES; + + switch (this.typeName) { + case TYPES.SPONSORSHIP_FEE: + this.sponsoredFee(); + break; + default: + this.transfered(); + } + } + + /** + * @param {{id: string, name: string}} asset + * @return {string} + */ + getAssetName(asset) { + try { + return !user.scam[asset.id] ? asset.name : ''; + } catch (e) { + return ''; + } + } + + sponsoredFee() { + this.assetName = this.getAssetName(this.props.fee.asset); + this.amountParams = { + sign: '+', + amount: this.props.fee.toFormat(), + name: this.props.fee.asset.name + }; + } + + transfered() { + this.assetName = this.getAssetName(this.props.amount.asset); + this.amountParams = { + amount: this.props.amount.toFormat(), + name: this.props.amount.asset.name + }; + if (this.props.amount && this.props.amount instanceof ds.wavesDataEntities.Money) { + baseAssetService.convertToBaseAsset(this.props.amount) + .then((baseMoney) => { + this.mirrorBalanceParams = { + amount: baseMoney.toFormat(), + name: baseMoney.asset.name + }; + $scope.$digest(); + }); + } + } + + } + + return new MassTransfer(); + }; + + controller.$inject = [ + 'user', + 'baseAssetService', + 'waves', + '$scope' + ]; + + angular.module('app.ui').component('wMassTransferRow', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/mass-transfer/mass-transfer.html', + controller + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/sponsorship_fee.html b/src/modules/ui/directives/transaction/types/mass-transfer/mass-transfer.html similarity index 50% rename from src/modules/ui/directives/transaction/types/sponsorship_fee.html rename to src/modules/ui/directives/transaction/types/mass-transfer/mass-transfer.html index 427769ead0..37bfadd522 100644 --- a/src/modules/ui/directives/transaction/types/sponsorship_fee.html +++ b/src/modules/ui/directives/transaction/types/mass-transfer/mass-transfer.html @@ -2,23 +2,22 @@
+ params="{name: $ctrl.assetName}"> +
+ params="{time: $ctrl.time, address: $ctrl.address}">
+ params="$ctrl.amountParams"> +
+
+
diff --git a/src/modules/ui/directives/transaction/types/reissue/Reissue.js b/src/modules/ui/directives/transaction/types/reissue/Reissue.js new file mode 100644 index 0000000000..08aa2d9775 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/reissue/Reissue.js @@ -0,0 +1,64 @@ +(function () { + 'use strict'; + + const tsUtils = require('ts-utils'); + const { Money } = require('@waves/data-entities'); + + /** + * @param {User} user + * @return {Reissue} + */ + + const controller = function (user) { + + class Reissue { + + /** + * {object} + */ + props = null; + + $postLink() { + this.assetName = this.getAssetName( + tsUtils.get(this.props, 'amount.asset') || + tsUtils.get(this.props, 'quantity.asset') || + this.props + ); + this.name = tsUtils.get(this.props, 'amount.asset.name') || + tsUtils.get(this.props, 'quantity.asset.name'); + + const amount = tsUtils.get(this.props, 'amount') || tsUtils.get(this.props, 'quantity'); + this.amount = amount instanceof Money ? + amount.toFormat() : + amount.div(Math.pow(10, this.props.precision)); + } + + /** + * @param {{id: string, name: string}} asset + * @return {string} + */ + getAssetName(asset) { + try { + return !user.scam[asset.id] ? asset.name : ''; + } catch (e) { + return ''; + } + } + + } + + return new Reissue(); + }; + + controller.$inject = [ + 'user' + ]; + + angular.module('app.ui').component('wReissue', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/reissue/reissue.html', + controller + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/reissue/reissue.html b/src/modules/ui/directives/transaction/types/reissue/reissue.html new file mode 100644 index 0000000000..afee586c3c --- /dev/null +++ b/src/modules/ui/directives/transaction/types/reissue/reissue.html @@ -0,0 +1,23 @@ +
+
+
+ + +
+
+ +
+
+
+
+ + {{$ctrl.name}} +
+
+ +
+
+
diff --git a/src/modules/ui/directives/transaction/types/script-invocation/script-invocation.html b/src/modules/ui/directives/transaction/types/script-invocation/script-invocation.html new file mode 100644 index 0000000000..27e71da500 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/script-invocation/script-invocation.html @@ -0,0 +1,12 @@ +
+
+
+ +
+
+ +
+
+
+
diff --git a/src/modules/ui/directives/transaction/types/script-invocation/script-invocation.js b/src/modules/ui/directives/transaction/types/script-invocation/script-invocation.js new file mode 100644 index 0000000000..88c98ec19f --- /dev/null +++ b/src/modules/ui/directives/transaction/types/script-invocation/script-invocation.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wScriptInvocation', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/script-invocation/script-invocation.html' + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/set-asset-script/SetAssetScript.js b/src/modules/ui/directives/transaction/types/set-asset-script/SetAssetScript.js new file mode 100644 index 0000000000..e27c8c8020 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/set-asset-script/SetAssetScript.js @@ -0,0 +1,42 @@ +(function () { + 'use strict'; + + /** + * @param {Waves} waves + * @return {Transaction} + */ + + const controller = function (waves) { + + class SetAssetScript { + + /** + * {object} + */ + props = null; + + $postLink() { + if (this.props.assetId) { + waves.node.assets.getAsset(this.props.assetId).then(asset => { + this.name = asset.name; + }); + } + } + + } + + return new SetAssetScript(); + }; + + controller.$inject = [ + 'waves' + ]; + + angular.module('app.ui').component('wSetAssetScript', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/set-asset-script/set-asset-script.html', + controller + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/set-asset-script.html b/src/modules/ui/directives/transaction/types/set-asset-script/set-asset-script.html similarity index 71% rename from src/modules/ui/directives/transaction/types/set-asset-script.html rename to src/modules/ui/directives/transaction/types/set-asset-script/set-asset-script.html index 0962d953e1..312d951a20 100644 --- a/src/modules/ui/directives/transaction/types/set-asset-script.html +++ b/src/modules/ui/directives/transaction/types/set-asset-script/set-asset-script.html @@ -4,8 +4,8 @@
- +
diff --git a/src/modules/ui/directives/transaction/types/set-script-cancel.html b/src/modules/ui/directives/transaction/types/set-script-cancel.html deleted file mode 100644 index 311c101749..0000000000 --- a/src/modules/ui/directives/transaction/types/set-script-cancel.html +++ /dev/null @@ -1,7 +0,0 @@ -
-
-
- -
-
-
diff --git a/src/modules/ui/directives/transaction/types/set-script/SetScript.js b/src/modules/ui/directives/transaction/types/set-script/SetScript.js new file mode 100644 index 0000000000..f468cc20bd --- /dev/null +++ b/src/modules/ui/directives/transaction/types/set-script/SetScript.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wSetScript', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/set-script/set-script.html' + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/set-script.html b/src/modules/ui/directives/transaction/types/set-script/set-script.html similarity index 60% rename from src/modules/ui/directives/transaction/types/set-script.html rename to src/modules/ui/directives/transaction/types/set-script/set-script.html index b52b4ad558..4cee824bcc 100644 --- a/src/modules/ui/directives/transaction/types/set-script.html +++ b/src/modules/ui/directives/transaction/types/set-script/set-script.html @@ -1,7 +1,7 @@
- +
diff --git a/src/modules/ui/directives/transaction/types/sponsorship.html b/src/modules/ui/directives/transaction/types/sponsorship.html deleted file mode 100644 index c6e41364ff..0000000000 --- a/src/modules/ui/directives/transaction/types/sponsorship.html +++ /dev/null @@ -1,14 +0,0 @@ -
-
-
- - - -
- {{::$ctrl.time}} -
-
-
-
-
diff --git a/src/modules/ui/directives/transaction/types/sponsorship/Sponsorship.js b/src/modules/ui/directives/transaction/types/sponsorship/Sponsorship.js new file mode 100644 index 0000000000..f0ed4fa554 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/sponsorship/Sponsorship.js @@ -0,0 +1,54 @@ +(function () { + 'use strict'; + + const tsUtils = require('ts-utils'); + + /** + * @param {User} user + * @return {Sponsorship} + */ + + const controller = function (user) { + + class Sponsorship { + + /** + * {object} + */ + props = null; + + $postLink() { + this.assetName = this.getAssetName( + tsUtils.get(this.props, 'minSponsoredAssetFee.asset') + ); + } + + /** + * @param {{id: string, name: string}} asset + * @return {string} + */ + getAssetName(asset) { + try { + return !user.scam[asset.id] ? asset.name : ''; + } catch (e) { + return ''; + } + } + + } + + return new Sponsorship(); + }; + + controller.$inject = [ + 'user' + ]; + + angular.module('app.ui').component('wSponsorship', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/sponsorship/sponsorship.html', + controller + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/create-alias.html b/src/modules/ui/directives/transaction/types/sponsorship/sponsorship.html similarity index 56% rename from src/modules/ui/directives/transaction/types/create-alias.html rename to src/modules/ui/directives/transaction/types/sponsorship/sponsorship.html index 324e688e5a..67654a376c 100644 --- a/src/modules/ui/directives/transaction/types/create-alias.html +++ b/src/modules/ui/directives/transaction/types/sponsorship/sponsorship.html @@ -1,12 +1,11 @@
- +
- + {{::$ctrl.props.time}}
diff --git a/src/modules/ui/directives/transaction/types/tokens.html b/src/modules/ui/directives/transaction/types/tokens.html deleted file mode 100644 index a2c72033b8..0000000000 --- a/src/modules/ui/directives/transaction/types/tokens.html +++ /dev/null @@ -1,25 +0,0 @@ -
-
-
- - -
-
- -
-
-
-
- - {{$ctrl.name}} -
-
- -
-
-
diff --git a/src/modules/ui/directives/transaction/types/transfer.html b/src/modules/ui/directives/transaction/types/transfer.html deleted file mode 100644 index 0c1e183ccc..0000000000 --- a/src/modules/ui/directives/transaction/types/transfer.html +++ /dev/null @@ -1,23 +0,0 @@ -
-
-
- - -
-
- -
-
-
-
- -
-
- -
-
-
diff --git a/src/modules/ui/directives/transaction/types/transfer/Transfer.js b/src/modules/ui/directives/transaction/types/transfer/Transfer.js new file mode 100644 index 0000000000..7e585f3a4b --- /dev/null +++ b/src/modules/ui/directives/transaction/types/transfer/Transfer.js @@ -0,0 +1,105 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wTransfer', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/transfer/transfer.html' + }); +})(); +(function () { + 'use strict'; + + /** + * @param {User} user + * @param {BaseAssetService} baseAssetService + * @param {Waves} waves + * @param {$rootScope.Scope} $scope + * @return {Transfer} + */ + + const controller = function (user, baseAssetService, waves, $scope) { + + class Transfer { + + /** + * {object} + */ + props = null; + + $postLink() { + this.typeName = this.props.typeName; + this.time = this.props.time; + this.address = this.props.shownAddress; + + const TYPES = waves.node.transactions.TYPES; + + switch (this.typeName) { + case TYPES.SPONSORSHIP_FEE: + this.sponsoredFee(); + break; + default: + this.transfered(); + } + } + + /** + * @param {{id: string, name: string}} asset + * @return {string} + */ + getAssetName(asset) { + try { + return !user.scam[asset.id] ? asset.name : ''; + } catch (e) { + return ''; + } + } + + sponsoredFee() { + this.assetName = this.getAssetName(this.props.fee.asset); + this.amountParams = { + sign: '+', + amount: this.props.fee.toFormat(), + name: this.props.fee.asset.name + }; + } + + transfered() { + this.assetName = this.getAssetName(this.props.amount.asset); + this.amountParams = { + amount: this.props.amount.toFormat(), + name: this.props.amount.asset.name + }; + if (this.props.amount && this.props.amount instanceof ds.wavesDataEntities.Money) { + baseAssetService.convertToBaseAsset(this.props.amount) + .then((baseMoney) => { + this.mirrorBalanceParams = { + amount: baseMoney.toFormat(), + name: baseMoney.asset.name + }; + $scope.$digest(); + }); + } + } + + } + + return new Transfer(); + }; + + controller.$inject = [ + 'user', + 'baseAssetService', + 'waves', + '$scope' + ]; + + angular.module('app.ui').component('wTransferRow', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/transfer/transfer.html', + controller + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/transfer/transfer.html b/src/modules/ui/directives/transaction/types/transfer/transfer.html new file mode 100644 index 0000000000..37bfadd522 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/transfer/transfer.html @@ -0,0 +1,23 @@ +
+
+
+ + +
+
+ +
+
+
+
+ +
+
+ +
+
+
diff --git a/src/modules/ui/directives/transaction/types/unknown/Unknown.js b/src/modules/ui/directives/transaction/types/unknown/Unknown.js new file mode 100644 index 0000000000..b1573f7342 --- /dev/null +++ b/src/modules/ui/directives/transaction/types/unknown/Unknown.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wUnknown', { + bindings: { + props: '<' + }, + templateUrl: 'modules/ui/directives/transaction/types/unknown/unknown.html' + }); +})(); diff --git a/src/modules/ui/directives/transaction/types/unknown.html b/src/modules/ui/directives/transaction/types/unknown/unknown.html similarity index 52% rename from src/modules/ui/directives/transaction/types/unknown.html rename to src/modules/ui/directives/transaction/types/unknown/unknown.html index 46319e7eb9..f52d7f1453 100644 --- a/src/modules/ui/directives/transaction/types/unknown.html +++ b/src/modules/ui/directives/transaction/types/unknown/unknown.html @@ -1,13 +1,13 @@
- +
- +
diff --git a/src/modules/ui/directives/transactionInfo/TransactionInfo.js b/src/modules/ui/directives/transactionInfo/TransactionInfo.js index 3854a3e62c..39000ed6d1 100644 --- a/src/modules/ui/directives/transactionInfo/TransactionInfo.js +++ b/src/modules/ui/directives/transactionInfo/TransactionInfo.js @@ -26,7 +26,8 @@ [SIGN_TYPE.DATA]: 'Data', [SIGN_TYPE.SET_SCRIPT]: 'Set Script', [SIGN_TYPE.SPONSORSHIP]: 'Sponsorship', - [SIGN_TYPE.SET_ASSET_SCRIPT]: 'Set Asset Script' + [SIGN_TYPE.SET_ASSET_SCRIPT]: 'Set Asset Script', + [SIGN_TYPE.SCRIPT_INVOCATION]: 'Script Invocation' }; class TransactionInfoCtrl extends Base { diff --git a/src/modules/ui/directives/transactionInfo/transaction-info-content.html b/src/modules/ui/directives/transactionInfo/transaction-info-content.html index c67033baba..b1d025bceb 100644 --- a/src/modules/ui/directives/transactionInfo/transaction-info-content.html +++ b/src/modules/ui/directives/transactionInfo/transaction-info-content.html @@ -12,6 +12,7 @@ +
diff --git a/src/modules/ui/directives/transactionInfo/transaction-info-json.html b/src/modules/ui/directives/transactionInfo/transaction-info-json.html index 90452aa641..3111257007 100644 --- a/src/modules/ui/directives/transactionInfo/transaction-info-json.html +++ b/src/modules/ui/directives/transactionInfo/transaction-info-json.html @@ -8,5 +8,5 @@
-
{{$ctrl.json}}
+
{{$ctrl.json}}
diff --git a/src/modules/ui/directives/transactionInfo/transactionInfo.less b/src/modules/ui/directives/transactionInfo/transactionInfo.less index 5446549314..7b6b6f398b 100644 --- a/src/modules/ui/directives/transactionInfo/transactionInfo.less +++ b/src/modules/ui/directives/transactionInfo/transactionInfo.less @@ -1,5 +1,6 @@ @import (reference) '../../../app/less/typography'; @import (reference) "../../../app/less/app-icons"; +@import (reference) '../../../app/less/app'; @import (reference) 'config'; @import (reference) 'icons'; @@ -64,6 +65,13 @@ w-transaction-info-header + w-transaction-info-general { padding-top: 30px; border-top: 1px solid @color-basic-100; } + + &-scrolled { + max-height: 248px; + overflow: auto; + margin-right: -13px; + padding-right: 13px; + } } &__lead { @@ -101,7 +109,7 @@ w-transaction-info-header + w-transaction-info-general { padding: 13px 0; border-top: 1px dashed @color-basic-100; - &:first-child { + &:first-child:not(.txinfo__row-header) { border-top: 1px solid @color-basic-100; } @@ -187,11 +195,24 @@ w-transaction-info-header + w-transaction-info-general { max-height: 140px; overflow: scroll; } + + &__button { + color: @color-submit-300; + cursor: pointer; + } } &-border-ts { border-top: 1px solid @color-basic-100; } + + &-data { + .txinfo__row { + &:last-child { + border-bottom: 1px dashed @color-basic-100; + } + } + } } @@ -289,13 +310,17 @@ w-transaction-info-header + w-transaction-info-general { .icon-tx-set-asset-script(); } + &.script-invocation { + .icon-tx-script-invocation(); + } + &::before { width: @tx-icon-size; height: @tx-icon-size; background-size: auto; background-color: @color-white; background-repeat: no-repeat; - background-image: url(/img/icons/transaction-icons-80.svg); + background-image: @transaction-icons; content: ''; display: block; } @@ -359,6 +384,202 @@ w-transaction-info-header + w-transaction-info-general { .status-label { margin-top: -4px; } + + &__item { + display: flex; + flex: 1 1 0; + overflow: hidden; + margin-right: 10px; + .txinfo__unit { + text-overflow: ellipsis; + overflow: hidden; + padding-right: 0; + } + + &:last-child { + justify-content: flex-end; + margin-right: 0; + } + } + + &__show { + &-fields { + margin-bottom: -1px; + padding-bottom: 10px; + } + + &-text { + cursor: pointer; + } + } + + .transaction-details { + display: flex; + flex-direction: column; + margin-bottom: 13px; + padding: 0 0 16px; + border-radius: 4px; + max-height: 217px; + overflow-y: hidden; + background-color: @color-basic-50; + transition: max-height 0.3s, margin 0.3s, padding 0.3s; + &.ng-hide { + max-height: 0; + margin-bottom: 0; + padding: 0; + } + &.ng-hide-add { + overflow-y: hidden; + } + &.ng-hide-remove { + overflow-y: hidden; + } + &__list { + padding: 0 16px; + margin: 0; + max-height: 178px; + overflow: hidden; + transition: max-height 0.3s, margin 0.3s; + } + &__item { + width: 100%; + display: flex; + align-items: flex-start; + justify-content: space-between; + border-top: 1px dashed @color-basic-100; + padding: 12px 0 13px; + &_header { + color: @color-basic-500; + } + &:first-child { + padding-top: 16px; + border-top: 0; + } + &:last-child { + padding-bottom: 16px; + } + } + &__actions { + display: flex; + justify-content: flex-end; + padding: 0 16px; + max-height: 100%; + } + &__action { + cursor: pointer; + display: inline-flex; + align-items: center; + &:not(:first-child) { + &:before { + content: ''; + background: @color-basic-500; + width: 1px; + height: 12px; + margin: 0 10px; + } + } + } + &.show-all { + max-height: 260px; + .transaction-details__list { + overflow-y: auto; + max-height: 226px; + } + } + } + + .invoke-args-list__item-value { + max-width: 216px; + &:hover ~ .tooltip { + display: block; + } + text-overflow: ellipsis; + overflow: hidden; + white-space: nowrap; + } + + .invoke-args-list__item { + position: relative; + } + + // TODO tooltip + //.tooltip { + // display: none; + // max-width: 100%; + // position: absolute; + // padding: 6px 12px; + // top: 35px; + // right: 149px; + // transform-origin: center; + // color: @color-white; + // font-size: @font-size-caption-2; + // line-height: 13px; + // cursor: pointer; + // text-shadow: 0 1px 6px rgba(78, 92, 110, 0.6); + // z-index: 10; + // text-align: left; + // word-wrap: break-word; + // border-radius: @border-radius; + // background: rgba(78, 92, 110, 0.8); + // span { + // overflow: hidden; + // text-overflow: ellipsis; + // display: inline-block; + // text-align: center; + // } + // + // &::before { + // position: absolute; + // content: ''; + // z-index: -1; + // top: -5px; + // right: 10px; + // opacity: .8; + // width: 0; + // height: 0; + // border: 5px solid transparent; + // border-bottom-color: @color-basic-700; + // border-top: 0 none; + // transform: translate(0); + // } + // + // &.right { + // right: 0; + // } + //} +} + + +@media screen and (max-width: @width-media-tiny) { + .recipients-row { + padding: 9px 0 10px; + &:first-child { + padding-top: 12px; + } + &:last-child { + padding-bottom: 12px; + } + } +} + +.code-wrapper { + border: 1px dashed @color-basic-200; + border-radius: @border-radius; + background: @color-basic-50; + height: auto; + max-height: 300px; + word-break: break-all; + padding: 17px; + display: block; + overflow: scroll; + + &-vertical { + overflow-y: auto; + overflow-x: hidden; + .pre { + white-space: normal; + } + } } @media screen and (max-width: 540px) { diff --git a/src/modules/ui/directives/transactionInfo/types/data/DataInfo.js b/src/modules/ui/directives/transactionInfo/types/data/DataInfo.js index 7c543ce060..df0fbf41d1 100644 --- a/src/modules/ui/directives/transactionInfo/types/data/DataInfo.js +++ b/src/modules/ui/directives/transactionInfo/types/data/DataInfo.js @@ -3,9 +3,10 @@ /** * @param {$rootScope.Scope} $scope + * @param {JQuery} $element * @return {DataInfo} */ - const controller = function ($scope) { + const controller = function ($scope, $element) { class DataInfo { @@ -13,10 +14,25 @@ * @type {Signable} */ signable; + /** + * @type {string} + */ + json; + /** + * @type {boolean} + */ + dataVisible = false; + /** + * @type {boolean} + */ + allVisible = false; $postLink() { this.transaction = this.signable.getTxData(); + this.signable.getDataForApi().then(json => { + this.json = WavesApp.stringifyJSON(json, null, 4); + }); (this.transaction.id ? Promise.resolve(this.transaction.id) : this.signable.getId()) .then(id => { this.id = id; @@ -24,12 +40,28 @@ }); } + /** + * @public + */ + toggleAll() { + this.allVisible = !this.allVisible; + $element.find('.transaction-details__list').stop().animate({ scrollTop: 0 }, 300); + } + + /** + * @public + */ + toggleVisible() { + this.allVisible = false; + this.dataVisible = !this.dataVisible; + } + } return new DataInfo(); }; - controller.$inject = ['$scope']; + controller.$inject = ['$scope', '$element']; angular.module('app.ui').component('wDataInfo', { bindings: { diff --git a/src/modules/ui/directives/transactionInfo/types/data/data-info.html b/src/modules/ui/directives/transactionInfo/types/data/data-info.html index dd77e94b70..43bf41df81 100644 --- a/src/modules/ui/directives/transactionInfo/types/data/data-info.html +++ b/src/modules/ui/directives/transactionInfo/types/data/data-info.html @@ -1,9 +1,46 @@ -
+
-
{{::$ctrl.transaction.stringifiedData}}
+
+
+
+
    +
  • +
    +
    +
    +
  • +
  • +
    {{transaction.key}}
    +
    {{transaction.type}}
    +
    {{transaction.value}}
    +
  • +
+
+ + + +
+
+
+ + + + + diff --git a/src/modules/ui/directives/transactionInfo/types/script-invocation/script-invocation-header.html b/src/modules/ui/directives/transactionInfo/types/script-invocation/script-invocation-header.html new file mode 100644 index 0000000000..7061567aa8 --- /dev/null +++ b/src/modules/ui/directives/transactionInfo/types/script-invocation/script-invocation-header.html @@ -0,0 +1,3 @@ +
+

+
diff --git a/src/modules/ui/directives/transactionInfo/types/script-invocation/script-invocation-info.html b/src/modules/ui/directives/transactionInfo/types/script-invocation/script-invocation-info.html new file mode 100644 index 0000000000..81d70f0242 --- /dev/null +++ b/src/modules/ui/directives/transactionInfo/types/script-invocation/script-invocation-info.html @@ -0,0 +1,53 @@ +
+
+
{{::$ctrl.transaction.call.function || 'Default function'}}
+
+ +
+
+
+
+
+
+
    +
  • + {{::arg.type}} + {{::arg.value}} +
  • +
+
+ + + +
+
+
+
+
+
{{::$ctrl.transaction.dApp}}
+
+
+
+
{{::$ctrl.payment}}
+
+
+
+
{{::$ctrl.transaction.id}}
+
+ + + \ No newline at end of file diff --git a/src/modules/ui/directives/transactionInfo/types/script-invocation/scriptInvocation.js b/src/modules/ui/directives/transactionInfo/types/script-invocation/scriptInvocation.js new file mode 100644 index 0000000000..25537043c8 --- /dev/null +++ b/src/modules/ui/directives/transactionInfo/types/script-invocation/scriptInvocation.js @@ -0,0 +1,86 @@ +(function () { + 'use strict'; + + /** + * @param {JQuery} $element + * @return {DataInfo} + */ + const controller = function ($element) { + + class DataInfo { + + /** + * @type {Signable} + */ + signable; + /** + * @type {boolean} + */ + dataVisible = false; + /** + * @type {boolean} + */ + allVisible = false; + /** + * @type {string} + */ + function; + /** + * @type {string} + */ + json; + /** + * @type {string} + */ + payment; + /** + * @type {string} + */ + args; + + + $postLink() { + this.transaction = this.signable.getTxData(); + this.signable.getDataForApi().then(json => { + this.json = WavesApp.stringifyJSON(json, null, 4); + }); + if (this.transaction.payment.length > 0) { + const payment = this.transaction.payment[0]; + this.payment = `${payment.getTokens().toFormat()} ${payment.asset.displayName}`; + } + if (this.transaction.call) { + this.args = this.transaction.call.args; + } + } + + /** + * @public + */ + toggleAll() { + this.allVisible = !this.allVisible; + $element.find('.transaction-details__list').stop().animate({ scrollTop: 0 }, 300); + } + + /** + * @public + */ + toggleVisible() { + this.allVisible = false; + this.dataVisible = !this.dataVisible; + } + + } + + return new DataInfo(); + }; + + controller.$inject = ['$element']; + + angular.module('app.ui').component('wScriptInvocationInfo', { + bindings: { + signable: '<' + }, + controller, + templateUrl: 'modules/ui/directives/transactionInfo/types/script-invocation/script-invocation-info.html' + }); +})(); diff --git a/src/modules/ui/directives/transactionInfo/types/script-invocation/scriptInvocationHeader.js b/src/modules/ui/directives/transactionInfo/types/script-invocation/scriptInvocationHeader.js new file mode 100644 index 0000000000..900d51df54 --- /dev/null +++ b/src/modules/ui/directives/transactionInfo/types/script-invocation/scriptInvocationHeader.js @@ -0,0 +1,10 @@ +(function () { + 'use strict'; + + angular.module('app.ui').component('wScriptInvocationHeader', { + bindings: { + signable: '<' + }, + templateUrl: 'modules/ui/directives/transactionInfo/types/script-invocation/script-invocation-header.html' + }); +})(); diff --git a/src/modules/utils/modals/assetInfo/AssetInfoCtrl.js b/src/modules/utils/modals/assetInfo/AssetInfoCtrl.js index 33f1214e2e..2e0ecd5ddc 100644 --- a/src/modules/utils/modals/assetInfo/AssetInfoCtrl.js +++ b/src/modules/utils/modals/assetInfo/AssetInfoCtrl.js @@ -13,8 +13,6 @@ const controller = function (Base, $scope, user, createPoll, utils, waves) { const ds = require('data-service'); - const { path } = require('ramda'); - const { STATUS_LIST } = require('@waves/oracle-data'); class AssetInfoCtrl extends Base { @@ -36,18 +34,17 @@ this.totalBalance = null; this.transactions = []; this.transactionsPending = true; - const data = ds.dataManager.getOracleAssetData(asset.id); - this.isVerified = path(['status'], data) === STATUS_LIST.VERIFIED; - this.isGateway = path(['status'], data) === 3; - this.isSuspicious = user.scam[this.asset.id]; - this.hasLabel = this.isVerified || this.isGateway || this.isSuspicious; - - // this.ticker = path(['ticker'], data); // TODO STEP 2 - this.ticker = asset.ticker; // TODO STEP 2 - this.link = path(['link'], data); - this.email = path(['email'], data); - this.provider = this.isVerified && path(['provider'], data) || null; - this.description = path(['description', 'en'], data) || asset.description; + + const { + link, email, provider, description + } = utils.getDataFromOracles(this.asset.id); + + // this.ticker = path(['ticker'], data); // TODO STEP 2= + this.link = link; + this.email = email; + + this.provider = provider; + this.description = description || asset.description; this.withScam = null; this.spam = []; diff --git a/src/modules/utils/modals/assetInfo/assetInfo.html b/src/modules/utils/modals/assetInfo/assetInfo.html index 5627977cd6..9e8e4ee5be 100644 --- a/src/modules/utils/modals/assetInfo/assetInfo.html +++ b/src/modules/utils/modals/assetInfo/assetInfo.html @@ -1,28 +1,6 @@
-
-
- -
-

- {{::$ctrl.asset.name}} - - - -

- -
{{::$ctrl.ticker}}
-
- -
- -
-
- -
-
+
-
-
- - -
-

{{::$ctrl.asset.name}} - - -

- -
- {{::$ctrl.ticker}} -
-
- -
- -
-
- -
-
+
@@ -122,7 +99,7 @@

{{::$ctrl.asset.name}}

+ class="error-400">
-
{{::$ctrl.errorMessage}}
+
{{::$ctrl.errorMessage}}
diff --git a/src/modules/utils/modals/modal.less b/src/modules/utils/modals/modal.less index 39bbee2358..e262efc695 100644 --- a/src/modules/utils/modals/modal.less +++ b/src/modules/utils/modals/modal.less @@ -1,3 +1,5 @@ +@import (reference) 'config'; + md-dialog { md-toolbar { @@ -46,6 +48,47 @@ md-dialog { } } +.md-dialog-backdrop:nth-of-type(even) { + z-index: 81; +} + +.md-dialog-backdrop:nth-of-type(odd) { + z-index: 79; + opacity: 0.7; +} + +.md-dialog-container:first-child:nth-of-type(even) { + z-index: 75; +} + +.md-dialog-container:nth-of-type(odd) { + z-index: 82; +} + +.md-dialog-container { + md-dialog { + box-shadow: none; + position: absolute; + max-height: 90%; + width: 540px; + background: @color-white; + color: @color-disabled-900; + + md-dialog-actions { + display: flex; + flex-direction: row; + justify-content: center; + } + } +} + +md-toolbar.md-default-theme:not(.md-menu-toolbar), +md-toolbar:not(.md-menu-toolbar) { + background-color: @color-white; + color: @color-black; + border-bottom: 1px solid @color-basic-200; +} + @media screen and (max-width: 540px) { md-dialog { @@ -65,4 +108,24 @@ md-dialog { } } + .md-dialog-container { + md-dialog { + width: 100%; + max-width: 100%; + min-width: 360px; + height: 100%; + max-height: 100%; + left: 0; + top: 0; + transform-origin: center; + transform: translateY(0) translateX(0); + border-radius: 0; + + md-dialog-content { + padding: 20px 20px 0; + height: 100%; + color: @color-disabled-900; + } + } + } } diff --git a/src/modules/utils/modals/pinAsset/pinAsset.html b/src/modules/utils/modals/pinAsset/pinAsset.html index 980e29e5eb..5bc1293611 100644 --- a/src/modules/utils/modals/pinAsset/pinAsset.html +++ b/src/modules/utils/modals/pinAsset/pinAsset.html @@ -5,11 +5,14 @@

- + + +