make linter happy
This commit is contained in:
parent
6533716fac
commit
a75ef403ac
@ -19,16 +19,19 @@
|
|||||||
* Types and helper functions for dealing with Taler amounts.
|
* Types and helper functions for dealing with Taler amounts.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { Checkable } from "./checkable";
|
import { Checkable } from "./checkable";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of fractional units that one value unit represents.
|
* Number of fractional units that one value unit represents.
|
||||||
*/
|
*/
|
||||||
export const fractionalBase = 1e8;
|
export const fractionalBase = 1e8;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Non-negative financial amount. Fractional values are expressed as multiples
|
* Non-negative financial amount. Fractional values are expressed as multiples
|
||||||
* of 1e-8.
|
* of 1e-8.
|
||||||
@ -60,6 +63,7 @@ export class AmountJson {
|
|||||||
static checked: (obj: any) => AmountJson;
|
static checked: (obj: any) => AmountJson;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Result of a possibly overflowing operation.
|
* Result of a possibly overflowing operation.
|
||||||
*/
|
*/
|
||||||
@ -74,6 +78,7 @@ export interface Result {
|
|||||||
saturated: boolean;
|
saturated: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the largest amount that is safely representable.
|
* Get the largest amount that is safely representable.
|
||||||
*/
|
*/
|
||||||
@ -85,6 +90,7 @@ export function getMaxAmount(currency: string): AmountJson {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an amount that represents zero units of a currency.
|
* Get an amount that represents zero units of a currency.
|
||||||
*/
|
*/
|
||||||
@ -96,6 +102,7 @@ export function getZero(currency: string): AmountJson {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add two amounts. Return the result and whether
|
* Add two amounts. Return the result and whether
|
||||||
* the addition overflowed. The overflow is always handled
|
* the addition overflowed. The overflow is always handled
|
||||||
@ -124,6 +131,7 @@ export function add(first: AmountJson, ...rest: AmountJson[]): Result {
|
|||||||
return { amount: { currency, value, fraction }, saturated: false };
|
return { amount: { currency, value, fraction }, saturated: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subtract two amounts. Return the result and whether
|
* Subtract two amounts. Return the result and whether
|
||||||
* the subtraction overflowed. The overflow is always handled
|
* the subtraction overflowed. The overflow is always handled
|
||||||
@ -158,6 +166,7 @@ export function sub(a: AmountJson, ...rest: AmountJson[]): Result {
|
|||||||
return { amount: { currency, value, fraction }, saturated: false };
|
return { amount: { currency, value, fraction }, saturated: false };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compare two amounts. Returns 0 when equal, -1 when a < b
|
* Compare two amounts. Returns 0 when equal, -1 when a < b
|
||||||
* and +1 when a > b. Throws when currencies don't match.
|
* and +1 when a > b. Throws when currencies don't match.
|
||||||
@ -186,6 +195,7 @@ export function cmp(a: AmountJson, b: AmountJson): number {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a copy of an amount.
|
* Create a copy of an amount.
|
||||||
*/
|
*/
|
||||||
@ -197,6 +207,7 @@ export function copy(a: AmountJson): AmountJson {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Divide an amount. Throws on division by zero.
|
* Divide an amount. Throws on division by zero.
|
||||||
*/
|
*/
|
||||||
@ -215,6 +226,7 @@ export function divide(a: AmountJson, n: number): AmountJson {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if an amount is non-zero.
|
* Check if an amount is non-zero.
|
||||||
*/
|
*/
|
||||||
@ -222,6 +234,7 @@ export function isNonZero(a: AmountJson): boolean {
|
|||||||
return a.value > 0 || a.fraction > 0;
|
return a.value > 0 || a.fraction > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse an amount like 'EUR:20.5' for 20 Euros and 50 ct.
|
* Parse an amount like 'EUR:20.5' for 20 Euros and 50 ct.
|
||||||
*/
|
*/
|
||||||
@ -237,6 +250,11 @@ export function parse(s: string): AmountJson|undefined {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse amount in standard string form (like 'EUR:20.5'),
|
||||||
|
* throw if the input is not a valid amount.
|
||||||
|
*/
|
||||||
export function parseOrThrow(s: string): AmountJson {
|
export function parseOrThrow(s: string): AmountJson {
|
||||||
const res = parse(s);
|
const res = parse(s);
|
||||||
if (!res) {
|
if (!res) {
|
||||||
@ -245,6 +263,7 @@ export function parseOrThrow(s: string): AmountJson {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert the amount to a float.
|
* Convert the amount to a float.
|
||||||
*/
|
*/
|
||||||
@ -252,6 +271,7 @@ export function toFloat(a: AmountJson): number {
|
|||||||
return a.value + (a.fraction / fractionalBase);
|
return a.value + (a.fraction / fractionalBase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert a float to a Taler amount.
|
* Convert a float to a Taler amount.
|
||||||
* Loss of precision possible.
|
* Loss of precision possible.
|
||||||
@ -264,6 +284,7 @@ export function fromFloat(floatVal: number, currency: string) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert to standard human-readable string representation that's
|
* Convert to standard human-readable string representation that's
|
||||||
* also used in JSON formats.
|
* also used in JSON formats.
|
||||||
@ -272,6 +293,10 @@ export function toString(a: AmountJson) {
|
|||||||
return `${a.currency}:${a.value + (a.fraction / fractionalBase)}`;
|
return `${a.currency}:${a.value + (a.fraction / fractionalBase)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the argument is a valid amount in string form.
|
||||||
|
*/
|
||||||
export function check(a: any) {
|
export function check(a: any) {
|
||||||
if (typeof a !== "string") {
|
if (typeof a !== "string") {
|
||||||
return false;
|
return false;
|
||||||
|
40
src/i18n.tsx
40
src/i18n.tsx
@ -26,24 +26,32 @@ import {strings} from "./i18n/strings";
|
|||||||
import * as jedLib from "jed";
|
import * as jedLib from "jed";
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
|
|
||||||
let lang: string;
|
|
||||||
try {
|
const jed = setupJed();
|
||||||
lang = chrome.i18n.getUILanguage();
|
|
||||||
// Chrome gives e.g. "en-US", but Firefox gives us "en_US"
|
|
||||||
lang = lang.replace("_", "-");
|
/**
|
||||||
} catch (e) {
|
* Set up jed library for internationalization,
|
||||||
lang = "en";
|
* based on browser language settings.
|
||||||
console.warn("i18n default language not available");
|
*/
|
||||||
|
function setupJed(): any {
|
||||||
|
let lang: string;
|
||||||
|
try {
|
||||||
|
lang = chrome.i18n.getUILanguage();
|
||||||
|
// Chrome gives e.g. "en-US", but Firefox gives us "en_US"
|
||||||
|
lang = lang.replace("_", "-");
|
||||||
|
} catch (e) {
|
||||||
|
lang = "en";
|
||||||
|
console.warn("i18n default language not available");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strings[lang]) {
|
||||||
|
lang = "en-US";
|
||||||
|
console.log(`language ${lang} not found, defaulting to english`);
|
||||||
|
}
|
||||||
|
return new jedLib.Jed(strings[lang]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strings[lang]) {
|
|
||||||
lang = "en-US";
|
|
||||||
console.log(`language ${lang} not found, defaulting to english`);
|
|
||||||
}
|
|
||||||
|
|
||||||
const jed = new jedLib.Jed(strings[lang]);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert template strings to a msgid
|
* Convert template strings to a msgid
|
||||||
|
@ -896,9 +896,16 @@ export function isWireDetail(x: any): x is WireDetail {
|
|||||||
*/
|
*/
|
||||||
@Checkable.Class({extra: true})
|
@Checkable.Class({extra: true})
|
||||||
export class Proposal {
|
export class Proposal {
|
||||||
|
/**
|
||||||
|
* Contract terms for the propoal.
|
||||||
|
*/
|
||||||
@Checkable.Value(() => ContractTerms)
|
@Checkable.Value(() => ContractTerms)
|
||||||
contract_terms: ContractTerms;
|
contract_terms: ContractTerms;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Signature over contract, made by the merchant. The public key used for signing
|
||||||
|
* must be contract_terms.merchant_pub.
|
||||||
|
*/
|
||||||
@Checkable.String()
|
@Checkable.String()
|
||||||
sig: string;
|
sig: string;
|
||||||
|
|
||||||
|
@ -2754,7 +2754,7 @@ export class Wallet {
|
|||||||
return this.activeTipOperations[key];
|
return this.activeTipOperations[key];
|
||||||
}
|
}
|
||||||
const p = this.processTipImpl(tipToken);
|
const p = this.processTipImpl(tipToken);
|
||||||
this.activeTipOperations[key] = p
|
this.activeTipOperations[key] = p;
|
||||||
try {
|
try {
|
||||||
return await p;
|
return await p;
|
||||||
} finally {
|
} finally {
|
||||||
@ -2892,7 +2892,7 @@ export class Wallet {
|
|||||||
async getTipStatus(tipToken: TipToken): Promise<TipStatus> {
|
async getTipStatus(tipToken: TipToken): Promise<TipStatus> {
|
||||||
const tipId = tipToken.tip_id;
|
const tipId = tipToken.tip_id;
|
||||||
const merchantDomain = new URI(tipToken.pickup_url).origin();
|
const merchantDomain = new URI(tipToken.pickup_url).origin();
|
||||||
let tipRecord = await this.q().get(Stores.tips, [tipId, merchantDomain]);
|
const tipRecord = await this.q().get(Stores.tips, [tipId, merchantDomain]);
|
||||||
const amount = Amounts.parseOrThrow(tipToken.amount);
|
const amount = Amounts.parseOrThrow(tipToken.amount);
|
||||||
const exchangeUrl = tipToken.exchange_url;
|
const exchangeUrl = tipToken.exchange_url;
|
||||||
this.processTip(tipToken);
|
this.processTip(tipToken);
|
||||||
|
@ -15,9 +15,9 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compatibility helpers needed for browsers that don't implement
|
* Compatibility helpers needed for browsers that don't implement
|
||||||
* WebExtension APIs consistently.
|
* WebExtension APIs consistently.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export function isFirefox(): boolean {
|
export function isFirefox(): boolean {
|
||||||
const rt = chrome.runtime as any;
|
const rt = chrome.runtime as any;
|
||||||
|
@ -379,7 +379,8 @@ class ContractPrompt extends React.Component<ContractPromptProps, ContractPrompt
|
|||||||
{products}
|
{products}
|
||||||
{(this.state.payStatus && this.state.payStatus.coinSelection)
|
{(this.state.payStatus && this.state.payStatus.coinSelection)
|
||||||
? <i18n.Translate wrap="p">
|
? <i18n.Translate wrap="p">
|
||||||
The total price is <span>{amount} </span> (plus <span>{renderAmount(this.state.payStatus.coinSelection.totalFees)}</span> fees).
|
The total price is <span>{amount} </span>
|
||||||
|
(plus <span>{renderAmount(this.state.payStatus.coinSelection.totalFees)}</span> fees).
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
:
|
:
|
||||||
<i18n.Translate wrap="p">The total price is <span>{amount}</span>.</i18n.Translate>
|
<i18n.Translate wrap="p">The total price is <span>{amount}</span>.</i18n.Translate>
|
||||||
|
@ -340,7 +340,7 @@ class ExchangeSelection extends ImplicitStateComponent<ExchangeSelectionProps> {
|
|||||||
<button className="pure-button button-success" onClick={() => this.select(this.props.suggestedExchangeUrl)}>
|
<button className="pure-button button-success" onClick={() => this.select(this.props.suggestedExchangeUrl)}>
|
||||||
<i18n.Translate wrap="span">
|
<i18n.Translate wrap="span">
|
||||||
Select <strong>{this.props.suggestedExchangeUrl}</strong>
|
Select <strong>{this.props.suggestedExchangeUrl}</strong>
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
@ -30,8 +30,8 @@ import * as i18n from "../../i18n";
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
acceptTip,
|
acceptTip,
|
||||||
getTipStatus,
|
|
||||||
getReserveCreationInfo,
|
getReserveCreationInfo,
|
||||||
|
getTipStatus,
|
||||||
} from "../wxApi";
|
} from "../wxApi";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -72,6 +72,9 @@ export interface UpgradeResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error thrown when the function from the backend (via RPC) threw an error.
|
||||||
|
*/
|
||||||
export class WalletApiError extends Error {
|
export class WalletApiError extends Error {
|
||||||
constructor(message: string, public detail: any) {
|
constructor(message: string, public detail: any) {
|
||||||
super(message);
|
super(message);
|
||||||
|
@ -475,7 +475,10 @@ function waitMs(timeoutMs: number): Promise<void> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function makeSyncWalletRedirect(url: string, tabId: number, oldUrl: string, params?: {[name: string]: string | undefined}): object {
|
function makeSyncWalletRedirect(url: string,
|
||||||
|
tabId: number,
|
||||||
|
oldUrl: string,
|
||||||
|
params?: {[name: string]: string | undefined}): object {
|
||||||
const innerUrl = new URI(chrome.extension.getURL("/src/webex/pages/" + url));
|
const innerUrl = new URI(chrome.extension.getURL("/src/webex/pages/" + url));
|
||||||
if (params) {
|
if (params) {
|
||||||
for (const key in params) {
|
for (const key in params) {
|
||||||
@ -552,8 +555,8 @@ function handleHttpPayment(headerList: chrome.webRequest.HttpHeader[], url: stri
|
|||||||
if (fields.contract_url) {
|
if (fields.contract_url) {
|
||||||
return makeSyncWalletRedirect("confirm-contract.html", tabId, url, {
|
return makeSyncWalletRedirect("confirm-contract.html", tabId, url, {
|
||||||
contractUrl: fields.contract_url,
|
contractUrl: fields.contract_url,
|
||||||
sessionId: fields.session_id,
|
|
||||||
resourceUrl: fields.resource_url,
|
resourceUrl: fields.resource_url,
|
||||||
|
sessionId: fields.session_id,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user