diff --git a/CHANGELOG.md b/CHANGELOG.md index aef343b3d4..20847d133e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,37 @@ +--------------------------------------------------------------------- +Release 2.0.171101 +--------------------------------------------------------------------- +New features +-------- +- #634 The hosted wallet is now available at wallet.bitshares.org +- #530 Withdraw amounts now factor in the gate fee +- #538 The voting page has been completely revamped +- #579 The margin position tab now includes a set of default assets +- #632 The connection status is now visible throughout the app +- #302 Your own orders are highlighted in the order book +- #623 The Chinese translation has been updated +- #670 My Trades now show dates instead of block numbers +- #581 Market fees are now shown in the exchange page +- #633 Clicking on connection status now takes you to Settings --> Access +- #430 The asset page for bit assets now includes a sortable list of open margin position +- #583 The portfolio is now sortable + +Bug fixes +-------- +- #658 BTS trade button missing from portfolio view +- #627 Display Feed Published value as an actual date/time in localized time zone +- #52 Show a warning about core_exchange_rate at asset create/update page +- #455 Trollbox has been removed completely +- #645 Kexcoin has been removed from the dashboard +- #622 Login screens have been harmonized +- #580 Annual membership fee now is now shown as disabled +- #607 Long line wrapping issue has been fixed +- #590 'Reserve asset' changed to 'Burn asset' +- #586 Input fields clear properly when switching between markets +- #594 Leading decimals can now be input correctly in the exchange +- #498 Orderbook scrollbars always visible +- #673 Account tab headers are now highlighted + --------------------------------------------------------------------- Release 2.0.171015 --------------------------------------------------------------------- diff --git a/README.md b/README.md index 9623b197c7..6481f065a7 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,6 @@ npm install The dev server uses Express in combination with Webpack. -<<<<<<< fcd7d7a6e6b91ecd0695bdac7368ef9dbaaec712 Once all the packages have been installed you can start the development server by running: >开发服务器使用了EXPRESS和Webpack. diff --git a/app/api/apiConfig.js b/app/api/apiConfig.js index 22224db34b..6e670258c3 100644 --- a/app/api/apiConfig.js +++ b/app/api/apiConfig.js @@ -31,7 +31,7 @@ export const settingsAPIs = { {url: "wss://bitshares.crypto.fans/ws", location: "Munich, Germany"}, {url: "wss://node.testnet.bitshares.eu", location: "Public Testnet Server (Frankfurt, Germany)"} ], - DEFAULT_FAUCET: "https://bitshares.openledger.info", + DEFAULT_FAUCET: "https://faucet.bitshares.eu", TESTNET_FAUCET: "https://faucet.testnet.bitshares.eu", RPC_URL: "https://openledger.info/api/" }; diff --git a/app/assets/locales/locale-en.json b/app/assets/locales/locale-en.json index e937044abc..f56bc7d422 100644 --- a/app/assets/locales/locale-en.json +++ b/app/assets/locales/locale-en.json @@ -2,7 +2,9 @@ "counterpart": { "formats": { "date": { - "short_custom": "%e %b '%y" + "short_custom": "%e %b '%y", + "market_history": "%e/%m %H:%M:%S", + "market_history_us": "%m/%e %H:%M:%S" } } }, @@ -18,7 +20,7 @@ "ru": "Русский" }, "incognito": { - "no_support": "This Bitshares Wallet relies on Local Storage and IndexedDB which are not persistent when using Incognito Browsing. We recommend using a regular browsing session.", + "no_support": "This BitShares Wallet relies on Local Storage and IndexedDB which are not persistent when using Incognito Browsing. We recommend using a regular browsing session.", "ignore": "I understand, continue." }, "sync_fail": { @@ -1096,7 +1098,7 @@ "not_first_account": "Since you already have an account, you will need to pay for this new account yourself. In order to do so, your account needs to have lifetime membership, which can be bought in the account page.", "must_be_ltm": "The fee paying account must be a lifetime member to perform that operation.", "backup_explain": "Clicking on the button below will generate a backup file with a .bin extension. This file is encrypted with your wallet password, and contains all the private keys for your accounts. It can be used to restore your wallet, or move it to a different computer/browser.", - "backup_new_account": "Congratulations, you've just created a new account on the Bitshares blockchain! It is strongly recommended that you make a backup of your wallet now. Without a backup there is no way to restore your account if something happens to your computer.", + "backup_new_account": "Congratulations, you've just created a new account on the BitShares blockchain! It is strongly recommended that you make a backup of your wallet now. Without a backup there is no way to restore your account if something happens to your computer.", "brainkey_not_backed_up": "This brainkey has never been backed up", "brainkey_backed_up": "This brainkey was last backed up", "new_password": "New password", @@ -1170,7 +1172,7 @@ "current_pass": "Current password", "no_wallet": "You do not have a local wallet yet", "generated": "Generated password", - "account_exp": "This account will be created on the blockchain and will be your address for any transfers you want to make! There are no long Bitcoin-style addresses in Bitshares!", + "account_exp": "This account will be created on the blockchain and will be your address for any transfers you want to make! There are no long Bitcoin-style addresses in BitShares!", "understand_1": "I understand that no one can recover my password if I lose or forget it", "understand_2": "I have written down or otherwise stored my password", "understand_3": " I understand that I will lose access to my funds if I lose my password", @@ -1335,7 +1337,7 @@ "coming_soon": "Coming soon" }, "unavailable": "The gateway service for this asset is currently down, please try again later", - "unavailable_bridge": "The brdige service for this asset is currently down, please try again later", + "unavailable_bridge": "The bridge service for this asset is currently down, please try again later", "unavailable_OPEN": "The OpenLedger Gateway is down or not responding", "unavailable_RUDEX": "The RuDEX Gateway is down or not responding", "unavailable_TRADE": "The Blocktrades Bridge is down or not responding" diff --git a/app/assets/locales/locale-it.json b/app/assets/locales/locale-it.json index 24427b0395..dc538d1d2e 100644 --- a/app/assets/locales/locale-it.json +++ b/app/assets/locales/locale-it.json @@ -11,7 +11,7 @@ "ru": "Русский" }, "incognito": { - "no_support": "Questo Portafoglio Bitshares necessita di Local Storage e IndexedDB, funzionalità che non sono persistenti nella modalità in incognito. Raccomandiamo l'uso di una sessione di navigazione normale.", + "no_support": "Questo Portafoglio BitShares necessita di Local Storage e IndexedDB, funzionalità che non sono persistenti nella modalità in incognito. Raccomandiamo l'uso di una sessione di navigazione normale.", "ignore": "Ho capito, continua." }, "sync_fail": { @@ -70,21 +70,28 @@ "withdraw_full": "Clicca per prelevare l'intero saldo", "withdraw_address": "Se non sei già in possesso di un indirizzo %(asset)s, per favore creane uno per completare il prelievo.", "memo_tip": "Puoi includere qualsiasi messaggio nel campo 'memo'. Il memo è facoltativo, ma in genere richiesto per i trasferimenti verso un exchange.", - "generate": "La password generata è stata creata localmente nel tuo browser.

Nessuno oltre a te ha accesso ad essa.

Incollala sotto e salvane una copia in un posto sicuro" + "generate": "La password generata è stata creata localmente nel tuo browser.

Nessuno oltre a te ha accesso ad essa.

Incollala sotto e salvane una copia in un posto sicuro", + "copy_password": "Clicca qui per copiare la password negli appunti", + "sync_yes": "Il nodo corrente è sincronizzato con la blockchain", + "sync_no": "Il nodo corrente non è sincronizzato con la blockchain, prova a passare a un altro", + "disconnected": "Non sei connesso a un nodo API, prova a ricaricare o a scegliere un nuovo punto di accesso nelle Impostazioni", + "market_fee": "Il proprietario di %(asset)s addebita una commissione di mercato del %(percent)s%% per gli ordini di acquisto. Questa commissione sarà dedotta dalla quantità che ricevi quando l'ordine è eseguito, e non è pagata quando l'ordine viene creato." }, "propose": "Proponi", "cancel": "Annulla", "account": { - "new_user": "Nuovo utgente?", + "new_user": "Nuovo utente?", "existing_user": "Utente esistente", - "intro_text_title": "Benvenuto nel BitShares DEX", - "intro_text_1": "L'exchange decentralizzato BitShares - chiamato anche Il DEX - è una piattaforma di ultima generazione per il trading di crisptovalute.", + "restore": "Ripristina", + "advanced": "Avanzate", + "intro_text_title": "Benvenuto su BitShares", + "intro_text_1": "Il tuo Exchange decentralizzato", "intro_text_2": "Il DEX è inerentemente decentralizzato, permettendoti la compravendita del token BitShares (BTS) e una varietà di asset trustless stabili nel prezzo e ancorati al mercato come bitUSD, bitCNY, bitBTC, bitGold e altri. È possibile fare trading di questi asset con zero rischio di controparte, permettendoti di mantenere il pieno controllo sui tuoi fondi.", "intro_text_3": "Il DEX permette anche la creazione di asset generati dagli utenti (user-issued assets, UIA), con cui si può fare trading con altri UIA o altri asset trustless sulla piattaforma. Un distributore molto noto sul DEX è OpenLedger, che offre una gamma di asset che include BTC, ETH, STEEM, DASH, LTC, DOGE e molti altri", "intro_text_4": "Ciò garantisce ai trader di criptovalute un unico mix di trading tradizionale e decentralizzato, il tutto con la familiare interfaccia di un exchange. Buon trading!", "in_open": "Questa è la quantità di %(asset)s che hai in ordini correntemente aperti.", "in_open_value": "Questo è il valore stimato di %(asset)s che hai in ordini correntemente aperti.", - "transfer_actions": "Movimenti", + "transfer_actions": "Trasferimenti", "market_actions": "Operazioni di mercato", "see_open": "Mostra ordini aperti", "total_estimate": "Questa è una stima del valore di tutti i tuoi asset, inclusi asset nascosti, ordini aperti, debito e garanzia. La stima è ottenuta usando informazioni in tempo reale dalla blockchain, e potrebbe non essere del tutto accurata.", @@ -102,8 +109,8 @@ "as_collateral": "Garanzia", "open_orders": "Ordini aperti", "total_value": "Valore totale", - "show_hidden": "Mostra asset nascosti", - "hide_hidden": "Nascondi asset nascosti", + "show_hidden": "Nascosti", + "hide_hidden": "Attivi", "ignore": "Nascondi", "unignore": "Mostra", "show_ignored": "Mostra account nascosti", @@ -123,7 +130,9 @@ "white_by": "Messo in whitelist da", "black_by": "Messo in blacklist da", "empty_white_by": "Nessun account ha messo %(account)s in whitelist.", - "empty_black_by": "Nessun account ha messo %(account)s in blacklist." + "empty_black_by": "Nessun account ha messo %(account)s in blacklist.", + "whitelist_authorities": "Autorità whitelist", + "blacklist_authorities": "Autorità blacklist" }, "vesting": { "title": "Saldi vesting", @@ -178,6 +187,7 @@ "approx_fee": "Commissione approssimativa", "exists": "Questo asset esiste sempre", "max_positive": "La disponibilità massima deve essere un numero positivo", + "too_large": "La disponibilità massima è eccessiva, per favore scegli un numero più piccolo", "core_exchange_rate": "Tasso di cambio centrale", "quote": "Quantità asset quotato", "quote_name": "Asset quotato", @@ -217,7 +227,9 @@ "error_invalid": "Quell'asset non può essere usato", "market": "Coppia di mercato preferita", "precision_warning": "Attenzione: Il numero di decimali non può essere modificato dopo la creazione", - "visible": "Nascondi asset in ricerca e mercati" + "visible": "Nascondi asset in ricerca e mercati", + "cer_warning_1": "Avviso", + "cer_warning_2": "Assicurati che il tuo core exchange rate sia maggiore del prezzo di mercato, altrimenti le persone compreranno il tuo token dal mercato e prosciugheranno il tuo fee pool tramite arbitraggio implicito. Il core exchange rate dovrebbe essere aggiornato regolarmente per riflettere il prezzo di mercato del tuo asset." }, "connections": { "known": "Conosciuto da", @@ -320,7 +332,13 @@ "toggle": "Cambia voto", "supported": "Supportato", "active_short": "Attivo", - "inactive": "Inattivo" + "inactive": "Backup", + "about": "Informazioni", + "create_worker": "Crea un nuovo worker", + "line": "Linea", + "save_finish": "Clicca Salva per completare", + "threshold": "Voti necesssari per l'attivazione", + "missing": "Necessari" }, "options": { "num_witnesses": "Numero desiderato di witness", @@ -331,6 +349,8 @@ "unfollow": "Non seguire", "follow": "Segui", "pay": "Invia a", + "deposit": "Deposita BTS", + "deposit_address": "Il tuo indirizzo di deposito è il nome del tuo account", "overview": "Panoramica", "home": "Home", "bts_market": "Mercato", @@ -352,7 +372,7 @@ "percent": "Percentuale della disponibilità totale", "please_create_account": "Per favore crea un account", "create_account": "Crea un account", - "create_new": "Create un nuovo account", + "create_new": "Crea un nuovo account", "password_login": "Login con password", "identicon": "Identicon", "pay_from": "Paga con l'account", @@ -366,7 +386,12 @@ "propose_from": "Proponi da", "settle": "Settle", "no_orders": "Nessun ordine aperto", - "asset_details": "Dettagli asset" + "asset_details": "Dettagli asset", + "portfolio": "Il mio Portfolio", + "activity": "Attività", + "eq_value_header": "Valore ({asset})", + "qty": "Qtà", + "total": "Totale ({asset})" }, "pagination": { "newer": "Più recenti", @@ -412,7 +437,8 @@ "proposal_create": "{account} ha creato una proposta di transazione", "proposal_update": "{account} ha aggiornato una proposta di transazione", "proposal_delete": "{account} ha rimosso una proposta di transazione", - "fill_order": "{account} ha acquistato {received} a {price}", + "fill_order_buy": "{account} ha acquistato {amount} per {price}", + "fill_order_sell": "{account} ha venduto {amount} per {price}", "vesting_balance_withdraw": "{account} ha ritirato un saldo vesting di {amount}", "balance_claim": "{account} ha riscosso un saldo di {amount}", "publish_feed": "{account} ha pubblicato un feed price di {price}", @@ -471,7 +497,8 @@ "asset_issue": "Emetti {amount} a {to} usando {account}", "asset_reserve": "Riserva (brucia) {amount} usando {account}", "vesting_balance_withdraw": "Preleva {amount} dal saldo vesting di {account}", - "feed_producer": "Aggiorna i produttori di feed per l'asset {asset} usando l'account {account}" + "feed_producer": "Aggiorna i produttori di feed per l'asset {asset} usando l'account {account}", + "call_order_update": "Cambia il debito {account} {debtSymbol} di {debt} e la garanzia di {collateral}" }, "transaction": { "confirm": "Per favore conferma la transazione", @@ -525,6 +552,7 @@ "deposit_to": "Depositato nell'account", "claimed": "Totale richiesto", "borrow_amount": "Debito", + "borrower": "Debitore", "funding_account": "Account sorgente", "delta_collateral": "Variazione garanzia", "delta_debt": "Variazione debito", @@ -674,7 +702,8 @@ "symbol": "Simbolo", "id": "ID", "issuer": "Erogatore", - "precision": "Precisione" + "precision": "Precisione", + "units": "Unità" }, "asset": { "title": "Asset", @@ -720,12 +749,22 @@ "maximum_short_squeeze_ratio": "MSSR", "publisher": "Publisher", "published": "Pubblicato" - } + }, + "margin_positions": { + "title": "Posizioni con margine" + }, + "whitelist": { + "whitelist_authorities": "Autorità whitelist", + "blacklist_authorities": "Autorita blacklist", + "whitelist_markets": "Whitelist mercato", + "blacklist_markets": "Blacklist mercato", + "enable_flag": "Il flag 'whitelist' deve essere abilitato per impostare le autorità whitelist" + } }, "witnesses": { "title": "Witness", "current": "Witness attuale", - "participation": "Tasso di participation", + "participation": "Tasso di partecipazione", "pay": "Paga-per-blocco", "budget": "Budget rimanente", "next_vote": "Prossimo aggiornamento dei voti", @@ -773,6 +812,8 @@ }, "settings": { "passwordLogin": "Fai il login usando il modalità account", + "cloud_login": "Login Portafoglio Cloud", + "local_wallet": "Login Portafoglio locale", "inverseMarket": "Preferenza orientazione del mercato", "unit": "Unità preferite per l'account", "confirmMarketOrder": "Chiedi conferma per gli ordini di mercato", @@ -837,7 +878,10 @@ "activate": "Attiva", "confirm_remove": "Sei sicuro di voler rimuovere %(name)s dalla lista dei nodi disponibili?", "valid_node_url": "L'URL del Nodo deve iniziare con ws:// oppure wss://", - "connection_error": "Impossibile connettersi con il nodo API node %(url)s; ripiegando su nodi funzionanti noti" + "connection_error": "Impossibile connettersi con il nodo API node %(url)s; ripiegando su nodi funzionanti noti", + "low_latency": "Bassa latenza", + "medium_latency": "Media latenza", + "high_latency": "Alta latenza" }, "footer": { "title": "BitShares", @@ -847,7 +891,10 @@ "nosync": "La blockchain non è sincronizzata, per favore attendi..", "connection": "Nessuna connessione alla Blockchain", "brainkey": "Raccomandato il backup della brainkey", - "update_available": "AGGIORNAMENTO DISPONIBILE" + "update_available": "AGGIORNAMENTO DISPONIBILE", + "synced": "Sincronizzato", + "unsynced": "Fuori sincrono", + "disconnected": "Disconnesso" }, "exchange": { "chart_options": { @@ -901,7 +948,7 @@ "base_supply": "Disponibilità valuta di base", "more": "Trova mercati", "volume_24": "Volume 24h", - "change": "Cambia", + "change": "Variazione", "confirm_buy": "Il tuo ordine è %(diff)s volte più alto dell'offerta più bassa, sei sicuro?", "confirm_sell": "Il tuo ordine è %(diff)s volte più basso della domanda più alta, sei sicuro?", "confirm_no_orders_buy": "Stai facendo un ordine di acquisto in un mercato senza ordini di vendita attivi. Sei sicuro di voler continuare?", @@ -943,7 +990,8 @@ "show_star_1": "Mostra", "show_star_2": "solo", "base": "Valuta di base:", - "search": "Cerca qui altri mercati" + "search": "Cerca qui altri mercati", + "order_value": "Valore ordine" }, "fees": { "title": "Elenco commissioni" @@ -967,7 +1015,7 @@ "change_wallet": "Cambia portafoglio", "wallet_created": "Portafoglio creato", "create_wallet": "Crea nuovo portafoglio", - "create_importkeys_text": "Per importare le chiavi, devi prima create un portafoglio per contenerle. Completa la finestra di dialogo sotto per creare un nuovo portafoglio.", + "create_importkeys_text": "Per importare le chiavi, devi prima creare un portafoglio per contenerle. Completa la finestra di dialogo sotto per creare un nuovo portafoglio.", "create_wallet_backup": "Crea nuovo portafoglio da un backup", "import_bts1": "Importa da BitShares 0.9.3c", "setup_wallet": "Configura il tuo portafoglio", @@ -1115,9 +1163,12 @@ "current_pass": "Password attuale", "no_wallet": "Non hai ancora un portafoglio", "generated": "Password generata", + "account_exp": "Questo account sarà creato nella blockchain e sarà il tuo indirizzo per ogni trasferimento tu voglia effettuare! Non ci sono lunghi indirizzi stile Bitcoin su BitShares!", "understand_1": "Ho capito che non potrò recuperare la mia password se la perdo o me ne dimentico", "understand_2": "L'ho messa per iscritto o salvato in altro modo la mia password", - "bts_rules": "La prima regola di BitShares è: Non perdere la tua password.
La seconda regola di BitShares è: Non perdere la tua password.
La terza regola di BitShares è: Non possiamo recuperare la tua password.
La quarta regola: Se puoi ricordare la tua password, allora non è sicura.
La quinta regola: Usa solo password generate a caso.
La sesta regola: Non dire a nessuno la tua password.
La settima regola: Fai sempre il backup della tua password." + "understand_3": "Ho capito che perderò l'accesso ai miei fondi se perdo la mia password", + "bts_rules": "La prima regola di BitShares è: Non perdere la tua password.
La seconda regola di BitShares è: Non perdere la tua password.
La terza regola di BitShares è: Non possiamo recuperare la tua password.
La quarta regola: Se puoi ricordare la tua password, allora non è sicura.
La quinta regola: Usa solo password generate a caso.
La sesta regola: Non dire a nessuno la tua password.
La settima regola: Fai sempre il backup della tua password.", + "ok_done": "OK, portami alla dashboard" }, "borrow": { "title": "%(asset_symbol)s con margine", @@ -1125,6 +1176,7 @@ "coll_ratio": "Collateral ratio", "call_limit": "Market Call Limit", "adjust": "Aggiorna posizione", + "adjust_short": "Aggiorna", "close": "Chiudi posizione", "update": "Aggiorna", "errors": { @@ -1175,7 +1227,12 @@ "key_approval_add": "Approvazione chiave da aggiungere", "key_approval_remove": "Approvazione chiave da rimuovere" }, - "ok": "OK" + "ok": "OK", + "qrcode":{ + "label":"qrcode", + "title":"Codice QR della chiave privata", + "input_message":"Inserisci una password usata per crittografare il codice QR.
Una password vuota mostrerà un codice QR in chiaro." + } }, "init_error": { "title": "Problemi nell'inizializzazione dell'applicazione", @@ -1263,7 +1320,18 @@ "purchase": "Acquista %(asset)s", "purchase_1": "Acquista %(outputAsset)s rapidamente e facilmente usando %(inputAsset)s da un portafoglio esterno. Questo servizio è fornito da Blocktrades", "deposit_limit": "Limite di deposito", - "address_with_memo": "%(address)s con memo %(memo)s" + "address_with_memo": "%(address)s con memo %(memo)s", + "rudex": { + "support_block": "Per supporto, contatta RuDEX a:", + "min_amount": "Quantità minima: %(minAmount)s %(symbol)s", + "min_amount_error": "Per favore inserisci un numero >= minimo", + "coming_soon": "Prossimamente" + }, + "unavailable": "Il servizio di gateway per questo asset non è al momento disponibile, riprova più tardi", + "unavailable_bridge": "Il servizio di bridge per questo asset non è al momento disponibile, riprova più tardi", + "unavailable_OPEN": "Il Gateway OpenLedger non è disponibile o non risponde", + "unavailable_RUDEX": "Il Gateway RuDEX non è disponibile o non risponde", + "unavailable_TRADE": "Il Bridge Blocktrades non è disponibile o non risponde" }, "trx_error": { "expire": "La tua transazione è scaduta senza essere stata confermata; per favore riprova più tardi." diff --git a/app/assets/stylesheets/base/_fonts.scss b/app/assets/stylesheets/base/_fonts.scss index e6e1f047d4..1009e3a1bc 100644 --- a/app/assets/stylesheets/base/_fonts.scss +++ b/app/assets/stylesheets/base/_fonts.scss @@ -118,8 +118,14 @@ button, .button { @include RobotoCondensed; } -.table.dashboard-table > thead > tr > th { - @include RobotoRegular; +.table.dashboard-table { + > thead > tr > th { + @include RobotoRegular; + } + + > tbody > tr > td { + @include RobotoCondensed; + } } // .key-value-table tr > td:first-child { diff --git a/app/assets/stylesheets/components/_account.scss b/app/assets/stylesheets/components/_account.scss index 3a38c529a7..4e899334f5 100755 --- a/app/assets/stylesheets/components/_account.scss +++ b/app/assets/stylesheets/components/_account.scss @@ -231,10 +231,17 @@ table.table.dashboard-table { border: 1px solid; &.worker-name { - max-width: 8rem; + max-width: 15rem; overflow-x: hidden; white-space: nowrap; text-overflow: ellipsis; + > div span.icon > svg { + width: 1.75rem; + height: 1.75rem; + } + > div > a { + font-size: 90%; + } } } &.total-value { diff --git a/app/assets/stylesheets/themes/_theme-template.scss b/app/assets/stylesheets/themes/_theme-template.scss index 60a7d88dd5..146fd9e355 100644 --- a/app/assets/stylesheets/themes/_theme-template.scss +++ b/app/assets/stylesheets/themes/_theme-template.scss @@ -1258,9 +1258,12 @@ $account-background color: $account-green; } } - &.is-active > a { - color: $account-primarytext; - background-color: $account-header; + &.is-active { + background-color: lighten($account-header, 4%); + > a { + color: $account-primarytext; + background-color: lighten($account-header, 4%); + } } &.total-value { > a { @@ -1353,8 +1356,8 @@ $account-background } .olDarkTheme .gate_fee .amount-selector { - width: 74%; - display: inline-block; + width: 100%; + display: inline-block; } .olDarkTheme .gate_fee .right-selector { diff --git a/app/components/Account/AccountOverview.jsx b/app/components/Account/AccountOverview.jsx index 082f88a758..fe235b2b5b 100644 --- a/app/components/Account/AccountOverview.jsx +++ b/app/components/Account/AccountOverview.jsx @@ -239,7 +239,7 @@ class AccountOverview extends React.Component { balances.push( - + @@ -344,7 +344,7 @@ class AccountOverview extends React.Component { let {isBitAsset, borrowModal, borrowLink} = renderBorrow(asset, this.props.account); if (includeAsset && visible || !includeAsset && !visible) balances.push( - + @@ -530,7 +530,7 @@ class AccountOverview extends React.Component { ]} />; - includedBalances.push({totalValueText}{portFolioValue}); + includedBalances.push({totalValueText}{portFolioValue}); let showAssetPercent = settings.get("showAssetPercent", false); @@ -575,7 +575,7 @@ class AccountOverview extends React.Component { {/**/} - + () {/*<*/} diff --git a/app/components/Account/AccountVoting.jsx b/app/components/Account/AccountVoting.jsx index b38f021ed2..413a67fae1 100644 --- a/app/components/Account/AccountVoting.jsx +++ b/app/components/Account/AccountVoting.jsx @@ -427,8 +427,8 @@ class AccountVoting extends React.Component { } return ( - new Date(a.get("work_end_date")) > now && - new Date(a.get("work_begin_date")) <= now + new Date(a.get("work_end_date") + "Z") > now && + new Date(a.get("work_begin_date") + "Z") <= now ); }) @@ -469,10 +469,10 @@ class AccountVoting extends React.Component { } let votes = a.get("total_votes_for") - a.get("total_votes_against"); - return ( - new Date(a.get("work_end_date")) >= now && - votes < voteThreshold + (new Date(a.get("work_end_date")+ "Z") > now && + votes < voteThreshold) || + new Date(a.get("work_begin_date")+ "Z") > now ); }) @@ -700,7 +700,7 @@ class AccountVoting extends React.Component { () - + {globalObject ? : null} @@ -714,7 +714,6 @@ class AccountVoting extends React.Component { {workerTableIndex === 2 ? null : } - diff --git a/app/components/Account/CreateAccount.jsx b/app/components/Account/CreateAccount.jsx index 2d6c4b3528..8f9a5aca77 100644 --- a/app/components/Account/CreateAccount.jsx +++ b/app/components/Account/CreateAccount.jsx @@ -83,7 +83,7 @@ class CreateAccount extends React.Component { TransactionConfirmStore.unlisten(this.onFinishConfirm); TransactionConfirmStore.reset(); - FetchChain("getAccount", this.state.accountName).then(() => { + FetchChain("getAccount", this.state.accountName, undefined, {[this.state.accountName]: true}).then(() => { console.log("onFinishConfirm"); this.props.router.push("/wallet/backup/create?newAccount=true"); }); @@ -99,7 +99,7 @@ class CreateAccount extends React.Component { AccountActions.createAccount(name, this.state.registrar_account, referralAccount || this.state.registrar_account, 0, refcode).then(() => { // User registering his own account if(this.state.registrar_account) { - FetchChain("getAccount", name).then(() => { + FetchChain("getAccount", name, undefined, {[name]: true}).then(() => { this.setState({ step: 2, loading: false @@ -107,13 +107,12 @@ class CreateAccount extends React.Component { }); TransactionConfirmStore.listen(this.onFinishConfirm); } else { // Account registered by the faucet - // this.props.router.push(`/wallet/backup/create?newAccount=true`); - FetchChain("getAccount", name).then(() => { + FetchChain("getAccount", name, undefined, {[name]: true}).then(() => { this.setState({ - step: 2 + step: 2, + loading: false }); }); - // this.props.router.push(`/account/${name}/overview`); } }).catch(error => { @@ -367,7 +366,7 @@ class CreateAccount extends React.Component { render() { let {step} = this.state; - + return (
diff --git a/app/components/Account/CreateAccountPassword.jsx b/app/components/Account/CreateAccountPassword.jsx index bd6b8f55dd..c6bbef5608 100644 --- a/app/components/Account/CreateAccountPassword.jsx +++ b/app/components/Account/CreateAccountPassword.jsx @@ -88,8 +88,7 @@ class CreateAccountPassword extends React.Component { TransactionConfirmStore.unlisten(this.onFinishConfirm); TransactionConfirmStore.reset(); - FetchChain("getAccount", this.state.accountName).then(() => { - console.log("onFinishConfirm"); + FetchChain("getAccount", this.state.accountName, undefined, {[this.state.accountName]: true}).then(() => { this.props.router.push("/wallet/backup/create?newAccount=true"); }); } @@ -109,7 +108,7 @@ class CreateAccountPassword extends React.Component { AccountActions.setPasswordAccount(name); // User registering his own account if(this.state.registrar_account) { - FetchChain("getAccount", name).then(() => { + FetchChain("getAccount", name, undefined, {[name]: true}).then(() => { this.setState({ step: 2, loading: false @@ -118,14 +117,12 @@ class CreateAccountPassword extends React.Component { }); TransactionConfirmStore.listen(this.onFinishConfirm); } else { // Account registered by the faucet - // this.props.router.push(`/wallet/backup/create?newAccount=true`); - FetchChain("getAccount", name).then(() => { + FetchChain("getAccount", name, undefined, {[name]: true}).then(() => { this.setState({ step: 2 }); + this._unlockAccount(name, password); }); - this._unlockAccount(name, password); - // this.props.router.push(`/account/${name}/overview`); } }).catch(error => { diff --git a/app/components/Account/WorkerApproval.jsx b/app/components/Account/WorkerApproval.jsx index 672208ccb2..8a12cfe2ad 100644 --- a/app/components/Account/WorkerApproval.jsx +++ b/app/components/Account/WorkerApproval.jsx @@ -69,39 +69,38 @@ class WorkerApproval extends React.Component{ fundedPercent = this.props.rest / worker.daily_pay * 100; } - let startDate = counterpart.localize(new Date(worker.work_begin_date), { type: "date", format: "short_custom" }); - let endDate = counterpart.localize(new Date(worker.work_end_date), { type: "date", format: "short_custom" }); + let startDate = counterpart.localize(new Date(worker.work_begin_date + "Z"), { type: "date", format: "short_custom" }); + let endDate = counterpart.localize(new Date(worker.work_end_date + "Z"), { type: "date", format: "short_custom" }); let now = new Date(); - let isExpired = new Date(worker.work_end_date) <= now; - let isProposed = !isExpired && total_votes < this.props.voteThreshold; + let isExpired = new Date(worker.work_end_date + "Z") <= now; + let hasStarted = new Date(worker.work_begin_date + "Z") <= now; + let isProposed = (!isExpired && total_votes < this.props.voteThreshold) || !hasStarted; return ( {isExpired ? null : {rank}} -
+
{worker.name} +
+
- - - - {!isProposed ? null : - + } diff --git a/app/components/Dashboard/DashboardList.jsx b/app/components/Dashboard/DashboardList.jsx index fb3afee065..65570b1d05 100644 --- a/app/components/Dashboard/DashboardList.jsx +++ b/app/components/Dashboard/DashboardList.jsx @@ -201,7 +201,7 @@ class DashboardList extends React.Component { - + {accountName} @@ -246,7 +246,7 @@ class DashboardList extends React.Component { - + {width >= 750 ? : null} {width >= 1200 ? : null} diff --git a/app/components/Dashboard/SimpleDepositWithdraw.jsx b/app/components/Dashboard/SimpleDepositWithdraw.jsx index ffc6c64194..e129abe893 100644 --- a/app/components/Dashboard/SimpleDepositWithdraw.jsx +++ b/app/components/Dashboard/SimpleDepositWithdraw.jsx @@ -19,6 +19,7 @@ import AssetName from "../Utility/AssetName"; import { ChainStore } from "bitsharesjs/es"; import { debounce } from "lodash"; import {DecimalChecker} from "../Exchange/ExchangeInput"; +import { blockTradesAPIs } from "api/apiConfig"; // import DepositFiatOpenLedger from "components/DepositWithdraw/openledger/DepositFiatOpenLedger"; // import WithdrawFiatOpenLedger from "components/DepositWithdraw/openledger/WithdrawFiatOpenLedger"; @@ -39,13 +40,12 @@ class DepositWithdrawContent extends DecimalChecker { constructor(props) { super(); + console.log("constructor"); this.state = { toAddress: WithdrawAddresses.getLast(props.walletType), withdrawValue:"", amountError: null, symbol:props.asset.get("symbol"), - intermediateAccount: props.asset.get("intermediateAccount"), - gateFee: props.asset.get("gateFee"), to_withdraw: new Asset({ asset_id: props.asset.get("id"), precision: props.asset.get("precision") @@ -73,7 +73,7 @@ class DepositWithdrawContent extends DecimalChecker { } componentWillReceiveProps(np) { - if (np.asset && np.asset !== this.props.asset) { + if ((np.asset && this.props.asset) && np.asset.get("id") !== this.props.asset.get("id")) { this.setState({ to_withdraw: new Asset({ asset_id: np.asset.get("id"), @@ -146,7 +146,21 @@ class DepositWithdrawContent extends DecimalChecker { if (!this.props.intermediateAccount) return; - let fee = this._getFee(); + const fee = this._getFee(); + const gateFee = this._getGateFee(); + + let sendAmount = this.state.to_withdraw.clone(); + + let balanceAmount = sendAmount.clone(this._getCurrentBalance().get("balance")); + + sendAmount.plus(gateFee); + + /* Insufficient balance */ + if (balanceAmount.lt(sendAmount)) { + // Send the originally entered amount + sendAmount = this.state.to_withdraw.clone(); + } + AccountActions.transfer( this.props.sender.get("id"), this.props.intermediateAccount, @@ -244,9 +258,11 @@ class DepositWithdrawContent extends DecimalChecker { const {asset} = this.props; const balance = this._getCurrentBalance(); if (!balance || !feeAmount) return; - const hasBalance = checkBalance(to_withdraw.getAmount({real: true}), asset, feeAmount, balance); + const hasBalance = checkBalance(to_withdraw.getAmount({real: true}), asset, this._getFee(), balance, this._getGateFee()); if (hasBalance === null) return; - this.setState({balanceError: !hasBalance}); + if (this.state.balanceError !== !hasBalance) + this.setState({balanceError: !hasBalance}); + return hasBalance; } @@ -257,7 +273,9 @@ class DepositWithdrawContent extends DecimalChecker { const coreStatus = this.state.feeStatus["1.3.0"]; const withdrawAssetStatus = this.state.feeStatus[this.state.to_withdraw.asset_id]; + // Use core asset to pay the fees if present and balance is sufficient since it's cheapest if (coreStatus && coreStatus.hasBalance) return coreStatus.fee; + // Use same asset as withdraw if not if (coreStatus && !coreStatus.hasBalance && withdrawAssetStatus && withdrawAssetStatus.hasBalance) { return withdrawAssetStatus.fee; } @@ -296,12 +314,12 @@ class DepositWithdrawContent extends DecimalChecker { } _validateAddress(address, props = this.props) { - validateAddress({walletType: props.walletType, newAddress: address}) + validateAddress({url: blockTradesAPIs.BASE_OL, walletType: props.walletType, newAddress: address}) .then(isValid => { if (this.state.toAddress === address) { this.setState({ withdraw_address_check_in_progress: false, - validAddress: isValid + validAddress: !!isValid }); } }).catch(err => { @@ -315,6 +333,15 @@ class DepositWithdrawContent extends DecimalChecker { newWnd.opener = null; } + _getGateFee() { + const {gateFee, asset} = this.props; + return new Asset({ + real: parseFloat(gateFee ? gateFee.replace(",", "") : 0), + asset_id: asset.get("id"), + precision: asset.get("precision") + }); + } + _renderWithdraw() { const {amountError} = this.state; const {name: assetName} = utils.replaceName(this.props.asset.get("symbol"), !!this.props.asset.get("bitasset")); @@ -336,9 +363,16 @@ class DepositWithdrawContent extends DecimalChecker { // } const currentFee = this._getFee(); + const gateFee = this._getGateFee(); const feeStatus = this.state.feeStatus[currentFee.asset_id]; const feeAsset = ChainStore.getAsset(currentFee.asset_id); + const disableSubmit = + (feeStatus && !feeStatus.hasBalance) || + this.state.balanceError || + !this.state.toAddress || + !this.state.withdrawValue; + return (

@@ -380,6 +414,20 @@ class DepositWithdrawContent extends DecimalChecker { {feeStatus && !feeStatus.hasBalance ?

:null}
+
+ +
+ + +
+
+
+
+
+
+ {feeStatus && !feeStatus.hasBalance ?

:null} +
+
@@ -407,7 +455,7 @@ class DepositWithdrawContent extends DecimalChecker { ) : null}
-
diff --git a/app/components/DepositWithdraw/WithdrawModal.jsx b/app/components/DepositWithdraw/WithdrawModal.jsx index ea2857f1aa..947b6f233d 100644 --- a/app/components/DepositWithdraw/WithdrawModal.jsx +++ b/app/components/DepositWithdraw/WithdrawModal.jsx @@ -11,64 +11,62 @@ import AccountActions from "actions/AccountActions"; class WithdrawModal extends React.Component { - static propTypes = { - account: ChainTypes.ChainAccount.isRequired, - issuer: ChainTypes.ChainAccount.isRequired, - asset: ChainTypes.ChainAsset.isRequired, - receive_asset_name: React.PropTypes.string, - receive_asset_symbol: React.PropTypes.string, - memo_prefix: React.PropTypes.string - } + static propTypes = { + account: ChainTypes.ChainAccount.isRequired, + issuer: ChainTypes.ChainAccount.isRequired, + asset: ChainTypes.ChainAsset.isRequired, + receive_asset_name: React.PropTypes.string, + receive_asset_symbol: React.PropTypes.string, + memo_prefix: React.PropTypes.string + } - constructor( props ) { - super(props); - this.state = { - withdraw_amount:null, - withdraw_address:null - } - } + constructor( props ) { + super(props); + this.state = { + withdraw_amount:null, + withdraw_address:null + }; + } - onWithdrawAmountChange( {amount, asset} ) { - this.setState( {withdraw_amount:amount} ); - } + onWithdrawAmountChange( {amount} ) { + this.setState( {withdraw_amount:amount} ); + } - onWithdrawAddressChanged( e ) { - this.setState( {withdraw_address:e.target.value} ); - } + onWithdrawAddressChanged( e ) { + this.setState( {withdraw_address:e.target.value} ); + } - onSubmit() { - let asset = this.props.asset; - let precision = utils.get_asset_precision(asset.get("precision")); - let amount = this.state.withdraw_amount.replace( /,/g, "" ) - console.log( "withdraw_amount: ", amount ); - AccountActions.transfer( - this.props.account.get("id"), - this.props.issuer.get("id"), - parseInt(amount * precision, 10), - asset.get("id"), - (this.props.memo_prefix || "") + this.state.withdraw_address - ) - } + onSubmit() { + let asset = this.props.asset; + let precision = utils.get_asset_precision(asset.get("precision")); + let amount = this.state.withdraw_amount.replace( /,/g, "" ); + AccountActions.transfer( + this.props.account.get("id"), + this.props.issuer.get("id"), + parseInt(amount * precision, 10), + asset.get("id"), + (this.props.memo_prefix || "") + this.state.withdraw_address + ); + } - render() { - let balance = null; - // console.log( "account: ", this.props.account.toJS() ); - let account_balances = this.props.account.get("balances").toJS(); - // console.log( "balances: ", account_balances ); - let asset_types = Object.keys(account_balances); + render() { + let balance = null; + // console.log( "account: ", this.props.account.toJS() ); + let account_balances = this.props.account.get("balances").toJS(); + // console.log( "balances: ", account_balances ); + let asset_types = Object.keys(account_balances); - if (asset_types.length > 0) { - let current_asset_id = this.props.asset.get('id'); - if( current_asset_id ) - balance = (: ) - else - balance = "No funds"; - } else { - balance = "No funds"; - } + if (asset_types.length > 0) { + let current_asset_id = this.props.asset.get("id"); + if( current_asset_id ) + balance = (: ); + else + balance = "No funds"; + } else { + balance = "No funds"; + } - - return (
+ return (

Withdraw {this.props.receive_asset_name}({this.props.receive_asset_symbol})

@@ -76,8 +74,8 @@ class WithdrawModal extends React.Component {
- ) - } + ); + } }; diff --git a/app/components/DepositWithdraw/blocktrades/WithdrawModalBlocktrades.jsx b/app/components/DepositWithdraw/blocktrades/WithdrawModalBlocktrades.jsx index 1ae5f5bd13..4bdd92bb02 100644 --- a/app/components/DepositWithdraw/blocktrades/WithdrawModalBlocktrades.jsx +++ b/app/components/DepositWithdraw/blocktrades/WithdrawModalBlocktrades.jsx @@ -10,7 +10,6 @@ import AmountSelector from "components/Utility/AmountSelector"; import AccountActions from "actions/AccountActions"; import ZfApi from "react-foundation-apps/src/utils/foundation-api"; import { validateAddress, WithdrawAddresses } from "common/blockTradesMethods"; -import AccountStore from "stores/AccountStore"; import {ChainStore} from "bitsharesjs/es"; import Modal from "react-foundation-apps/src/modal"; import { checkFeeStatusAsync, checkBalance } from "common/trxHelper"; @@ -202,7 +201,6 @@ class WithdrawModalBlocktrades extends React.Component { } onSubmit() { - if ((!this.state.withdraw_address_check_in_progress) && (this.state.withdraw_address && this.state.withdraw_address.length) && (this.state.withdraw_amount !== null)) { if (!this.state.withdraw_address_is_valid) { ZfApi.publish(this.getWithdrawModalId(), "open"); @@ -223,13 +221,30 @@ class WithdrawModalBlocktrades extends React.Component { const {feeAmount} = this.state; - let amount = parseFloat(String.prototype.replace.call(this.state.withdraw_amount, /,/g, "")); + const amount = parseFloat(String.prototype.replace.call(this.state.withdraw_amount, /,/g, "")); + const gateFee = parseFloat(String.prototype.replace.call(this.props.gateFee, /,/g, "")); + let sendAmount = new Asset({ asset_id: asset.get("id"), precision: asset.get("precision"), real: amount }); + let balanceAmount = sendAmount.clone(this.props.balance.get("balance")); + + const gateFeeAmount = new Asset({ + asset_id: asset.get("id"), + precision: asset.get("precision"), + real: gateFee + }); + + sendAmount.plus(gateFeeAmount); + + /* Insufficient balance */ + if (balanceAmount.lt(sendAmount)) { + sendAmount = balanceAmount; + } + AccountActions.transfer( this.props.account.get("id"), this.props.issuer.get("id"), @@ -460,6 +475,11 @@ class WithdrawModalBlocktrades extends React.Component { balance = "No funds"; } + const disableSubmit = + this.state.error || + this.state.balanceError || + !this.state.withdraw_amount; + return (
@@ -532,7 +552,7 @@ class WithdrawModalBlocktrades extends React.Component { {/* Withdraw/Cancel buttons */}
-
+
diff --git a/app/components/Exchange/BuySell.jsx b/app/components/Exchange/BuySell.jsx index c6711a7e0e..89519c954b 100644 --- a/app/components/Exchange/BuySell.jsx +++ b/app/components/Exchange/BuySell.jsx @@ -168,7 +168,6 @@ class BuySell extends React.Component { // } const isBid = type === "bid"; let marketFee = isBid && quoteMarketFee ? quoteMarketFee : !isBid && baseMarketFee ? baseMarketFee : null; - console.log("isBid", isBid, "quoteMarketFee", !!quoteMarketFee, "baseMarketFee", !!baseMarketFee); let hasBalance = isBid ? balanceAmount.getAmount({real: true}) >= parseFloat(total) : balanceAmount.getAmount({real: true}) >= parseFloat(amount); let buttonText = isPredictionMarket ? counterpart.translate("exchange.short") : isBid ? counterpart.translate("exchange.buy") : counterpart.translate("exchange.sell"); diff --git a/app/components/Exchange/MarketHistory.jsx b/app/components/Exchange/MarketHistory.jsx index 3aba6a2198..dc80e7f888 100644 --- a/app/components/Exchange/MarketHistory.jsx +++ b/app/components/Exchange/MarketHistory.jsx @@ -1,9 +1,7 @@ import React from "react"; import {PropTypes} from "react"; -import {Link} from "react-router/es"; import Immutable from "immutable"; import Ps from "perfect-scrollbar"; -import utils from "common/utils"; import Translate from "react-translate-component"; import market_utils from "common/market_utils"; import PriceText from "../Utility/PriceText"; @@ -15,6 +13,10 @@ import TransitionWrapper from "../Utility/TransitionWrapper"; import AssetName from "../Utility/AssetName"; import { ChainTypes as grapheneChainTypes } from "bitsharesjs/es"; const {operations} = grapheneChainTypes; +import BlockDate from "../Utility/BlockDate"; +import counterpart from "counterpart"; +import ReactTooltip from "react-tooltip"; +import getLocale from "browser-locale"; class MarketHistory extends React.Component { constructor(props) { @@ -57,10 +59,12 @@ class MarketHistory extends React.Component { let historyNode = this.refs.history; historyNode.scrollTop = 0; Ps.update(historyNode); + + setTimeout(ReactTooltip.rebuild, 1000); } render() { - let {history, myHistory, base, quote, baseSymbol, quoteSymbol, flipped, isNullAccount} = this.props; + let {history, myHistory, base, quote, baseSymbol, quoteSymbol, isNullAccount} = this.props; let {activeTab} = this.state; let historyRows = null; @@ -69,7 +73,6 @@ class MarketHistory extends React.Component { } if (activeTab === "my_history" && (myHistory && myHistory.size)) { - let index = 0; let keyIndex = -1; let flipped = base.get("id").split(".")[2] > quote.get("id").split(".")[2]; historyRows = myHistory.filter(a => { @@ -110,7 +113,7 @@ class MarketHistory extends React.Component { {parsed_order.receives} {parsed_order.pays} - #{utils.format_number(block_num, 0)} + ); }).toArray(); @@ -119,7 +122,7 @@ class MarketHistory extends React.Component { let keyIndex = -1; let flipped = base.get("id").split(".")[2] > quote.get("id").split(".")[2]; historyRows = this.props.history - .filter(a => { + .filter(() => { index++; return index % 2 === 0; }) @@ -136,7 +139,6 @@ class MarketHistory extends React.Component { paysAsset = quote; receivesAsset = base; } - let parsed_order = market_utils.parse_order_history(order, paysAsset, receivesAsset, isAsk, flipped); return ( @@ -145,7 +147,9 @@ class MarketHistory extends React.Component { {parsed_order.receives} {parsed_order.pays} - {parsed_order.time} + + {counterpart.localize(new Date(order.time), {type: "date", format: getLocale().toLowerCase().indexOf("en-us") !== -1 ? "market_history_us": "market_history"})} + ); }).toArray(); @@ -173,7 +177,7 @@ class MarketHistory extends React.Component { - + diff --git a/app/components/Utility/BlockDate.jsx b/app/components/Utility/BlockDate.jsx new file mode 100644 index 0000000000..d3399a6403 --- /dev/null +++ b/app/components/Utility/BlockDate.jsx @@ -0,0 +1,57 @@ +import React from "react"; +import counterpart from "counterpart"; +import {connect} from "alt-react"; +import BlockchainStore from "stores/BlockchainStore"; +import BlockchainActions from "actions/BlockchainActions"; +import ReactTooltip from "react-tooltip"; +import getLocale from "browser-locale"; + +/** + * @brief displays block's date and time based on block number + * + * properties: block - number + * Note, it doesn't fetch block, just calculates time based on number alone. + **/ + +class BlockDate extends React.Component { + + static defaultProps = { + format: getLocale().toLowerCase().indexOf("en-us") !== -1 ? "market_history_us": "market_history", + tooltip: false, + component: "span" + } + + componentWillMount() { + BlockchainActions.getBlock.defer(this.props.block_number); + } + + shouldComponentUpdate(np) { + if (np.block && !this.props.block) setTimeout(ReactTooltip.rebuild, 1000); + return np.block !== this.props.block; + } + + render() { + const {block, tooltip, component, format} = this.props; + if (!block) return React.createElement(component); + return ( + React.createElement(component, {className: tooltip ? "tooltip": "", "data-tip": tooltip ? block.timestamp : ""}, + + {counterpart.localize(block.timestamp, {type: "date", format})} + + ) + ); + } +} + +BlockDate = connect(BlockDate, { + listenTo() { + return [BlockchainStore]; + }, + getProps(props) { + return { + block: BlockchainStore.getState().blocks.get(props.block_number) + }; + } +}); + +export default BlockDate; diff --git a/app/lib/common/MarketClasses.js b/app/lib/common/MarketClasses.js index eb2e1b0744..ff1e3329f6 100644 --- a/app/lib/common/MarketClasses.js +++ b/app/lib/common/MarketClasses.js @@ -48,7 +48,8 @@ class Asset { } toSats(amount = 1) { // Return the full integer amount in 'satoshis' - return Math.floor(amount * this.satoshi); + // Round to prevent floating point math errors + return Math.round(amount * this.satoshi); } setAmount({sats, real}) { diff --git a/app/stores/BlockchainStore.js b/app/stores/BlockchainStore.js index 7d0807aeb6..179da373e5 100644 --- a/app/stores/BlockchainStore.js +++ b/app/stores/BlockchainStore.js @@ -2,11 +2,7 @@ import Immutable from "immutable"; import alt from "alt-instance"; import BlockchainActions from "actions/BlockchainActions"; import {ChainStore} from "bitsharesjs/es"; - -import { - Block -} - from "./tcomb_structs"; +import {Block} from "./tcomb_structs"; class BlockchainStore { constructor() { @@ -29,7 +25,7 @@ class BlockchainStore { onGetBlock(block) { if (!this.blocks.get(block.id)) { if (!/Z$/.test(block.timestamp)) { - block.timestamp += 'Z'; + block.timestamp += "Z"; } block.timestamp = new Date(block.timestamp); this.blocks = this.blocks.set( @@ -43,6 +39,9 @@ class BlockchainStore { let {block, maxBlock} = payload; if (typeof block.timestamp === "string") { block.timestamp += "+00:00"; + if (!/Z$/.test(block.timestamp)) { + block.timestamp += "Z"; + } } block.timestamp = new Date(block.timestamp); if (block.id > maxBlock - this.maxBlocks) { diff --git a/app/stores/MarketsStore.js b/app/stores/MarketsStore.js index 4b2e9c3f97..03fd0a3f1c 100644 --- a/app/stores/MarketsStore.js +++ b/app/stores/MarketsStore.js @@ -298,6 +298,9 @@ class MarketsStore { if (result.history) { this.activeMarketHistory = this.activeMarketHistory.clear(); result.history.forEach(order => { + if (!/Z$/.test(order.time)) { + order.time += "Z"; + } order.op.time = order.time; /* Only include history objects that aren't 'something for nothing' to avoid confusion */ if (!(order.op.receives.amount == 0 || order.op.pays.amount == 0)) { @@ -963,7 +966,7 @@ class MarketsStore { first = history[0]; } last = history[history.length -1]; - /* Some market histories have 0 value for price values, set to 1 in that case */ + /* Some market histories have 0 value for price values, set to 1 in that case */ function removeZeros(entry) { for (let key in entry) { if (key.indexOf("volume") === -1 && entry[key] === 0) { diff --git a/app/test/marketTests.js b/app/test/marketTests.js index 44d170c784..e8fdd29e86 100644 --- a/app/test/marketTests.js +++ b/app/test/marketTests.js @@ -52,6 +52,11 @@ describe("Asset", function() { assert.equal(asset.asset_id, "1.3.0", "Asset should be 1.3.0"); assert.equal(asset.amount, 100000, "Amount should be 242"); assert.equal(asset.satoshi, 100000, "Satoshi should be 10000"); + + let asset2 = new Asset({asset_id: "1.3.861", real: "0.00030", precision: 8}); + assert.equal(asset2.asset_id, "1.3.861", "Asset should be 1.3.861"); + assert.equal(asset2.amount, 30000, "Amount should be 30000"); + assert.equal(asset2.satoshi, 100000000, "Satoshi should be 100000000"); }); it("Can be added", function() { diff --git a/deploy.sh b/deploy.sh index bd472be0a0..cc92594634 100755 --- a/deploy.sh +++ b/deploy.sh @@ -23,18 +23,16 @@ then # Commit Changes ################ - echo "Pushing new wallet repo" + echo "Pushing new wallet folder" cd $TRAVIS_BUILD_DIR/bitshares.org #git config user.email "travis@bitshares.org" #git config user.name "BitShares Wallet Build Automation" git add -A git commit -a -m "Update wallet by Travis: v$TRAVIS_TAG" - - # Push Changes - ############## git push ## wallet.bitshares.org subdomain (independent repo) + echo "Pushing new wallet subdomain repo" git clone https://github.com:${GITHUB_TOKEN}@github.com/${WALLET_REPO} $TRAVIS_BUILD_DIR/wallet.bitshares.org cd $TRAVIS_BUILD_DIR/wallet.bitshares.org git checkout gh-pages @@ -43,4 +41,5 @@ then cp -Rv $TRAVIS_BUILD_DIR/build/hash-history_/* . git add -A git commit -a -m "Update wallet by Travis: v$TRAVIS_TAG" + git push fi diff --git a/package.json b/package.json index 1435deff13..964cb75c42 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "BitShares2-light", - "version": "2.0.171031", + "version": "2.0.171101", "description": "Advanced wallet interface for the BitShares financial blockchain.", "homepage": "https://github.com/bitshares/bitshares-ui", "author": "Sigve Kvalsvik ", @@ -127,6 +127,7 @@ "alt-react": "0.0.1", "bignumber.js": "^4.0.0", "bitsharesjs": "^1.4.1", + "browser-locale": "^1.0.3", "classnames": "^2.2.1", "cookies-js": "^1.2.1", "counterpart": "^0.17.1", diff --git a/webpack.config.js b/webpack.config.js index 0deec84f85..617fcd1535 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -51,7 +51,7 @@ module.exports = function(env) { var outputPath = path.join(root_dir, "assets"); // COMMON PLUGINS - const baseUrl = "baseUrl" in env ? env.baseUrl : "/"; + const baseUrl = env.electron ? "" : "baseUrl" in env ? env.baseUrl : "/"; var plugins = [ new webpack.optimize.OccurrenceOrderPlugin(), new webpack.DefinePlugin({