aboutsummaryrefslogtreecommitdiff
path: root/src/webex
diff options
context:
space:
mode:
Diffstat (limited to 'src/webex')
-rw-r--r--src/webex/pages/confirm-contract.tsx14
-rw-r--r--src/webex/pages/confirm-create-reserve.tsx28
-rw-r--r--src/webex/pages/payback.tsx4
-rw-r--r--src/webex/pages/popup.tsx19
-rw-r--r--src/webex/pages/tree.tsx20
-rw-r--r--src/webex/renderHtml.tsx12
6 files changed, 62 insertions, 35 deletions
diff --git a/src/webex/pages/confirm-contract.tsx b/src/webex/pages/confirm-contract.tsx
index c4692cbf2..fa71b1028 100644
--- a/src/webex/pages/confirm-contract.tsx
+++ b/src/webex/pages/confirm-contract.tsx
@@ -107,6 +107,12 @@ interface ContractPromptState {
payDisabled: boolean;
alreadyPaid: boolean;
exchanges: null|ExchangeRecord[];
+ /**
+ * Don't request updates to proposal state while
+ * this is set to true, to avoid UI flickering
+ * when pressing pay.
+ */
+ holdCheck: boolean;
}
class ContractPrompt extends React.Component<ContractPromptProps, ContractPromptState> {
@@ -118,6 +124,7 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
exchanges: null,
proposal: null,
payDisabled: true,
+ holdCheck: false,
};
}
@@ -138,6 +145,10 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
}
async checkPayment() {
+ window.setTimeout(() => this.checkPayment(), 500);
+ if (this.state.holdCheck) {
+ return;
+ }
const payStatus = await wxApi.checkPay(this.props.proposalId);
if (payStatus === "insufficient-balance") {
const msgInsufficient = i18n.str`You have insufficient funds of the requested currency in your wallet.`;
@@ -160,11 +171,11 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
} else {
this.setState({payDisabled: false, error: null});
}
- window.setTimeout(() => this.checkPayment(), 500);
}
async doPayment() {
const proposal = this.state.proposal;
+ this.setState({holdCheck: true});
if (!proposal) {
return;
}
@@ -178,6 +189,7 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
document.location.href = proposal.contractTerms.fulfillment_url;
break;
}
+ this.setState({holdCheck: false});
}
diff --git a/src/webex/pages/confirm-create-reserve.tsx b/src/webex/pages/confirm-create-reserve.tsx
index 6e1cc4a82..a695d9353 100644
--- a/src/webex/pages/confirm-create-reserve.tsx
+++ b/src/webex/pages/confirm-create-reserve.tsx
@@ -22,7 +22,7 @@
* @author Florian Dold
*/
-import {amountToPretty, canonicalizeBaseUrl} from "../../helpers";
+import {canonicalizeBaseUrl} from "../../helpers";
import * as i18n from "../../i18n";
import {
AmountJson,
@@ -40,6 +40,8 @@ import {
getReserveCreationInfo,
} from "../wxApi";
+import {renderAmount} from "../renderHtml";
+
import * as React from "react";
import * as ReactDOM from "react-dom";
import URI = require("urijs");
@@ -163,10 +165,10 @@ function renderReserveCreationDetails(rci: ReserveCreationInfo|null) {
return (
<tr>
<td>{countByPub[denom.denomPub] + "x"}</td>
- <td>{amountToPretty(denom.value)}</td>
- <td>{amountToPretty(denom.feeWithdraw)}</td>
- <td>{amountToPretty(denom.feeRefresh)}</td>
- <td>{amountToPretty(denom.feeDeposit)}</td>
+ <td>{renderAmount(denom.value)}</td>
+ <td>{renderAmount(denom.feeWithdraw)}</td>
+ <td>{renderAmount(denom.feeRefresh)}</td>
+ <td>{renderAmount(denom.feeDeposit)}</td>
</tr>
);
}
@@ -187,22 +189,22 @@ function renderReserveCreationDetails(rci: ReserveCreationInfo|null) {
{rci!.wireFees.feesForType[s].map((f) => (
<tr>
<td>{moment.unix(f.endStamp).format("llll")}</td>
- <td>{amountToPretty(f.wireFee)}</td>
- <td>{amountToPretty(f.closingFee)}</td>
+ <td>{renderAmount(f.wireFee)}</td>
+ <td>{renderAmount(f.closingFee)}</td>
</tr>
))}
</tbody>,
];
}
- const withdrawFeeStr = amountToPretty(rci.withdrawFee);
- const overheadStr = amountToPretty(rci.overhead);
+ const withdrawFee = renderAmount(rci.withdrawFee);
+ const overhead = renderAmount(rci.overhead);
return (
<div>
<h3>Overview</h3>
- <p>{i18n.str`Withdrawal fees: ${withdrawFeeStr}`}</p>
- <p>{i18n.str`Rounding loss: ${overheadStr}`}</p>
+ <p>{i18n.str`Withdrawal fees:`} {withdrawFee}</p>
+ <p>{i18n.str`Rounding loss:`} {overhead}</p>
<p>{i18n.str`Earliest expiration (for deposit): ${moment.unix(rci.earliestDepositExpiration).fromNow()}`}</p>
<h3>Coin Fees</h3>
<table className="pure-table">
@@ -374,7 +376,7 @@ class ExchangeSelection extends ImplicitStateComponent<ExchangeSelectionProps> {
Using exchange provider <strong>{this.url()}</strong>.
The exchange provider will charge
{" "}
- <span>{amountToPretty(totalCost)}</span>
+ <span>{renderAmount(totalCost)}</span>
{" "}
in fees.
</i18n.Translate>
@@ -476,7 +478,7 @@ class ExchangeSelection extends ImplicitStateComponent<ExchangeSelectionProps> {
<div>
<i18n.Translate wrap="p">
{"You are about to withdraw "}
- <strong>{amountToPretty(this.props.amount)}</strong>
+ <strong>{renderAmount(this.props.amount)}</strong>
{" from your bank account into your wallet."}
</i18n.Translate>
{this.selectingExchange() ? this.renderSelect() : this.renderConfirm()}
diff --git a/src/webex/pages/payback.tsx b/src/webex/pages/payback.tsx
index 4aadf5add..51ad8612c 100644
--- a/src/webex/pages/payback.tsx
+++ b/src/webex/pages/payback.tsx
@@ -24,7 +24,7 @@
/**
* Imports.
*/
-import { amountToPretty } from "../../helpers";
+import { renderAmount } from "../renderHtml";
import {
ReserveRecord,
} from "../../types";
@@ -73,7 +73,7 @@ class Payback extends ImplicitStateComponent<any> {
<div>
{reserves.map((r) => (
<div>
- <h2>Reserve for ${amountToPretty(r.current_amount!)}</h2>
+ <h2>Reserve for ${renderAmount(r.current_amount!)}</h2>
<ul>
<li>Exchange: ${r.exchange_base_url}</li>
</ul>
diff --git a/src/webex/pages/popup.tsx b/src/webex/pages/popup.tsx
index 54e4f3e2d..ee9c8023f 100644
--- a/src/webex/pages/popup.tsx
+++ b/src/webex/pages/popup.tsx
@@ -25,7 +25,6 @@
/**
* Imports.
*/
-import { amountToPretty } from "../../helpers";
import * as i18n from "../../i18n";
import {
AmountJson,
@@ -36,7 +35,7 @@ import {
WalletBalanceEntry,
} from "../../types";
-import { abbrev } from "../renderHtml";
+import { abbrev, renderAmount } from "../renderHtml";
import * as React from "react";
import * as ReactDOM from "react-dom";
@@ -258,15 +257,15 @@ class WalletBalanceView extends React.Component<any, any> {
let incoming: JSX.Element | undefined;
let payment: JSX.Element | undefined;
- console.log("available: ", entry.pendingIncoming ? amountToPretty(entry.available) : null);
- console.log("incoming: ", entry.pendingIncoming ? amountToPretty(entry.pendingIncoming) : null);
+ console.log("available: ", entry.pendingIncoming ? renderAmount(entry.available) : null);
+ console.log("incoming: ", entry.pendingIncoming ? renderAmount(entry.pendingIncoming) : null);
if (Amounts.isNonZero(entry.pendingIncoming)) {
incoming = (
<i18n.Translate wrap="span">
<span style={{color: "darkgreen"}}>
{"+"}
- {amountToPretty(entry.pendingIncoming)}
+ {renderAmount(entry.pendingIncoming)}
</span>
{" "}
incoming
@@ -278,7 +277,7 @@ class WalletBalanceView extends React.Component<any, any> {
payment = (
<i18n.Translate wrap="span">
<span style={{color: "darkblue"}}>
- {amountToPretty(entry.pendingPayment)}
+ {renderAmount(entry.pendingPayment)}
</span>
{" "}
being spent
@@ -344,7 +343,7 @@ function formatHistoryItem(historyItem: HistoryRecord) {
<i18n.Translate wrap="p">
Bank requested reserve (<span>{abbrev(d.reservePub)}</span>) for
{" "}
- <span>{amountToPretty(d.requestedAmount)}</span>.
+ <span>{renderAmount(d.requestedAmount)}</span>.
</i18n.Translate>
);
case "confirm-reserve": {
@@ -354,7 +353,7 @@ function formatHistoryItem(historyItem: HistoryRecord) {
return (
<i18n.Translate wrap="p">
Started to withdraw
- {" "}{amountToPretty(d.requestedAmount)}{" "}
+ {" "}{renderAmount(d.requestedAmount)}{" "}
from <span>{exchange}</span> (<span>{pub}</span>).
</i18n.Translate>
);
@@ -369,7 +368,7 @@ function formatHistoryItem(historyItem: HistoryRecord) {
}
case "depleted-reserve": {
const exchange = d.exchangeBaseUrl ? (new URI(d.exchangeBaseUrl)).host() : "??";
- const amount = amountToPretty(d.requestedAmount);
+ const amount = renderAmount(d.requestedAmount);
const pub = abbrev(d.reservePub);
return (
<i18n.Translate wrap="p">
@@ -383,7 +382,7 @@ function formatHistoryItem(historyItem: HistoryRecord) {
const fulfillmentLinkElem = <a href={url} onClick={openTab(url)}>view product</a>;
return (
<i18n.Translate wrap="p">
- Paid <span>{amountToPretty(d.amount)}</span> to merchant <span>{merchantElem}</span>.
+ Paid <span>{renderAmount(d.amount)}</span> to merchant <span>{merchantElem}</span>.
{" "}
(<span>{fulfillmentLinkElem}</span>)
</i18n.Translate>
diff --git a/src/webex/pages/tree.tsx b/src/webex/pages/tree.tsx
index 3eafbbeb4..ad1693fb5 100644
--- a/src/webex/pages/tree.tsx
+++ b/src/webex/pages/tree.tsx
@@ -21,7 +21,7 @@
*/
-import { amountToPretty, getTalerStampDate } from "../../helpers";
+import { getTalerStampDate } from "../../helpers";
import {
CoinRecord,
CoinStatus,
@@ -42,6 +42,8 @@ import {
refresh,
} from "../wxApi";
+import { renderAmount } from "../renderHtml";
+
import * as React from "react";
import * as ReactDOM from "react-dom";
@@ -57,8 +59,8 @@ class ReserveView extends React.Component<ReserveViewProps, void> {
<ul>
<li>Key: {r.reserve_pub}</li>
<li>Created: {(new Date(r.created * 1000).toString())}</li>
- <li>Current: {r.current_amount ? amountToPretty(r.current_amount!) : "null"}</li>
- <li>Requested: {amountToPretty(r.requested_amount)}</li>
+ <li>Current: {r.current_amount ? renderAmount(r.current_amount!) : "null"}</li>
+ <li>Requested: {renderAmount(r.requested_amount)}</li>
<li>Confirmed: {r.confirmed}</li>
</ul>
</div>
@@ -135,7 +137,7 @@ class CoinView extends React.Component<CoinViewProps, void> {
<div className="tree-item">
<ul>
<li>Key: {c.coinPub}</li>
- <li>Current amount: {amountToPretty(c.currentAmount)}</li>
+ <li>Current amount: {renderAmount(c.currentAmount)}</li>
<li>Denomination: <ExpanderText text={c.denomPub} /></li>
<li>Suspended: {(c.suspended || false).toString()}</li>
<li>Status: {CoinStatus[c.status]}</li>
@@ -304,11 +306,11 @@ class DenominationList extends ImplicitStateComponent<DenominationListProps> {
<div className="tree-item">
<ul>
<li>Offered: {d.isOffered ? "yes" : "no"}</li>
- <li>Value: {amountToPretty(d.value)}</li>
- <li>Withdraw fee: {amountToPretty(d.feeWithdraw)}</li>
- <li>Refresh fee: {amountToPretty(d.feeRefresh)}</li>
- <li>Deposit fee: {amountToPretty(d.feeDeposit)}</li>
- <li>Refund fee: {amountToPretty(d.feeRefund)}</li>
+ <li>Value: {renderAmount(d.value)}</li>
+ <li>Withdraw fee: {renderAmount(d.feeWithdraw)}</li>
+ <li>Refresh fee: {renderAmount(d.feeRefresh)}</li>
+ <li>Deposit fee: {renderAmount(d.feeDeposit)}</li>
+ <li>Refund fee: {renderAmount(d.feeRefund)}</li>
<li>Start: {getTalerStampDate(d.stampStart)!.toString()}</li>
<li>Withdraw expiration: {getTalerStampDate(d.stampExpireWithdraw)!.toString()}</li>
<li>Legal expiration: {getTalerStampDate(d.stampExpireLegal)!.toString()}</li>
diff --git a/src/webex/renderHtml.tsx b/src/webex/renderHtml.tsx
index 4dd7baded..51f9019ef 100644
--- a/src/webex/renderHtml.tsx
+++ b/src/webex/renderHtml.tsx
@@ -27,6 +27,8 @@
import { amountToPretty } from "../helpers";
import * as i18n from "../i18n";
import {
+ AmountJson,
+ Amounts,
ContractTerms,
} from "../types";
@@ -63,6 +65,16 @@ export function renderContractTerms(contractTerms: ContractTerms): JSX.Element {
/**
+ * Render amount as HTML, which non-breaking space between
+ * decimal value and currency.
+ */
+export function renderAmount(amount: AmountJson) {
+ const x = amount.value + amount.fraction / Amounts.fractionalBase;
+ return <span>{x}&nbsp;{amount.currency}</span>;
+}
+
+
+/**
* Abbreviate a string to a given length, and show the full
* string on hover as a tooltip.
*/