From aaf950e2ad5c07d4423f9822e3a0ae9f7b8d2bdf Mon Sep 17 00:00:00 2001 From: Florian Dold Date: Mon, 30 Mar 2020 16:09:32 +0530 Subject: re-format with prettier v2, fix HTML --- src/webex/background.html | 16 +- src/webex/chromeBadge.ts | 59 ++- src/webex/compat.ts | 14 +- src/webex/i18n.tsx | 75 ++-- src/webex/messages.ts | 8 +- src/webex/notify.ts | 44 +- src/webex/pages/add-auditor.html | 44 +- src/webex/pages/add-auditor.tsx | 8 +- src/webex/pages/auditors.html | 50 +-- src/webex/pages/auditors.tsx | 84 ++-- src/webex/pages/benchmark.html | 16 +- src/webex/pages/benchmark.tsx | 49 +-- src/webex/pages/pay.html | 129 +++--- src/webex/pages/pay.tsx | 17 +- src/webex/pages/payback.html | 50 +-- src/webex/pages/popup.css | 278 ++++++------ src/webex/pages/popup.html | 22 +- src/webex/pages/popup.tsx | 80 ++-- src/webex/pages/redirect.html | 16 +- src/webex/pages/redirect.js | 2 +- src/webex/pages/refund.html | 16 +- src/webex/pages/refund.tsx | 7 +- src/webex/pages/reset-required.html | 43 +- src/webex/pages/reset-required.tsx | 40 +- src/webex/pages/return-coins.html | 18 +- src/webex/pages/return-coins.tsx | 167 ++++--- src/webex/pages/show-db.html | 10 +- src/webex/pages/show-db.ts | 41 +- src/webex/pages/tip.html | 33 +- src/webex/pages/tip.tsx | 10 +- src/webex/pages/welcome.html | 33 +- src/webex/pages/welcome.tsx | 2 +- src/webex/pages/withdraw.html | 31 +- src/webex/pages/withdraw.tsx | 2 +- src/webex/renderHtml.tsx | 14 +- src/webex/style/pure.css | 853 ++++++++++++++++++------------------ src/webex/style/wallet.css | 196 +++++---- src/webex/wxApi.ts | 2 +- src/webex/wxBackend.ts | 12 +- 39 files changed, 1352 insertions(+), 1239 deletions(-) (limited to 'src/webex') diff --git a/src/webex/background.html b/src/webex/background.html index 0535dd5f3..12a962c67 100644 --- a/src/webex/background.html +++ b/src/webex/background.html @@ -1,11 +1,11 @@ - - - - (wallet bg page) - - - - + + + + (wallet bg page) + + + + diff --git a/src/webex/chromeBadge.ts b/src/webex/chromeBadge.ts index e6b21ad91..cdd99f8c1 100644 --- a/src/webex/chromeBadge.ts +++ b/src/webex/chromeBadge.ts @@ -14,10 +14,8 @@ TALER; see the file COPYING. If not, see */ - import { isFirefox } from "./compat"; - /** * Polyfill for requestAnimationFrame, which * doesn't work from a background page. @@ -28,7 +26,6 @@ function rAF(cb: (ts: number) => void) { }, 100 /* 100 ms delay between frames */); } - /** * Badge for Chrome that renders a Taler logo with a rotating ring if some * background activity is happening. @@ -139,16 +136,27 @@ export class ChromeBadge { if (this.animationRunning) { /* Draw circle around the "T" with an opening of this.gapWidth */ const aMax = ChromeBadge.rotationAngleMax; - const startAngle = this.rotationAngle / aMax * Math.PI * 2; - const stopAngle = ((this.rotationAngle + aMax - this.gapWidth) / aMax) * Math.PI * 2; - this.ctx.arc(0, 0, this.canvas.width / 2 - 2, /* radius */ startAngle, stopAngle, false); + const startAngle = (this.rotationAngle / aMax) * Math.PI * 2; + const stopAngle = + ((this.rotationAngle + aMax - this.gapWidth) / aMax) * Math.PI * 2; + this.ctx.arc( + 0, + 0, + this.canvas.width / 2 - 2, + /* radius */ startAngle, + stopAngle, + false, + ); } else { /* Draw full circle */ - this.ctx.arc(0, 0, - this.canvas.width / 2 - 2, /* radius */ - 0, - Math.PI * 2, - false); + this.ctx.arc( + 0, + 0, + this.canvas.width / 2 - 2 /* radius */, + 0, + Math.PI * 2, + false, + ); } this.ctx.stroke(); // go back to the origin @@ -162,7 +170,14 @@ export class ChromeBadge { const ch = this.canvas.height; this.ctx.beginPath(); this.ctx.arc(cw - r, ch - r, r, 0, 2 * Math.PI, false); - const gradient = this.ctx.createRadialGradient(cw - r, ch - r, r, cw - r, ch - r, 5); + const gradient = this.ctx.createRadialGradient( + cw - r, + ch - r, + r, + cw - r, + ch - r, + 5, + ); gradient.addColorStop(0, "rgba(255, 255, 255, 1)"); gradient.addColorStop(1, "blue"); this.ctx.fillStyle = gradient; @@ -173,11 +188,13 @@ export class ChromeBadge { // tslint:disable-next-line:no-string-literal if (window["chrome"] && window.chrome["browserAction"]) { try { - const imageData = this.ctx.getImageData(0, - 0, - this.canvas.width, - this.canvas.height); - chrome.browserAction.setIcon({imageData}); + const imageData = this.ctx.getImageData( + 0, + 0, + this.canvas.width, + this.canvas.height, + ); + chrome.browserAction.setIcon({ imageData }); } catch (e) { // Might fail if browser has over-eager canvas fingerprinting countermeasures. // There's nothing we can do then ... @@ -194,7 +211,7 @@ export class ChromeBadge { return; } this.animationRunning = true; - let start: number|undefined; + let start: number | undefined; const step = (timestamp: number) => { if (!this.animationRunning) { return; @@ -206,8 +223,10 @@ export class ChromeBadge { // stop if we're close enough to origin this.rotationAngle = 0; } else { - this.rotationAngle = (this.rotationAngle + (timestamp - start) * - ChromeBadge.rotationSpeed) % ChromeBadge.rotationAngleMax; + this.rotationAngle = + (this.rotationAngle + + (timestamp - start) * ChromeBadge.rotationSpeed) % + ChromeBadge.rotationAngleMax; } if (this.isBusy) { if (this.gapWidth < ChromeBadge.openMax) { diff --git a/src/webex/compat.ts b/src/webex/compat.ts index 121c58e7f..f1a68f33e 100644 --- a/src/webex/compat.ts +++ b/src/webex/compat.ts @@ -20,16 +20,16 @@ */ export function isFirefox(): boolean { - const rt = chrome.runtime as any; - if (typeof rt.getBrowserInfo === "function") { - return true; - } - return false; + const rt = chrome.runtime as any; + if (typeof rt.getBrowserInfo === "function") { + return true; + } + return false; } /** * Check if we are running under nodejs. */ export function isNode() { - return (typeof process !== 'undefined') && (process.release.name === 'node') -} \ No newline at end of file + return typeof process !== "undefined" && process.release.name === "node"; +} diff --git a/src/webex/i18n.tsx b/src/webex/i18n.tsx index 3923654e7..2e753e441 100644 --- a/src/webex/i18n.tsx +++ b/src/webex/i18n.tsx @@ -21,19 +21,17 @@ /** * Imports. */ -import {strings} from "../i18n/strings"; +import { strings } from "../i18n/strings"; // @ts-ignore: no type decl for this library import * as jedLib from "jed"; import * as React from "react"; - const jed = setupJed(); let enableTracing = false; - /** * Set up jed library for internationalization, * based on browser language settings. @@ -56,7 +54,6 @@ function setupJed(): any { return new jedLib.Jed(strings[lang]); } - /** * Convert template strings to a msgid */ @@ -71,22 +68,22 @@ function toI18nString(stringSeq: ReadonlyArray) { return s; } - /** * Internationalize a string template with arbitrary serialized values. */ export function str(stringSeq: TemplateStringsArray, ...values: any[]) { const s = toI18nString(stringSeq); - const tr = jed.translate(s).ifPlural(1, s).fetch(...values); + const tr = jed + .translate(s) + .ifPlural(1, s) + .fetch(...values); return tr; } - interface TranslateSwitchProps { target: number; } - function stringifyChildren(children: any): string { let n = 1; const ss = React.Children.map(children, (c) => { @@ -100,7 +97,6 @@ function stringifyChildren(children: any): string { return s; } - interface TranslateProps { /** * Component that the translated element should be wrapped in. @@ -114,7 +110,6 @@ interface TranslateProps { wrapProps?: any; } - /** * Translate text node children of this component. * If a child component might produce a text node, it must be wrapped @@ -130,11 +125,19 @@ interface TranslateProps { export class Translate extends React.Component { render(): JSX.Element { const s = stringifyChildren(this.props.children); - const tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: number) => i % 2 === 0); + const tr = jed + .ngettext(s, s, 1) + .split(/%(\d+)\$s/) + .filter((e: any, i: number) => i % 2 === 0); const childArray = React.Children.toArray(this.props.children!); for (let i = 0; i < childArray.length - 1; ++i) { - if ((typeof childArray[i]) === "string" && (typeof childArray[i + 1]) === "string") { - childArray[i + 1] = (childArray[i] as string).concat(childArray[i + 1] as string); + if ( + typeof childArray[i] === "string" && + typeof childArray[i + 1] === "string" + ) { + childArray[i + 1] = (childArray[i] as string).concat( + childArray[i + 1] as string, + ); childArray.splice(i, 1); } } @@ -158,7 +161,6 @@ export class Translate extends React.Component { } } - /** * Switch translation based on singular or plural based on the target prop. * Should only contain TranslateSingular and TransplatePlural as children. @@ -171,7 +173,10 @@ export class Translate extends React.Component { * * ``` */ -export class TranslateSwitch extends React.Component { +export class TranslateSwitch extends React.Component< + TranslateSwitchProps, + void +> { render(): JSX.Element { let singular: React.ReactElement | undefined; let plural: React.ReactElement | undefined; @@ -186,7 +191,7 @@ export class TranslateSwitch extends React.Component } }); } - if ((!singular) || (!plural)) { + if (!singular || !plural) { console.error("translation not found"); return React.createElement("span", {}, ["translation not found"]); } @@ -198,7 +203,6 @@ export class TranslateSwitch extends React.Component } } - interface TranslationPluralProps { target: number; } @@ -206,14 +210,24 @@ interface TranslationPluralProps { /** * See [[TranslateSwitch]]. */ -export class TranslatePlural extends React.Component { +export class TranslatePlural extends React.Component< + TranslationPluralProps, + void +> { render(): JSX.Element { const s = stringifyChildren(this.props.children); - const tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: number) => i % 2 === 0); + const tr = jed + .ngettext(s, s, 1) + .split(/%(\d+)\$s/) + .filter((e: any, i: number) => i % 2 === 0); const childArray = React.Children.toArray(this.props.children!); for (let i = 0; i < childArray.length - 1; ++i) { - if ((typeof childArray[i]) === "string" && (typeof childArray[i + 1]) === "string") { - childArray[i + i] = childArray[i] as string + childArray[i + 1] as string; + if ( + typeof childArray[i] === "string" && + typeof childArray[i + 1] === "string" + ) { + childArray[i + i] = ((childArray[i] as string) + + childArray[i + 1]) as string; childArray.splice(i, 1); } } @@ -234,18 +248,27 @@ export class TranslatePlural extends React.Component { +export class TranslateSingular extends React.Component< + TranslationPluralProps, + void +> { render(): JSX.Element { const s = stringifyChildren(this.props.children); - const tr = jed.ngettext(s, s, 1).split(/%(\d+)\$s/).filter((e: any, i: number) => i % 2 === 0); + const tr = jed + .ngettext(s, s, 1) + .split(/%(\d+)\$s/) + .filter((e: any, i: number) => i % 2 === 0); const childArray = React.Children.toArray(this.props.children!); for (let i = 0; i < childArray.length - 1; ++i) { - if ((typeof childArray[i]) === "string" && (typeof childArray[i + 1]) === "string") { - childArray[i + i] = childArray[i] as string + childArray[i + 1] as string; + if ( + typeof childArray[i] === "string" && + typeof childArray[i + 1] === "string" + ) { + childArray[i + i] = ((childArray[i] as string) + + childArray[i + 1]) as string; childArray.splice(i, 1); } } diff --git a/src/webex/messages.ts b/src/webex/messages.ts index 7672fcb4b..b695b4ab6 100644 --- a/src/webex/messages.ts +++ b/src/webex/messages.ts @@ -147,7 +147,10 @@ export interface MessageMap { response: walletTypes.BenchmarkResult; }; "get-withdraw-details": { - request: { talerWithdrawUri: string; maybeSelectedExchange: string | undefined }; + request: { + talerWithdrawUri: string; + maybeSelectedExchange: string | undefined; + }; response: walletTypes.WithdrawDetails; }; "accept-withdrawal": { @@ -159,12 +162,11 @@ export interface MessageMap { response: walletTypes.PreparePayResult; }; "get-diagnostics": { - request: { }; + request: {}; response: walletTypes.WalletDiagnostics; }; } - /** * String literal types for messages. */ diff --git a/src/webex/notify.ts b/src/webex/notify.ts index 61a96cb1b..910a20999 100644 --- a/src/webex/notify.ts +++ b/src/webex/notify.ts @@ -41,18 +41,17 @@ if (document.documentElement.getAttribute("data-taler-nojs")) { interface Handler { type: string; - listener: (e: Event) => void|Promise; + listener: (e: Event) => void | Promise; } const handlers: Handler[] = []; - -let sheet: CSSStyleSheet|null; +let sheet: CSSStyleSheet | null; function initStyle() { logVerbose && console.log("taking over styles"); const name = "taler-presence-stylesheet"; const content = "/* Taler stylesheet controlled by JS */"; - let style = document.getElementById(name) as HTMLStyleElement|null; + let style = document.getElementById(name) as HTMLStyleElement | null; if (!style) { style = document.createElement("style"); // Needed by WebKit @@ -68,7 +67,9 @@ function initStyle() { style.innerText = content; } if (!style.sheet) { - throw Error("taler-presence-stylesheet should be a style sheet ( or + +
diff --git a/src/webex/pages/add-auditor.tsx b/src/webex/pages/add-auditor.tsx index 0f681aae4..5840f4d63 100644 --- a/src/webex/pages/add-auditor.tsx +++ b/src/webex/pages/add-auditor.tsx @@ -35,8 +35,7 @@ interface ConfirmAuditorProps { function ConfirmAuditor(props: ConfirmAuditorProps) { const [addDone, setAddDone] = useState(false); - - const add = async() => { + const add = async () => { const currencies = await getCurrencies(); let currency: CurrencyRecord | undefined; @@ -78,7 +77,7 @@ function ConfirmAuditor(props: ConfirmAuditorProps) { await updateCurrency(currency); setAddDone(true); - } + }; const back = () => { window.history.back(); @@ -115,7 +114,6 @@ function ConfirmAuditor(props: ConfirmAuditorProps) { ); } - registerMountPage(() => { const walletPageUrl = new URL(document.location.href); const url = walletPageUrl.searchParams.get("url"); @@ -136,5 +134,5 @@ registerMountPage(() => { } const expirationStamp = Number.parseInt(auditorStampStr); const args = { url, currency, auditorPub, expirationStamp }; - return ; + return ; }); diff --git a/src/webex/pages/auditors.html b/src/webex/pages/auditors.html index cbfc3b4b5..7c207f750 100644 --- a/src/webex/pages/auditors.html +++ b/src/webex/pages/auditors.html @@ -1,34 +1,34 @@ + + + Taler Wallet: Auditors - - - Taler Wallet: Auditors + - + - + + - - - - + +
diff --git a/src/webex/pages/auditors.tsx b/src/webex/pages/auditors.tsx index 876cf326b..e2bb29af1 100644 --- a/src/webex/pages/auditors.tsx +++ b/src/webex/pages/auditors.tsx @@ -20,17 +20,13 @@ * @author Florian Dold */ - import { AuditorRecord, CurrencyRecord, ExchangeForCurrencyRecord, } from "../../types/dbTypes"; -import { - getCurrencies, - updateCurrency, -} from "../wxApi"; +import { getCurrencies, updateCurrency } from "../wxApi"; import * as React from "react"; import * as ReactDOM from "react-dom"; @@ -60,14 +56,22 @@ class CurrencyList extends React.Component<{}, CurrencyListState> { } async confirmRemoveAuditor(c: CurrencyRecord, a: AuditorRecord) { - if (window.confirm(`Do you really want to remove auditor ${a.baseUrl} for currency ${c.name}?`)) { + if ( + window.confirm( + `Do you really want to remove auditor ${a.baseUrl} for currency ${c.name}?`, + ) + ) { c.auditors = c.auditors.filter((x) => x.auditorPub !== a.auditorPub); await updateCurrency(c); } } async confirmRemoveExchange(c: CurrencyRecord, e: ExchangeForCurrencyRecord) { - if (window.confirm(`Do you really want to remove exchange ${e.baseUrl} for currency ${c.name}?`)) { + if ( + window.confirm( + `Do you really want to remove exchange ${e.baseUrl} for currency ${c.name}?`, + ) + ) { c.exchanges = c.exchanges.filter((x) => x.baseUrl !== e.baseUrl); await updateCurrency(c); } @@ -81,18 +85,21 @@ class CurrencyList extends React.Component<{}, CurrencyListState> {

Trusted Auditors:

    - {c.auditors.map((a) => ( -
  • - {a.baseUrl}{" "} - -
      -
    • valid until {new Date(a.expirationStamp).toString()}
    • -
    • public key {a.auditorPub}
    • -
    -
  • - ))} + {c.auditors.map((a) => ( +
  • + {a.baseUrl}{" "} + +
      +
    • valid until {new Date(a.expirationStamp).toString()}
    • +
    • public key {a.auditorPub}
    • +
    +
  • + ))}
); @@ -106,14 +113,17 @@ class CurrencyList extends React.Component<{}, CurrencyListState> {

Trusted Exchanges:

    - {c.exchanges.map((e) => ( -
  • - {e.baseUrl}{" "} - -
  • - ))} + {c.exchanges.map((e) => ( +
  • + {e.baseUrl}{" "} + +
  • + ))}
); @@ -126,16 +136,16 @@ class CurrencyList extends React.Component<{}, CurrencyListState> { } return (
- {currencies.map((c) => ( -
-

Currency {c.name}

-

Displayed with {c.fractionalDigits} fractional digits.

-

Auditors

-
{this.renderAuditors(c)}
-

Exchanges

-
{this.renderExchanges(c)}
-
- ))} + {currencies.map((c) => ( +
+

Currency {c.name}

+

Displayed with {c.fractionalDigits} fractional digits.

+

Auditors

+
{this.renderAuditors(c)}
+

Exchanges

+
{this.renderExchanges(c)}
+
+ ))}
); } diff --git a/src/webex/pages/benchmark.html b/src/webex/pages/benchmark.html index a593d1e37..d4216ecad 100644 --- a/src/webex/pages/benchmark.html +++ b/src/webex/pages/benchmark.html @@ -1,17 +1,17 @@ - + - + Taler Wallet: Benchmarks - - + + -
-

Benchmarks

-
-
+
+

Benchmarks

+
+
diff --git a/src/webex/pages/benchmark.tsx b/src/webex/pages/benchmark.tsx index fe874f2b7..7de546bb0 100644 --- a/src/webex/pages/benchmark.tsx +++ b/src/webex/pages/benchmark.tsx @@ -14,7 +14,6 @@ TALER; see the file COPYING. If not, see */ - /** * Benchmarks for the wallet. * @@ -31,14 +30,12 @@ import * as React from "react"; import * as ReactDOM from "react-dom"; import { registerMountPage } from "../renderHtml"; - interface BenchmarkRunnerState { repetitions: number; result?: BenchmarkResult; running: boolean; } - function BenchmarkDisplay(props: BenchmarkRunnerState) { const result = props.result; if (!result) { @@ -50,24 +47,23 @@ function BenchmarkDisplay(props: BenchmarkRunnerState) { } return ( <> -

Results for {result.repetitions} repetitions

- - - - - - - { - Object.keys(result.time).sort().map( - k => - - - - - ) - } - -
{i18n.str`Operation`}{i18n.str`time (ms/op)`}
{k}{result.time[k] / result.repetitions}
+

Results for {result.repetitions} repetitions

+ + + + + + + {Object.keys(result.time) + .sort() + .map((k) => ( + + + + + ))} + +
{i18n.str`Operation`}{i18n.str`time (ms/op)`}
{k}{result.time[k] / result.repetitions}
); } @@ -91,10 +87,13 @@ class BenchmarkRunner extends React.Component { return (
- this.setState({ repetitions: Number.parseInt(evt.target.value) })} /> - {" "} + + this.setState({ repetitions: Number.parseInt(evt.target.value) }) + } + />{" "}
diff --git a/src/webex/pages/pay.html b/src/webex/pages/pay.html index 20605ac49..6afc95615 100644 --- a/src/webex/pages/pay.html +++ b/src/webex/pages/pay.html @@ -1,79 +1,76 @@ + + + Taler Wallet: Confirm Contract - - - Taler Wallet: Confirm Contract + + - - + - + + - - + - - - -
-

GNU Taler Wallet

-
-
- + .okaybox { + border: 1px solid; + display: inline-block; + margin: 1em; + padding: 1em; + font-weight: bold; + background: #00fa9a; + } + + + +
+

GNU Taler Wallet

+
+
+ diff --git a/src/webex/pages/pay.tsx b/src/webex/pages/pay.tsx index 7f36cb66e..714e3b0a3 100644 --- a/src/webex/pages/pay.tsx +++ b/src/webex/pages/pay.tsx @@ -78,17 +78,15 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) { let contractTerms: ContractTerms; try { - contractTerms = codecForContractTerms().decode(JSON.parse(payStatus.contractTermsRaw)); + contractTerms = codecForContractTerms().decode( + JSON.parse(payStatus.contractTermsRaw), + ); } catch (e) { // This should never happen, as the wallet is supposed to check the contract terms // before storing them. console.error(e); console.log("raw contract terms were", payStatus.contractTermsRaw); - return ( - - Invalid contract terms. - - ); + return Invalid contract terms.; } if (!contractTerms) { @@ -149,7 +147,9 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) { {insufficientBalance ? (
-

Unable to pay: Your balance is insufficient.

+

+ Unable to pay: Your balance is insufficient. +

) : null} @@ -168,7 +168,8 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) { doPayment()}> + onClick={() => doPayment()} + > {i18n.str`Confirm payment`} diff --git a/src/webex/pages/payback.html b/src/webex/pages/payback.html index d6fe334c8..706949544 100644 --- a/src/webex/pages/payback.html +++ b/src/webex/pages/payback.html @@ -1,34 +1,34 @@ + + + Taler Wallet: Payback - - - Taler Wallet: Payback + - + - + + - - - - + +
diff --git a/src/webex/pages/popup.css b/src/webex/pages/popup.css index 4cae66177..cca002399 100644 --- a/src/webex/pages/popup.css +++ b/src/webex/pages/popup.css @@ -1,4 +1,3 @@ - /** * @author Gabor X. Toth * @author Marcello Stanisci @@ -6,182 +5,181 @@ */ body { - min-height: 20em; - width: 30em; - margin: 0; - padding: 0; - max-height: 800px; - overflow: hidden; - background-color: #f8faf7; - font-family: Arial, Helvetica, sans-serif; + min-height: 20em; + width: 30em; + margin: 0; + padding: 0; + max-height: 800px; + overflow: hidden; + background-color: #f8faf7; + font-family: Arial, Helvetica, sans-serif; } .nav { - background-color: #033; - padding: 0.5em 0; + background-color: #033; + padding: 0.5em 0; } .nav a { - color: #f8faf7; - padding: 0.7em 1.4em; - text-decoration: none; + color: #f8faf7; + padding: 0.7em 1.4em; + text-decoration: none; } .nav a.active { - background-color: #f8faf7; - color: #000; - font-weight: bold; + background-color: #f8faf7; + color: #000; + font-weight: bold; } - .container { - overflow-y: scroll; - max-height: 400px; + overflow-y: scroll; + max-height: 400px; } .abbrev { - text-decoration-style: dotted; + text-decoration-style: dotted; } #content { - padding: 1em; + padding: 1em; } - #wallet-table .amount { - text-align: right; + text-align: right; } .hidden { - display: none; + display: none; } #transactions-table th, #transactions-table td { - padding: 0.2em 0.5em; + padding: 0.2em 0.5em; } #reserve-create table { - width: 100%; + width: 100%; } #reserve-create table td.label { - width: 5em; + width: 5em; } #reserve-create table .input input[type="text"] { - width: 100%; + width: 100%; } .historyItem { - min-width: 380px; - display: flex; - flex-direction: row; - border-bottom: 1px solid #d9dbd8; - padding: 0.5em; - align-items: center; - } - - .historyItem .amount { - font-size: 110%; - font-weight: bold; - text-align: right; - } - - .historyDate, - .historyTitle, - .historyText, - .historySmall { - margin: 0.3em; - } - - .historyDate { - font-size: 90%; - color: slategray; - text-align: right; - } - - .historyLeft { - display: flex; - flex-direction: column; - text-align: right; - } - - .historyContent { - flex: 1; - } - - .historyTitle { - font-weight: 400; - } - - .historyText { - font-size: 90%; - } - - .historySmall { - font-size: 70%; - text-transform: uppercase; - } - - .historyAmount { - flex-grow: 1; - } - - .historyAmount .primary { - font-size: 100%; - } - - .historyAmount .secondary { - font-size: 80%; - } - - .historyAmount .positive { - color: #088; - } - - .historyAmount .positive:before { - content: "+"; - } - - .historyAmount .negative { - color: #800 - } - - .historyAmount .negative:before { - color: #800; - content: "-"; - } - .icon { - margin: 0 10px; - text-align: center; - width: 35px; - font-size: 20px; - border-radius: 50%; - background: #ccc; - color: #fff; - padding-top: 4px; - height: 30px; - } - - .option { - text-transform: uppercase; - text-align: right; - padding: 0.4em; - font-size: 0.9em; - } - - input[type=checkbox], input[type=radio] { - vertical-align: middle; - position: relative; - bottom: 1px; - } - - input[type=radio] { - bottom: 2px; - } - - .balance { - text-align: center; - padding-top: 2em; - } \ No newline at end of file + min-width: 380px; + display: flex; + flex-direction: row; + border-bottom: 1px solid #d9dbd8; + padding: 0.5em; + align-items: center; +} + +.historyItem .amount { + font-size: 110%; + font-weight: bold; + text-align: right; +} + +.historyDate, +.historyTitle, +.historyText, +.historySmall { + margin: 0.3em; +} + +.historyDate { + font-size: 90%; + color: slategray; + text-align: right; +} + +.historyLeft { + display: flex; + flex-direction: column; + text-align: right; +} + +.historyContent { + flex: 1; +} + +.historyTitle { + font-weight: 400; +} + +.historyText { + font-size: 90%; +} + +.historySmall { + font-size: 70%; + text-transform: uppercase; +} + +.historyAmount { + flex-grow: 1; +} + +.historyAmount .primary { + font-size: 100%; +} + +.historyAmount .secondary { + font-size: 80%; +} + +.historyAmount .positive { + color: #088; +} + +.historyAmount .positive:before { + content: "+"; +} + +.historyAmount .negative { + color: #800; +} + +.historyAmount .negative:before { + color: #800; + content: "-"; +} +.icon { + margin: 0 10px; + text-align: center; + width: 35px; + font-size: 20px; + border-radius: 50%; + background: #ccc; + color: #fff; + padding-top: 4px; + height: 30px; +} + +.option { + text-transform: uppercase; + text-align: right; + padding: 0.4em; + font-size: 0.9em; +} + +input[type="checkbox"], +input[type="radio"] { + vertical-align: middle; + position: relative; + bottom: 1px; +} + +input[type="radio"] { + bottom: 2px; +} + +.balance { + text-align: center; + padding-top: 2em; +} diff --git a/src/webex/pages/popup.html b/src/webex/pages/popup.html index 7929da765..030641d60 100644 --- a/src/webex/pages/popup.html +++ b/src/webex/pages/popup.html @@ -1,18 +1,16 @@ + + - - + + - - - - - - - - -
- + + + + +
+ diff --git a/src/webex/pages/popup.tsx b/src/webex/pages/popup.tsx index 44f45f9db..7b20f2227 100644 --- a/src/webex/pages/popup.tsx +++ b/src/webex/pages/popup.tsx @@ -29,10 +29,7 @@ import * as i18n from "../i18n"; import { AmountJson } from "../../util/amounts"; import * as Amounts from "../../util/amounts"; -import { - WalletBalance, - WalletBalanceEntry, -} from "../../types/walletTypes"; +import { WalletBalance, WalletBalanceEntry } from "../../types/walletTypes"; import { abbrev, @@ -98,7 +95,7 @@ class Router extends React.Component { console.log("rendering route", route); let defaultChild: React.ReactChild | null = null; let foundChild: React.ReactChild | null = null; - React.Children.forEach(this.props.children, child => { + React.Children.forEach(this.props.children, (child) => { const childProps: any = (child as any).props; if (!childProps) { return; @@ -188,7 +185,7 @@ function bigAmount(amount: AmountJson): JSX.Element { const v = amount.value + amount.fraction / Amounts.fractionalBase; return ( - {v}{" "} + {v}{" "} {amount.currency} ); @@ -281,7 +278,7 @@ class WalletBalanceView extends React.Component { ); } - const l = [incoming, payment].filter(x => x !== undefined); + const l = [incoming, payment].filter((x) => x !== undefined); if (l.length === 0) { return ; } @@ -300,7 +297,7 @@ class WalletBalanceView extends React.Component { const wallet = this.balance; if (this.gotError) { return ( -
+

{i18n.str`Error: could not retrieve balance information.`}

Click here for help and @@ -313,7 +310,7 @@ class WalletBalanceView extends React.Component { return ; } console.log(wallet); - const listing = Object.keys(wallet.byCurrency).map(key => { + const listing = Object.keys(wallet.byCurrency).map((key) => { const entry: WalletBalanceEntry = wallet.byCurrency[key]; return (

@@ -321,7 +318,11 @@ class WalletBalanceView extends React.Component {

); }); - return listing.length > 0 ?
{listing}
: ; + return listing.length > 0 ? ( +
{listing}
+ ) : ( + + ); } } @@ -356,7 +357,7 @@ function HistoryItem({ invalid, timestamp, icon, - negative = false + negative = false, }: HistoryItemProps) { function formatDate(timestamp: number | "never") { if (timestamp !== "never") { @@ -425,7 +426,7 @@ function HistoryItem({ function amountDiff( total: string | Amounts.AmountJson, - partial: string | Amounts.AmountJson + partial: string | Amounts.AmountJson, ): Amounts.AmountJson | string { let a = typeof total === "string" ? Amounts.parse(total) : total; let b = typeof partial === "string" ? Amounts.parse(partial) : partial; @@ -436,12 +437,11 @@ function amountDiff( } } - function parseSummary(summary: string) { let parsed = summary.split(/: (.+)/); return { merchant: parsed[0], - item: parsed[1] + item: parsed[1], }; } @@ -454,7 +454,7 @@ function formatHistoryItem(historyItem: HistoryEvent) { small={i18n.str`Refresh sessions has completed`} fees={amountDiff( historyItem.amountRefreshedRaw, - historyItem.amountRefreshedEffective + historyItem.amountRefreshedEffective, )} /> ); @@ -462,7 +462,7 @@ function formatHistoryItem(historyItem: HistoryEvent) { case "order-refused": { const { merchant, item } = parseSummary( - historyItem.orderShortInfo.summary + historyItem.orderShortInfo.summary, ); return ( - + {item ? abbrev(item, 30) : null} @@ -542,14 +539,11 @@ function formatHistoryItem(historyItem: HistoryEvent) { case "order-accepted": { const url = historyItem.orderShortInfo.fulfillmentUrl; const { merchant, item } = parseSummary( - historyItem.orderShortInfo.summary + historyItem.orderShortInfo.summary, ); const fulfillmentLinkElem = ( - + {item ? abbrev(item, 40) : null} @@ -573,7 +567,7 @@ function formatHistoryItem(historyItem: HistoryEvent) { small={i18n.str`Reserve balance updated`} fees={amountDiff( historyItem.amountExpected, - historyItem.amountReserveBalance + historyItem.amountReserveBalance, )} /> ); @@ -593,9 +587,9 @@ function formatHistoryItem(historyItem: HistoryEvent) { fees={amountDiff( amountDiff( historyItem.amountRefundedRaw, - historyItem.amountRefundedInvalid + historyItem.amountRefundedInvalid, ), - historyItem.amountRefundedEffective + historyItem.amountRefundedEffective, )} /> ); @@ -604,7 +598,7 @@ function formatHistoryItem(historyItem: HistoryEvent) { const exchange = new URL(historyItem.exchangeBaseUrl).host; const fees = amountDiff( historyItem.amountWithdrawnRaw, - historyItem.amountWithdrawnEffective + historyItem.amountWithdrawnEffective, ); return ( { "refreshed", "reserve-balance-updated", "exchange-updated", - "exchange-added" + "exchange-added", ]; - + componentWillMount() { this.update(); this.setState({ filter: true }); @@ -678,7 +672,7 @@ class WalletHistory extends React.Component { } update() { - chrome.runtime.sendMessage({ type: "get-history" }, resp => { + chrome.runtime.sendMessage({ type: "get-history" }, (resp) => { if (this.unmounted) { return; } @@ -709,15 +703,13 @@ class WalletHistory extends React.Component { } const listing: any[] = []; - const messages = history - .reverse() - .filter(hEvent => { - if (!this.state.filter) return true; - return this.hidenTypes.indexOf(hEvent.type) === -1; - }); + const messages = history.reverse().filter((hEvent) => { + if (!this.state.filter) return true; + return this.hidenTypes.indexOf(hEvent.type) === -1; + }); for (const record of messages) { - const item = (); + const item = ; listing.push(item); } @@ -821,5 +813,5 @@ function WalletPopup() { registerMountPage(() => { chrome.runtime.connect({ name: "popup" }); - return + return ; }); diff --git a/src/webex/pages/redirect.html b/src/webex/pages/redirect.html index 9d07d3d2b..67fddb527 100644 --- a/src/webex/pages/redirect.html +++ b/src/webex/pages/redirect.html @@ -1,14 +1,12 @@ + + - - - - - - - - Redirecting to extension page ... - + + + + Redirecting to extension page ... + diff --git a/src/webex/pages/redirect.js b/src/webex/pages/redirect.js index 879f5b530..547b225bd 100644 --- a/src/webex/pages/redirect.js +++ b/src/webex/pages/redirect.js @@ -2,7 +2,7 @@ * This is the entry point for redirects, and should be the only * web-accessible resource declared in the manifest. This prevents * malicious websites from embedding wallet pages in them. - * + * * We still need this redirect page since a webRequest can only directly * redirect to pages inside the extension that are a web-accessible resource. */ diff --git a/src/webex/pages/refund.html b/src/webex/pages/refund.html index 203fda21b..c671bb193 100644 --- a/src/webex/pages/refund.html +++ b/src/webex/pages/refund.html @@ -1,16 +1,16 @@ + + + Taler Wallet: Refund Status - - - Taler Wallet: Refund Status + - + - - - - + + +
diff --git a/src/webex/pages/refund.tsx b/src/webex/pages/refund.tsx index 2a3f65d21..389d5e569 100644 --- a/src/webex/pages/refund.tsx +++ b/src/webex/pages/refund.tsx @@ -65,11 +65,10 @@ function RefundStatusView(props: { talerRefundUri: string }) {

Refund Status

The product {purchaseDetails.contractTerms.summary!} has - received a total refund of . -

-

- Note that additional fees from the exchange may apply. + received a total refund of{" "} + .

+

Note that additional fees from the exchange may apply.

); } diff --git a/src/webex/pages/reset-required.html b/src/webex/pages/reset-required.html index 72b176b4d..124d5f46f 100644 --- a/src/webex/pages/reset-required.html +++ b/src/webex/pages/reset-required.html @@ -1,30 +1,27 @@ + + + Taler Wallet: Select Taler Provider - - - Taler Wallet: Select Taler Provider + + + - - - + + - - - - - - - - -
-
-
- + + + +
+
+
+ diff --git a/src/webex/pages/reset-required.tsx b/src/webex/pages/reset-required.tsx index 6631705af..81f21f459 100644 --- a/src/webex/pages/reset-required.tsx +++ b/src/webex/pages/reset-required.tsx @@ -14,7 +14,6 @@ TALER; see the file COPYING. If not, see */ - /** * Page to inform the user when a database reset is required. * @@ -38,16 +37,15 @@ class State { resetRequired: boolean; } - class ResetNotification extends React.Component { constructor(props: any) { super(props); - this.state = {checked: false, resetRequired: true}; + this.state = { checked: false, resetRequired: true }; setInterval(() => this.update(), 500); } async update() { const res = await wxApi.checkUpgrade(); - this.setState({resetRequired: res.dbResetRequired}); + this.setState({ resetRequired: res.dbResetRequired }); } render() { if (this.state.resetRequired) { @@ -55,32 +53,42 @@ class ResetNotification extends React.Component {

Manual Reset Reqired

- The wallet's database in your browser is incompatible with the {" "} - currently installed wallet. Please reset manually. + The wallet's database in your browser is incompatible with the{" "} + currently installed wallet. Please reset manually.

-

Once the database format has stabilized, we will provide automatic upgrades.

- this.setState({checked: e.target.checked})} />{" "} +

+ Once the database format has stabilized, we will provide automatic + upgrades. +

+ this.setState({ checked: e.target.checked })} + />{" "}
- +
); } return (
-

Everything is fine!

- A reset is not required anymore, you can close this page. +

Everything is fine!

A reset is not required anymore, you can + close this page.
); } } - document.addEventListener("DOMContentLoaded", () => { - ReactDOM.render(, document.getElementById( "container")!); + ReactDOM.render(, document.getElementById("container")!); }); diff --git a/src/webex/pages/return-coins.html b/src/webex/pages/return-coins.html index c0ab218d2..54106f3e6 100644 --- a/src/webex/pages/return-coins.html +++ b/src/webex/pages/return-coins.html @@ -1,17 +1,17 @@ + + + Taler Wallet: Return Coins to Bank Account - - - Taler Wallet: Return Coins to Bank Account + + - - + - - - - + + +
diff --git a/src/webex/pages/return-coins.tsx b/src/webex/pages/return-coins.tsx index 7c835da0a..fd9238ee2 100644 --- a/src/webex/pages/return-coins.tsx +++ b/src/webex/pages/return-coins.tsx @@ -20,7 +20,6 @@ * @author Florian Dold */ - /** * Imports. */ @@ -28,20 +27,13 @@ import { AmountJson } from "../../util/amounts"; import * as Amounts from "../../util/amounts"; -import { - SenderWireInfos, - WalletBalance, -} from "../../types/walletTypes"; +import { SenderWireInfos, WalletBalance } from "../../types/walletTypes"; import * as i18n from "../i18n"; import * as wire from "../../util/wire"; -import { - getBalance, - getSenderWireInfos, - returnCoins, -} from "../wxApi"; +import { getBalance, getSenderWireInfos, returnCoins } from "../wxApi"; import { renderAmount } from "../renderHtml"; @@ -60,17 +52,27 @@ interface ReturnSelectionItemState { currency: string; } -class ReturnSelectionItem extends React.Component { +class ReturnSelectionItem extends React.Component< + ReturnSelectionItemProps, + ReturnSelectionItemState +> { constructor(props: ReturnSelectionItemProps) { super(props); const exchange = this.props.exchangeUrl; const wireTypes = this.props.senderWireInfos.exchangeWireTypes; - const supportedWires = this.props.senderWireInfos.senderWires.filter((x) => { - return wireTypes[exchange] && wireTypes[exchange].indexOf((x as any).type) >= 0; - }); + const supportedWires = this.props.senderWireInfos.senderWires.filter( + (x) => { + return ( + wireTypes[exchange] && + wireTypes[exchange].indexOf((x as any).type) >= 0 + ); + }, + ); this.state = { currency: props.balance.byExchange[props.exchangeUrl].available.currency, - selectedValue: Amounts.toString(props.balance.byExchange[props.exchangeUrl].available), + selectedValue: Amounts.toString( + props.balance.byExchange[props.exchangeUrl].available, + ), selectedWire: "", supportedWires, }; @@ -83,28 +85,46 @@ class ReturnSelectionItem extends React.Component

Exchange {exchange}

Available amount: {renderAmount(byExchange[exchange].available)}

-

Supported wire methods: {wireTypes[exchange].length ? wireTypes[exchange].join(", ") : "none"}

-

Wire {""} - this.setState({selectedValue: evt.target.value})} - style={{textAlign: "center"}} - /> {this.props.balance.byExchange[exchange].available.currency} {""} - to account {""} - . +

+ Supported wire methods:{" "} + {wireTypes[exchange].length ? wireTypes[exchange].join(", ") : "none"} +

+

+ Wire {""} + + this.setState({ selectedValue: evt.target.value }) + } + style={{ textAlign: "center" }} + />{" "} + {this.props.balance.byExchange[exchange].available.currency} {""} + to account {""} + + .

- {this.state.selectedWire - ? - : null} + {this.state.selectedWire ? ( + + ) : null}
); } @@ -133,16 +153,23 @@ interface ReturnSelectionListProps { selectDetail(d: SelectedDetail): void; } -class ReturnSelectionList extends React.Component { +class ReturnSelectionList extends React.Component< + ReturnSelectionListProps, + {} +> { render(): JSX.Element { const byExchange = this.props.balance.byExchange; const exchanges = Object.keys(byExchange); if (!exchanges.length) { - return

Currently no funds available to transfer.

; + return ( +

Currently no funds available to transfer.

+ ); } return (
- {exchanges.map((e) => )} + {exchanges.map((e) => ( + + ))}
); } @@ -154,7 +181,6 @@ interface SelectedDetail { exchange: string; } - interface ReturnConfirmationProps { detail: SelectedDetail; cancel(): void; @@ -165,11 +191,19 @@ class ReturnConfirmation extends React.Component { render() { return (
-

Please confirm if you want to transmit {renderAmount(this.props.detail.amount)} at {""} - {this.props.detail.exchange} to account {""} - {wire.summarizeWire(this.props.detail.senderWire)}. +

+ Please confirm if you want to transmit{" "} + {renderAmount(this.props.detail.amount)} at {""} + {this.props.detail.exchange} to account {""} + + {wire.summarizeWire(this.props.detail.senderWire)} + + .

-

diff --git a/src/webex/pages/show-db.ts b/src/webex/pages/show-db.ts
index d95951385..16ea80d2d 100644
--- a/src/webex/pages/show-db.ts
+++ b/src/webex/pages/show-db.ts
@@ -14,15 +14,19 @@
  TALER; see the file COPYING.  If not, see 
  */
 
-
 /**
  * Wallet database dump for debugging.
  *
  * @author Florian Dold
  */
 
-function replacer(match: string, pIndent: string, pKey: string, pVal: string,
-                  pEnd: string) {
+function replacer(
+  match: string,
+  pIndent: string,
+  pKey: string,
+  pVal: string,
+  pEnd: string,
+) {
   const key = "";
   const val = "";
   const str = "";
@@ -36,18 +40,18 @@ function replacer(match: string, pIndent: string, pKey: string, pVal: string,
   return r + (pEnd || "");
 }
 
-
 function prettyPrint(obj: any) {
-  const jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/mg;
+  const jsonLine = /^( *)("[\w]+": )?("[^"]*"|[\w.+-]*)?([,[{])?$/gm;
   return JSON.stringify(obj, null as any, 3)
-             .replace(/&/g, "&").replace(/\\"/g, """)
-             .replace(//g, ">")
-             .replace(jsonLine, replacer);
+    .replace(/&/g, "&")
+    .replace(/\\"/g, """)
+    .replace(//g, ">")
+    .replace(jsonLine, replacer);
 }
 
-
 document.addEventListener("DOMContentLoaded", () => {
-  chrome.runtime.sendMessage({type: "dump-db"}, (resp) => {
+  chrome.runtime.sendMessage({ type: "dump-db" }, (resp) => {
     const el = document.getElementById("dump");
     if (!el) {
       throw Error();
@@ -57,16 +61,18 @@ document.addEventListener("DOMContentLoaded", () => {
     document.getElementById("download")!.addEventListener("click", (evt) => {
       console.log("creating download");
       const element = document.createElement("a");
-      element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(JSON.stringify(resp)));
+      element.setAttribute(
+        "href",
+        "data:text/plain;charset=utf-8," +
+          encodeURIComponent(JSON.stringify(resp)),
+      );
       element.setAttribute("download", "wallet-dump.txt");
       element.style.display = "none";
       document.body.appendChild(element);
       element.click();
     });
-
   });
 
-
   const fileInput = document.getElementById("fileInput")! as HTMLInputElement;
   fileInput.onchange = (evt) => {
     if (!fileInput.files || fileInput.files.length !== 1) {
@@ -79,9 +85,12 @@ document.addEventListener("DOMContentLoaded", () => {
       console.log("got file");
       const dump = JSON.parse(e.target.result);
       console.log("parsed contents", dump);
-      chrome.runtime.sendMessage({ type: "import-db", detail: { dump } }, (resp) => {
-        alert("loaded");
-      });
+      chrome.runtime.sendMessage(
+        { type: "import-db", detail: { dump } },
+        (resp) => {
+          alert("loaded");
+        },
+      );
     };
     console.log("reading file", file);
     fr.readAsText(file);
diff --git a/src/webex/pages/tip.html b/src/webex/pages/tip.html
index 72d91a123..0625640ed 100644
--- a/src/webex/pages/tip.html
+++ b/src/webex/pages/tip.html
@@ -1,24 +1,21 @@
 
 
+  
+    
+    Taler Wallet: Received Tip
 
-
-  
-  Taler Wallet: Received Tip
+    
+    
+    
 
-  
-  
-  
-
-  
-  
-
-
-
-
-  
-

GNU Taler Wallet

-
-
- + + + + +
+

GNU Taler Wallet

+
+
+ diff --git a/src/webex/pages/tip.tsx b/src/webex/pages/tip.tsx index c44b343a4..35e033c0d 100644 --- a/src/webex/pages/tip.tsx +++ b/src/webex/pages/tip.tsx @@ -28,13 +28,16 @@ import * as i18n from "../i18n"; import { acceptTip, getReserveCreationInfo, getTipStatus } from "../wxApi"; -import { WithdrawDetailView, renderAmount, ProgressButton } from "../renderHtml"; +import { + WithdrawDetailView, + renderAmount, + ProgressButton, +} from "../renderHtml"; import * as Amounts from "../../util/amounts"; import { useState, useEffect } from "react"; import { TipStatus } from "../../types/walletTypes"; - function TipDisplay(props: { talerTipUri: string }) { const [tipStatus, setTipStatus] = useState(undefined); const [discarded, setDiscarded] = useState(false); @@ -88,8 +91,7 @@ function TipDisplay(props: { talerTipUri: string }) {
accept()}> Accept Tip - - {" "} + {" "} diff --git a/src/webex/pages/welcome.html b/src/webex/pages/welcome.html index 9a96d04a7..8f17891e2 100644 --- a/src/webex/pages/welcome.html +++ b/src/webex/pages/welcome.html @@ -1,24 +1,21 @@ + + + Taler Wallet: Withdraw - - - Taler Wallet: Withdraw + + + - - - - - - - - - - -
-

GNU Taler Wallet Installed!

-
Loading...
-
- + + + + +
+

GNU Taler Wallet Installed!

+
Loading...
+
+ diff --git a/src/webex/pages/welcome.tsx b/src/webex/pages/welcome.tsx index e8f7028ed..83f4f01d5 100644 --- a/src/webex/pages/welcome.tsx +++ b/src/webex/pages/welcome.tsx @@ -68,7 +68,7 @@ function Diagnostics() { >

Problems detected:

    - {diagnostics.errors.map(errMsg => ( + {diagnostics.errors.map((errMsg) => (
  1. {errMsg}
  2. ))}
diff --git a/src/webex/pages/withdraw.html b/src/webex/pages/withdraw.html index e5c527275..861b219f5 100644 --- a/src/webex/pages/withdraw.html +++ b/src/webex/pages/withdraw.html @@ -1,24 +1,21 @@ + + + Taler Wallet: Withdraw - - - Taler Wallet: Withdraw + + + - - - + + + - - - - - - -
-

GNU Taler Wallet

+ +
+

GNU Taler Wallet

-
- - +
+ diff --git a/src/webex/pages/withdraw.tsx b/src/webex/pages/withdraw.tsx index c123e2a6f..7a2665314 100644 --- a/src/webex/pages/withdraw.tsx +++ b/src/webex/pages/withdraw.tsx @@ -127,7 +127,7 @@ function NewExchangeSelection(props: { talerWithdrawUri: string }) {

setCustomUrl(e.target.value)} + onChange={(e) => setCustomUrl(e.target.value)} value={customUrl} />

diff --git a/src/webex/renderHtml.tsx b/src/webex/renderHtml.tsx index 3204c410d..08e7de607 100644 --- a/src/webex/renderHtml.tsx +++ b/src/webex/renderHtml.tsx @@ -143,7 +143,7 @@ function AuditorDetailsView(props: { } return (
- {(rci.exchangeInfo.details?.auditors ?? []).map(a => ( + {(rci.exchangeInfo.details?.auditors ?? []).map((a) => (

Auditor {a.auditor_url}

@@ -214,7 +214,7 @@ function FeeDetailsView(props: { , - {rci!.wireFees.feesForType[s].map(f => ( + {rci!.wireFees.feesForType[s].map((f) => ( {stringifyTimestamp(f.endStamp)} {renderAmount(f.wireFee)} @@ -232,7 +232,10 @@ function FeeDetailsView(props: {

Overview

- Public key: + Public key:{" "} +

{i18n.str`Withdrawal fees:`} {withdrawFee} @@ -240,8 +243,9 @@ function FeeDetailsView(props: {

{i18n.str`Rounding loss:`} {overhead}

-

{i18n.str`Earliest expiration (for deposit): ${ - stringifyTimestamp(rci.earliestDepositExpiration)}`}

+

{i18n.str`Earliest expiration (for deposit): ${stringifyTimestamp( + rci.earliestDepositExpiration, + )}`}

Coin Fees

diff --git a/src/webex/style/pure.css b/src/webex/style/pure.css index 739113970..88a4bb7d7 100644 --- a/src/webex/style/pure.css +++ b/src/webex/style/pure.css @@ -449,7 +449,7 @@ th { .hidden, [hidden] { - display: none !important; + display: none !important; } /** @@ -457,20 +457,20 @@ th { * aspect ratio. */ .pure-img { - max-width: 100%; - height: auto; - display: block; + max-width: 100%; + height: auto; + display: block; } /*csslint regex-selectors:false, known-properties:false, duplicate-properties:false*/ .pure-g { - letter-spacing: -0.31em; /* Webkit: collapse white-space between units */ - *letter-spacing: normal; /* reset IE < 8 */ - *word-spacing: -0.43em; /* IE < 8: collapse white-space between units */ - text-rendering: optimizespeed; /* Webkit: fixes text-rendering: optimizeLegibility */ + letter-spacing: -0.31em; /* Webkit: collapse white-space between units */ + *letter-spacing: normal; /* reset IE < 8 */ + *word-spacing: -0.43em; /* IE < 8: collapse white-space between units */ + text-rendering: optimizespeed; /* Webkit: fixes text-rendering: optimizeLegibility */ - /* + /* Sets the font stack to fonts known to work properly with the above letter and word spacings. See: https://github.com/yahoo/pure/issues/41/ @@ -486,28 +486,28 @@ th { * Helvetica, Arial, sans-serif: Common font stack on OS X and Windows. */ - font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif; + font-family: FreeSans, Arimo, "Droid Sans", Helvetica, Arial, sans-serif; - /* Use flexbox when possible to avoid `letter-spacing` side-effects. */ - display: -webkit-box; - display: -webkit-flex; - display: -ms-flexbox; - display: flex; - -webkit-flex-flow: row wrap; - -ms-flex-flow: row wrap; - flex-flow: row wrap; + /* Use flexbox when possible to avoid `letter-spacing` side-effects. */ + display: -webkit-box; + display: -webkit-flex; + display: -ms-flexbox; + display: flex; + -webkit-flex-flow: row wrap; + -ms-flex-flow: row wrap; + flex-flow: row wrap; - /* Prevents distributing space between rows */ - -webkit-align-content: flex-start; - -ms-flex-line-pack: start; - align-content: flex-start; + /* Prevents distributing space between rows */ + -webkit-align-content: flex-start; + -ms-flex-line-pack: start; + align-content: flex-start; } /* IE10 display: -ms-flexbox (and display: flex in IE 11) does not work inside a table; fall back to block and rely on font hack */ @media all and (-ms-high-contrast: none), (-ms-high-contrast: active) { - table .pure-g { - display: block; - } + table .pure-g { + display: block; + } } /* Opera as of 12 on Windows needs word-spacing. @@ -516,25 +516,25 @@ th { */ .opera-only :-o-prefocus, .pure-g { - word-spacing: -0.43em; + word-spacing: -0.43em; } .pure-u { - display: inline-block; - *display: inline; /* IE < 8: fake inline-block */ - zoom: 1; - letter-spacing: normal; - word-spacing: normal; - vertical-align: top; - text-rendering: auto; + display: inline-block; + *display: inline; /* IE < 8: fake inline-block */ + zoom: 1; + letter-spacing: normal; + word-spacing: normal; + vertical-align: top; + text-rendering: auto; } /* Resets the font family back to the OS/browser's default sans-serif font, this the same font stack that Normalize.css sets for the `body`. */ -.pure-g [class *= "pure-u"] { - font-family: sans-serif; +.pure-g [class*="pure-u"] { + font-family: sans-serif; } .pure-u-1, @@ -583,245 +583,254 @@ this the same font stack that Normalize.css sets for the `body`. .pure-u-22-24, .pure-u-23-24, .pure-u-24-24 { - display: inline-block; - *display: inline; - zoom: 1; - letter-spacing: normal; - word-spacing: normal; - vertical-align: top; - text-rendering: auto; + display: inline-block; + *display: inline; + zoom: 1; + letter-spacing: normal; + word-spacing: normal; + vertical-align: top; + text-rendering: auto; } .pure-u-1-24 { - width: 4.1667%; - *width: 4.1357%; + width: 4.1667%; + *width: 4.1357%; } .pure-u-1-12, .pure-u-2-24 { - width: 8.3333%; - *width: 8.3023%; + width: 8.3333%; + *width: 8.3023%; } .pure-u-1-8, .pure-u-3-24 { - width: 12.5000%; - *width: 12.4690%; + width: 12.5%; + *width: 12.469%; } .pure-u-1-6, .pure-u-4-24 { - width: 16.6667%; - *width: 16.6357%; + width: 16.6667%; + *width: 16.6357%; } .pure-u-1-5 { - width: 20%; - *width: 19.9690%; + width: 20%; + *width: 19.969%; } .pure-u-5-24 { - width: 20.8333%; - *width: 20.8023%; + width: 20.8333%; + *width: 20.8023%; } .pure-u-1-4, .pure-u-6-24 { - width: 25%; - *width: 24.9690%; + width: 25%; + *width: 24.969%; } .pure-u-7-24 { - width: 29.1667%; - *width: 29.1357%; + width: 29.1667%; + *width: 29.1357%; } .pure-u-1-3, .pure-u-8-24 { - width: 33.3333%; - *width: 33.3023%; + width: 33.3333%; + *width: 33.3023%; } .pure-u-3-8, .pure-u-9-24 { - width: 37.5000%; - *width: 37.4690%; + width: 37.5%; + *width: 37.469%; } .pure-u-2-5 { - width: 40%; - *width: 39.9690%; + width: 40%; + *width: 39.969%; } .pure-u-5-12, .pure-u-10-24 { - width: 41.6667%; - *width: 41.6357%; + width: 41.6667%; + *width: 41.6357%; } .pure-u-11-24 { - width: 45.8333%; - *width: 45.8023%; + width: 45.8333%; + *width: 45.8023%; } .pure-u-1-2, .pure-u-12-24 { - width: 50%; - *width: 49.9690%; + width: 50%; + *width: 49.969%; } .pure-u-13-24 { - width: 54.1667%; - *width: 54.1357%; + width: 54.1667%; + *width: 54.1357%; } .pure-u-7-12, .pure-u-14-24 { - width: 58.3333%; - *width: 58.3023%; + width: 58.3333%; + *width: 58.3023%; } .pure-u-3-5 { - width: 60%; - *width: 59.9690%; + width: 60%; + *width: 59.969%; } .pure-u-5-8, .pure-u-15-24 { - width: 62.5000%; - *width: 62.4690%; + width: 62.5%; + *width: 62.469%; } .pure-u-2-3, .pure-u-16-24 { - width: 66.6667%; - *width: 66.6357%; + width: 66.6667%; + *width: 66.6357%; } .pure-u-17-24 { - width: 70.8333%; - *width: 70.8023%; + width: 70.8333%; + *width: 70.8023%; } .pure-u-3-4, .pure-u-18-24 { - width: 75%; - *width: 74.9690%; + width: 75%; + *width: 74.969%; } .pure-u-19-24 { - width: 79.1667%; - *width: 79.1357%; + width: 79.1667%; + *width: 79.1357%; } .pure-u-4-5 { - width: 80%; - *width: 79.9690%; + width: 80%; + *width: 79.969%; } .pure-u-5-6, .pure-u-20-24 { - width: 83.3333%; - *width: 83.3023%; + width: 83.3333%; + *width: 83.3023%; } .pure-u-7-8, .pure-u-21-24 { - width: 87.5000%; - *width: 87.4690%; + width: 87.5%; + *width: 87.469%; } .pure-u-11-12, .pure-u-22-24 { - width: 91.6667%; - *width: 91.6357%; + width: 91.6667%; + *width: 91.6357%; } .pure-u-23-24 { - width: 95.8333%; - *width: 95.8023%; + width: 95.8333%; + *width: 95.8023%; } .pure-u-1, .pure-u-1-1, .pure-u-5-5, .pure-u-24-24 { - width: 100%; + width: 100%; } .pure-button { - /* Structure */ - display: inline-block; - zoom: 1; - line-height: normal; - white-space: nowrap; - vertical-align: middle; - text-align: center; - cursor: pointer; - -webkit-user-drag: none; - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; - box-sizing: border-box; + /* Structure */ + display: inline-block; + zoom: 1; + line-height: normal; + white-space: nowrap; + vertical-align: middle; + text-align: center; + cursor: pointer; + -webkit-user-drag: none; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + box-sizing: border-box; } /* Firefox: Get rid of the inner focus border */ .pure-button::-moz-focus-inner { - padding: 0; - border: 0; + padding: 0; + border: 0; } /* Inherit .pure-g styles */ .pure-button-group { - letter-spacing: -0.31em; /* Webkit: collapse white-space between units */ - *letter-spacing: normal; /* reset IE < 8 */ - *word-spacing: -0.43em; /* IE < 8: collapse white-space between units */ - text-rendering: optimizespeed; /* Webkit: fixes text-rendering: optimizeLegibility */ + letter-spacing: -0.31em; /* Webkit: collapse white-space between units */ + *letter-spacing: normal; /* reset IE < 8 */ + *word-spacing: -0.43em; /* IE < 8: collapse white-space between units */ + text-rendering: optimizespeed; /* Webkit: fixes text-rendering: optimizeLegibility */ } .opera-only :-o-prefocus, .pure-button-group { - word-spacing: -0.43em; + word-spacing: -0.43em; } .pure-button-group .pure-button { - letter-spacing: normal; - word-spacing: normal; - vertical-align: top; - text-rendering: auto; + letter-spacing: normal; + word-spacing: normal; + vertical-align: top; + text-rendering: auto; } /*csslint outline-none:false*/ .pure-button { - font-family: inherit; - font-size: 100%; - padding: 0.5em 1em; - color: #444; /* rgba not supported (IE 8) */ - color: rgba(0, 0, 0, 0.80); /* rgba supported */ - border: 1px solid #999; /*IE 6/7/8*/ - border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/ - background-color: #E6E6E6; - text-decoration: none; - border-radius: 2px; + font-family: inherit; + font-size: 100%; + padding: 0.5em 1em; + color: #444; /* rgba not supported (IE 8) */ + color: rgba(0, 0, 0, 0.8); /* rgba supported */ + border: 1px solid #999; /*IE 6/7/8*/ + border: none rgba(0, 0, 0, 0); /*IE9 + everything else*/ + background-color: #e6e6e6; + text-decoration: none; + border-radius: 2px; } .pure-button-hover, .pure-button:hover, .pure-button:focus { - /* csslint ignore:start */ - filter: alpha(opacity=90); - /* csslint ignore:end */ - background-image: -webkit-linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10)); - background-image: linear-gradient(transparent, rgba(0,0,0, 0.05) 40%, rgba(0,0,0, 0.10)); + /* csslint ignore:start */ + filter: alpha(opacity=90); + /* csslint ignore:end */ + background-image: -webkit-linear-gradient( + transparent, + rgba(0, 0, 0, 0.05) 40%, + rgba(0, 0, 0, 0.1) + ); + background-image: linear-gradient( + transparent, + rgba(0, 0, 0, 0.05) 40%, + rgba(0, 0, 0, 0.1) + ); } .pure-button:focus { - outline: 0; + outline: 0; } .pure-button-active, .pure-button:active { - box-shadow: 0 0 0 1px rgba(0,0,0, 0.15) inset, 0 0 6px rgba(0,0,0, 0.20) inset; - border-color: #000\9; + box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.15) inset, + 0 0 6px rgba(0, 0, 0, 0.2) inset; + border-color: #000\9; } .pure-button[disabled], @@ -829,46 +838,45 @@ this the same font stack that Normalize.css sets for the `body`. .pure-button-disabled:hover, .pure-button-disabled:focus, .pure-button-disabled:active { - border: none; - background-image: none; - /* csslint ignore:start */ - filter: alpha(opacity=40); - /* csslint ignore:end */ - opacity: 0.40; - cursor: not-allowed; - box-shadow: none; - pointer-events: none; + border: none; + background-image: none; + /* csslint ignore:start */ + filter: alpha(opacity=40); + /* csslint ignore:end */ + opacity: 0.4; + cursor: not-allowed; + box-shadow: none; + pointer-events: none; } .pure-button-hidden { - display: none; + display: none; } .pure-button-primary, .pure-button-selected, a.pure-button-primary, a.pure-button-selected { - background-color: rgb(0, 120, 231); - color: #fff; + background-color: rgb(0, 120, 231); + color: #fff; } /* Button Groups */ .pure-button-group .pure-button { - margin: 0; - border-radius: 0; - border-right: 1px solid #111; /* fallback color for rgba() for IE7/8 */ - border-right: 1px solid rgba(0, 0, 0, 0.2); - + margin: 0; + border-radius: 0; + border-right: 1px solid #111; /* fallback color for rgba() for IE7/8 */ + border-right: 1px solid rgba(0, 0, 0, 0.2); } .pure-button-group .pure-button:first-child { - border-top-left-radius: 2px; - border-bottom-left-radius: 2px; + border-top-left-radius: 2px; + border-bottom-left-radius: 2px; } .pure-button-group .pure-button:last-child { - border-top-right-radius: 2px; - border-bottom-right-radius: 2px; - border-right: none; + border-top-right-radius: 2px; + border-bottom-right-radius: 2px; + border-right: none; } /*csslint box-model:false*/ @@ -895,13 +903,13 @@ so we can ignore the csslint warning. .pure-form input[type="color"], .pure-form select, .pure-form textarea { - padding: 0.5em 0.6em; - display: inline-block; - border: 1px solid #ccc; - box-shadow: inset 0 1px 3px #ddd; - border-radius: 4px; - vertical-align: middle; - box-sizing: border-box; + padding: 0.5em 0.6em; + display: inline-block; + border: 1px solid #ccc; + box-shadow: inset 0 1px 3px #ddd; + border-radius: 4px; + vertical-align: middle; + box-sizing: border-box; } /* @@ -909,22 +917,20 @@ Need to separate out the :not() selector from the rest of the CSS 2.1 selectors since IE8 won't execute CSS that contains a CSS3 selector. */ .pure-form input:not([type]) { - padding: 0.5em 0.6em; - display: inline-block; - border: 1px solid #ccc; - box-shadow: inset 0 1px 3px #ddd; - border-radius: 4px; - box-sizing: border-box; + padding: 0.5em 0.6em; + display: inline-block; + border: 1px solid #ccc; + box-shadow: inset 0 1px 3px #ddd; + border-radius: 4px; + box-sizing: border-box; } - /* Chrome (as of v.32/34 on OS X) needs additional room for color to display. */ /* May be able to remove this tweak as color inputs become more standardized across browsers. */ .pure-form input[type="color"] { - padding: 0.2em 0.5em; + padding: 0.2em 0.5em; } - .pure-form input[type="text"]:focus, .pure-form input[type="password"]:focus, .pure-form input[type="email"]:focus, @@ -941,8 +947,8 @@ since IE8 won't execute CSS that contains a CSS3 selector. .pure-form input[type="color"]:focus, .pure-form select:focus, .pure-form textarea:focus { - outline: 0; - border-color: #129FEA; + outline: 0; + border-color: #129fea; } /* @@ -950,20 +956,20 @@ Need to separate out the :not() selector from the rest of the CSS 2.1 selectors since IE8 won't execute CSS that contains a CSS3 selector. */ .pure-form input:not([type]):focus { - outline: 0; - border-color: #129FEA; + outline: 0; + border-color: #129fea; } .pure-form input[type="file"]:focus, .pure-form input[type="radio"]:focus, .pure-form input[type="checkbox"]:focus { - outline: thin solid #129FEA; - outline: 1px auto #129FEA; + outline: thin solid #129fea; + outline: 1px auto #129fea; } .pure-form .pure-checkbox, .pure-form .pure-radio { - margin: 0.5em 0; - display: block; + margin: 0.5em 0; + display: block; } .pure-form input[type="text"][disabled], @@ -982,9 +988,9 @@ since IE8 won't execute CSS that contains a CSS3 selector. .pure-form input[type="color"][disabled], .pure-form select[disabled], .pure-form textarea[disabled] { - cursor: not-allowed; - background-color: #eaeded; - color: #cad2d3; + cursor: not-allowed; + background-color: #eaeded; + color: #cad2d3; } /* @@ -992,53 +998,53 @@ Need to separate out the :not() selector from the rest of the CSS 2.1 selectors since IE8 won't execute CSS that contains a CSS3 selector. */ .pure-form input:not([type])[disabled] { - cursor: not-allowed; - background-color: #eaeded; - color: #cad2d3; + cursor: not-allowed; + background-color: #eaeded; + color: #cad2d3; } .pure-form input[readonly], .pure-form select[readonly], .pure-form textarea[readonly] { - background-color: #eee; /* menu hover bg color */ - color: #777; /* menu text color */ - border-color: #ccc; + background-color: #eee; /* menu hover bg color */ + color: #777; /* menu text color */ + border-color: #ccc; } .pure-form input:focus:invalid, .pure-form textarea:focus:invalid, .pure-form select:focus:invalid { - color: #b94a48; - border-color: #e9322d; + color: #b94a48; + border-color: #e9322d; } .pure-form input[type="file"]:focus:invalid:focus, .pure-form input[type="radio"]:focus:invalid:focus, .pure-form input[type="checkbox"]:focus:invalid:focus { - outline-color: #e9322d; + outline-color: #e9322d; } .pure-form select { - /* Normalizes the height; padding is not sufficient. */ - height: 2.25em; - border: 1px solid #ccc; - background-color: white; + /* Normalizes the height; padding is not sufficient. */ + height: 2.25em; + border: 1px solid #ccc; + background-color: white; } .pure-form select[multiple] { - height: auto; + height: auto; } .pure-form label { - margin: 0.5em 0 0.2em; + margin: 0.5em 0 0.2em; } .pure-form fieldset { - margin: 0; - padding: 0.35em 0 0.75em; - border: 0; + margin: 0; + padding: 0.35em 0 0.75em; + border: 0; } .pure-form legend { - display: block; - width: 100%; - padding: 0.3em 0; - margin-bottom: 0.3em; - color: #333; - border-bottom: 1px solid #e5e5e5; + display: block; + width: 100%; + padding: 0.3em 0; + margin-bottom: 0.3em; + color: #333; + border-bottom: 1px solid #e5e5e5; } .pure-form-stacked input[type="text"], @@ -1059,8 +1065,8 @@ since IE8 won't execute CSS that contains a CSS3 selector. .pure-form-stacked select, .pure-form-stacked label, .pure-form-stacked textarea { - display: block; - margin: 0.25em 0; + display: block; + margin: 0.25em 0; } /* @@ -1068,8 +1074,8 @@ Need to separate out the :not() selector from the rest of the CSS 2.1 selectors since IE8 won't execute CSS that contains a CSS3 selector. */ .pure-form-stacked input:not([type]) { - display: block; - margin: 0.25em 0; + display: block; + margin: 0.25em 0; } .pure-form-aligned input, .pure-form-aligned textarea, @@ -1077,397 +1083,397 @@ since IE8 won't execute CSS that contains a CSS3 selector. /* NOTE: pure-help-inline is deprecated. Use .pure-form-message-inline instead. */ .pure-form-aligned .pure-help-inline, .pure-form-message-inline { - display: inline-block; - *display: inline; - *zoom: 1; - vertical-align: middle; + display: inline-block; + *display: inline; + *zoom: 1; + vertical-align: middle; } .pure-form-aligned textarea { - vertical-align: top; + vertical-align: top; } /* Aligned Forms */ .pure-form-aligned .pure-control-group { - margin-bottom: 0.5em; + margin-bottom: 0.5em; } .pure-form-aligned .pure-control-group label { - text-align: right; - display: inline-block; - vertical-align: middle; - width: 10em; - margin: 0 1em 0 0; + text-align: right; + display: inline-block; + vertical-align: middle; + width: 10em; + margin: 0 1em 0 0; } .pure-form-aligned .pure-controls { - margin: 1.5em 0 0 11em; + margin: 1.5em 0 0 11em; } /* Rounded Inputs */ .pure-form input.pure-input-rounded, .pure-form .pure-input-rounded { - border-radius: 2em; - padding: 0.5em 1em; + border-radius: 2em; + padding: 0.5em 1em; } /* Grouped Inputs */ .pure-form .pure-group fieldset { - margin-bottom: 10px; + margin-bottom: 10px; } .pure-form .pure-group input, .pure-form .pure-group textarea { - display: block; - padding: 10px; - margin: 0 0 -1px; - border-radius: 0; - position: relative; - top: -1px; + display: block; + padding: 10px; + margin: 0 0 -1px; + border-radius: 0; + position: relative; + top: -1px; } .pure-form .pure-group input:focus, .pure-form .pure-group textarea:focus { - z-index: 3; + z-index: 3; } .pure-form .pure-group input:first-child, .pure-form .pure-group textarea:first-child { - top: 1px; - border-radius: 4px 4px 0 0; - margin: 0; + top: 1px; + border-radius: 4px 4px 0 0; + margin: 0; } .pure-form .pure-group input:first-child:last-child, .pure-form .pure-group textarea:first-child:last-child { - top: 1px; - border-radius: 4px; - margin: 0; + top: 1px; + border-radius: 4px; + margin: 0; } .pure-form .pure-group input:last-child, .pure-form .pure-group textarea:last-child { - top: -2px; - border-radius: 0 0 4px 4px; - margin: 0; + top: -2px; + border-radius: 0 0 4px 4px; + margin: 0; } .pure-form .pure-group button { - margin: 0.35em 0; + margin: 0.35em 0; } .pure-form .pure-input-1 { - width: 100%; + width: 100%; } .pure-form .pure-input-3-4 { - width: 75%; + width: 75%; } .pure-form .pure-input-2-3 { - width: 66%; + width: 66%; } .pure-form .pure-input-1-2 { - width: 50%; + width: 50%; } .pure-form .pure-input-1-3 { - width: 33%; + width: 33%; } .pure-form .pure-input-1-4 { - width: 25%; + width: 25%; } /* Inline help for forms */ /* NOTE: pure-help-inline is deprecated. Use .pure-form-message-inline instead. */ .pure-form .pure-help-inline, .pure-form-message-inline { - display: inline-block; - padding-left: 0.3em; - color: #666; - vertical-align: middle; - font-size: 0.875em; + display: inline-block; + padding-left: 0.3em; + color: #666; + vertical-align: middle; + font-size: 0.875em; } /* Block help for forms */ .pure-form-message { + display: block; + color: #666; + font-size: 0.875em; +} + +@media only screen and (max-width: 480px) { + .pure-form button[type="submit"] { + margin: 0.7em 0 0; + } + + .pure-form input:not([type]), + .pure-form input[type="text"], + .pure-form input[type="password"], + .pure-form input[type="email"], + .pure-form input[type="url"], + .pure-form input[type="date"], + .pure-form input[type="month"], + .pure-form input[type="time"], + .pure-form input[type="datetime"], + .pure-form input[type="datetime-local"], + .pure-form input[type="week"], + .pure-form input[type="number"], + .pure-form input[type="search"], + .pure-form input[type="tel"], + .pure-form input[type="color"], + .pure-form label { + margin-bottom: 0.3em; display: block; - color: #666; - font-size: 0.875em; -} - -@media only screen and (max-width : 480px) { - .pure-form button[type="submit"] { - margin: 0.7em 0 0; - } - - .pure-form input:not([type]), - .pure-form input[type="text"], - .pure-form input[type="password"], - .pure-form input[type="email"], - .pure-form input[type="url"], - .pure-form input[type="date"], - .pure-form input[type="month"], - .pure-form input[type="time"], - .pure-form input[type="datetime"], - .pure-form input[type="datetime-local"], - .pure-form input[type="week"], - .pure-form input[type="number"], - .pure-form input[type="search"], - .pure-form input[type="tel"], - .pure-form input[type="color"], - .pure-form label { - margin-bottom: 0.3em; - display: block; - } - - .pure-group input:not([type]), - .pure-group input[type="text"], - .pure-group input[type="password"], - .pure-group input[type="email"], - .pure-group input[type="url"], - .pure-group input[type="date"], - .pure-group input[type="month"], - .pure-group input[type="time"], - .pure-group input[type="datetime"], - .pure-group input[type="datetime-local"], - .pure-group input[type="week"], - .pure-group input[type="number"], - .pure-group input[type="search"], - .pure-group input[type="tel"], - .pure-group input[type="color"] { - margin-bottom: 0; - } - - .pure-form-aligned .pure-control-group label { - margin-bottom: 0.3em; - text-align: left; - display: block; - width: 100%; - } - - .pure-form-aligned .pure-controls { - margin: 1.5em 0 0 0; - } - - /* NOTE: pure-help-inline is deprecated. Use .pure-form-message-inline instead. */ - .pure-form .pure-help-inline, - .pure-form-message-inline, - .pure-form-message { - display: block; - font-size: 0.75em; - /* Increased bottom padding to make it group with its related input element. */ - padding: 0.2em 0 0.8em; - } + } + + .pure-group input:not([type]), + .pure-group input[type="text"], + .pure-group input[type="password"], + .pure-group input[type="email"], + .pure-group input[type="url"], + .pure-group input[type="date"], + .pure-group input[type="month"], + .pure-group input[type="time"], + .pure-group input[type="datetime"], + .pure-group input[type="datetime-local"], + .pure-group input[type="week"], + .pure-group input[type="number"], + .pure-group input[type="search"], + .pure-group input[type="tel"], + .pure-group input[type="color"] { + margin-bottom: 0; + } + + .pure-form-aligned .pure-control-group label { + margin-bottom: 0.3em; + text-align: left; + display: block; + width: 100%; + } + + .pure-form-aligned .pure-controls { + margin: 1.5em 0 0 0; + } + + /* NOTE: pure-help-inline is deprecated. Use .pure-form-message-inline instead. */ + .pure-form .pure-help-inline, + .pure-form-message-inline, + .pure-form-message { + display: block; + font-size: 0.75em; + /* Increased bottom padding to make it group with its related input element. */ + padding: 0.2em 0 0.8em; + } } /*csslint adjoining-classes: false, box-model:false*/ .pure-menu { - box-sizing: border-box; + box-sizing: border-box; } .pure-menu-fixed { - position: fixed; - left: 0; - top: 0; - z-index: 3; + position: fixed; + left: 0; + top: 0; + z-index: 3; } .pure-menu-list, .pure-menu-item { - position: relative; + position: relative; } .pure-menu-list { - list-style: none; - margin: 0; - padding: 0; + list-style: none; + margin: 0; + padding: 0; } .pure-menu-item { - padding: 0; - margin: 0; - height: 100%; + padding: 0; + margin: 0; + height: 100%; } .pure-menu-link, .pure-menu-heading { - display: block; - text-decoration: none; - white-space: nowrap; + display: block; + text-decoration: none; + white-space: nowrap; } /* HORIZONTAL MENU */ .pure-menu-horizontal { - width: 100%; - white-space: nowrap; + width: 100%; + white-space: nowrap; } .pure-menu-horizontal .pure-menu-list { - display: inline-block; + display: inline-block; } /* Initial menus should be inline-block so that they are horizontal */ .pure-menu-horizontal .pure-menu-item, .pure-menu-horizontal .pure-menu-heading, .pure-menu-horizontal .pure-menu-separator { - display: inline-block; - *display: inline; - zoom: 1; - vertical-align: middle; + display: inline-block; + *display: inline; + zoom: 1; + vertical-align: middle; } /* Submenus should still be display: block; */ .pure-menu-item .pure-menu-item { - display: block; + display: block; } .pure-menu-children { - display: none; - position: absolute; - left: 100%; - top: 0; - margin: 0; - padding: 0; - z-index: 3; + display: none; + position: absolute; + left: 100%; + top: 0; + margin: 0; + padding: 0; + z-index: 3; } .pure-menu-horizontal .pure-menu-children { - left: 0; - top: auto; - width: inherit; + left: 0; + top: auto; + width: inherit; } .pure-menu-allow-hover:hover > .pure-menu-children, .pure-menu-active > .pure-menu-children { - display: block; - position: absolute; + display: block; + position: absolute; } /* Vertical Menus - show the dropdown arrow */ .pure-menu-has-children > .pure-menu-link:after { - padding-left: 0.5em; - content: "\25B8"; - font-size: small; + padding-left: 0.5em; + content: "\25B8"; + font-size: small; } /* Horizontal Menus - show the dropdown arrow */ .pure-menu-horizontal .pure-menu-has-children > .pure-menu-link:after { - content: "\25BE"; + content: "\25BE"; } /* scrollable menus */ .pure-menu-scrollable { - overflow-y: scroll; - overflow-x: hidden; + overflow-y: scroll; + overflow-x: hidden; } .pure-menu-scrollable .pure-menu-list { - display: block; + display: block; } .pure-menu-horizontal.pure-menu-scrollable .pure-menu-list { - display: inline-block; + display: inline-block; } .pure-menu-horizontal.pure-menu-scrollable { - white-space: nowrap; - overflow-y: hidden; - overflow-x: auto; - -ms-overflow-style: none; - -webkit-overflow-scrolling: touch; - /* a little extra padding for this style to allow for scrollbars */ - padding: .5em 0; + white-space: nowrap; + overflow-y: hidden; + overflow-x: auto; + -ms-overflow-style: none; + -webkit-overflow-scrolling: touch; + /* a little extra padding for this style to allow for scrollbars */ + padding: 0.5em 0; } .pure-menu-horizontal.pure-menu-scrollable::-webkit-scrollbar { - display: none; + display: none; } /* misc default styling */ .pure-menu-separator, .pure-menu-horizontal .pure-menu-children .pure-menu-separator { - background-color: #ccc; - height: 1px; - margin: .3em 0; + background-color: #ccc; + height: 1px; + margin: 0.3em 0; } .pure-menu-horizontal .pure-menu-separator { - width: 1px; - height: 1.3em; - margin: 0 .3em ; + width: 1px; + height: 1.3em; + margin: 0 0.3em; } /* Need to reset the separator since submenu is vertical */ .pure-menu-horizontal .pure-menu-children .pure-menu-separator { - display: block; - width: auto; + display: block; + width: auto; } .pure-menu-heading { - text-transform: uppercase; - color: #565d64; + text-transform: uppercase; + color: #565d64; } .pure-menu-link { - color: #777; + color: #777; } .pure-menu-children { - background-color: #fff; + background-color: #fff; } .pure-menu-link, .pure-menu-disabled, .pure-menu-heading { - padding: .5em 1em; + padding: 0.5em 1em; } .pure-menu-disabled { - opacity: .5; + opacity: 0.5; } .pure-menu-disabled .pure-menu-link:hover { - background-color: transparent; + background-color: transparent; } .pure-menu-active > .pure-menu-link, .pure-menu-link:hover, .pure-menu-link:focus { - background-color: #eee; + background-color: #eee; } .pure-menu-selected .pure-menu-link, .pure-menu-selected .pure-menu-link:visited { - color: #000; + color: #000; } .pure-table { - /* Remove spacing between table cells (from Normalize.css) */ - border-collapse: collapse; - border-spacing: 0; - empty-cells: show; - border: 1px solid #cbcbcb; + /* Remove spacing between table cells (from Normalize.css) */ + border-collapse: collapse; + border-spacing: 0; + empty-cells: show; + border: 1px solid #cbcbcb; } .pure-table caption { - color: #000; - font: italic 85%/1 arial, sans-serif; - padding: 1em 0; - text-align: center; + color: #000; + font: italic 85%/1 arial, sans-serif; + padding: 1em 0; + text-align: center; } .pure-table td, .pure-table th { - border-left: 1px solid #cbcbcb;/* inner column border */ - border-width: 0 0 0 1px; - font-size: inherit; - margin: 0; - overflow: visible; /*to make ths where the title is really long work*/ - padding: 0.5em 1em; /* cell padding */ + border-left: 1px solid #cbcbcb; /* inner column border */ + border-width: 0 0 0 1px; + font-size: inherit; + margin: 0; + overflow: visible; /*to make ths where the title is really long work*/ + padding: 0.5em 1em; /* cell padding */ } /* Consider removing this next declaration block, as it causes problems when there's a rowspan on the first cell. Case added to the tests. issue#432 */ .pure-table td:first-child, .pure-table th:first-child { - border-left-width: 0; + border-left-width: 0; } .pure-table thead { - background-color: #e0e0e0; - color: #000; - text-align: left; - vertical-align: bottom; + background-color: #e0e0e0; + color: #000; + text-align: left; + vertical-align: bottom; } /* @@ -1476,33 +1482,32 @@ striping: odd - #f2f2f2 (light gray) */ .pure-table td { - background-color: transparent; + background-color: transparent; } .pure-table-odd td { - background-color: #f2f2f2; + background-color: #f2f2f2; } /* nth-child selector for modern browsers */ .pure-table-striped tr:nth-child(2n-1) td { - background-color: #f2f2f2; + background-color: #f2f2f2; } /* BORDERED TABLES */ .pure-table-bordered td { - border-bottom: 1px solid #cbcbcb; + border-bottom: 1px solid #cbcbcb; } .pure-table-bordered tbody > tr:last-child > td { - border-bottom-width: 0; + border-bottom-width: 0; } - /* HORIZONTAL BORDERED TABLES */ .pure-table-horizontal td, .pure-table-horizontal th { - border-width: 0 0 1px 0; - border-bottom: 1px solid #cbcbcb; + border-width: 0 0 1px 0; + border-bottom: 1px solid #cbcbcb; } .pure-table-horizontal tbody > tr:last-child > td { - border-bottom-width: 0; + border-bottom-width: 0; } diff --git a/src/webex/style/wallet.css b/src/webex/style/wallet.css index b4bfd6f6d..16a414b3d 100644 --- a/src/webex/style/wallet.css +++ b/src/webex/style/wallet.css @@ -4,75 +4,77 @@ body { } #main { - border: solid 1px black; - border-radius: 10px; - margin-left: auto; - margin-right: auto; - margin-top: 2em; - max-width: 50%; - padding: 2em; + border: solid 1px black; + border-radius: 10px; + margin-left: auto; + margin-right: auto; + margin-top: 2em; + max-width: 50%; + padding: 2em; } header { - width: 100%; - height: 100px; - margin: 0; - padding: 0; - border-bottom: 1px solid black; + width: 100%; + height: 100px; + margin: 0; + padding: 0; + border-bottom: 1px solid black; } header h1 { - font-size: 200%; - margin: 0; - padding: 0 0 0 120px; - position: relative; - top: 50%; - transform: translateY(-50%); + font-size: 200%; + margin: 0; + padding: 0 0 0 120px; + position: relative; + top: 50%; + transform: translateY(-50%); } header #logo { - float: left; - width: 100px; - height: 100px; - padding: 0; - margin: 0; - text-align: center; - border-right: 1px solid black; - background-image: url(/img/logo.png); - background-size: 100px; + float: left; + width: 100px; + height: 100px; + padding: 0; + margin: 0; + text-align: center; + border-right: 1px solid black; + background-image: url(/img/logo.png); + background-size: 100px; } aside { - width: 100px; - float: left; + width: 100px; + float: left; } section#main { - margin: auto; - padding: 20px; - border-left: 1px solid black; - height: 100%; - max-width: 50%; + margin: auto; + padding: 20px; + border-left: 1px solid black; + height: 100%; + max-width: 50%; } section#main h1:first-child { - margin-top: 0; + margin-top: 0; } h1 { - font-size: 160%; + font-size: 160%; } h2 { - font-size: 140%; + font-size: 140%; } h3 { - font-size: 120%; + font-size: 120%; } -h4, h5, h6 { - font-size: 100%; +h4, +h5, +h6 { + font-size: 100%; } .form-row { @@ -92,63 +94,74 @@ input.url { } .json-key { - color: brown; + color: brown; } .json-value { - color: navy; - } + color: navy; +} .json-string { - color: olive; + color: olive; } button { - font-size: 120%; - padding: 0.5em; + font-size: 120%; + padding: 0.5em; } button.confirm-pay { - float: right; + float: right; } /* We use fading to hide slower DOM updates */ .fade { - -webkit-animation: fade 0.7s; - animation: fade 0.7s; - opacity: 1; + -webkit-animation: fade 0.7s; + animation: fade 0.7s; + opacity: 1; } @-webkit-keyframes fade { - from {opacity: 0} - to {opacity: 1} + from { + opacity: 0; + } + to { + opacity: 1; + } } @keyframes fade { - from {opacity: 0} - to {opacity: 1} - } + from { + opacity: 0; + } + to { + opacity: 1; + } +} button.linky { - background:none!important; - border:none; - padding:0!important; + background: none !important; + border: none; + padding: 0 !important; - font-family:arial,sans-serif; - color:#069; - text-decoration:underline; - cursor:pointer; + font-family: arial, sans-serif; + color: #069; + text-decoration: underline; + cursor: pointer; } -.blacklink a:link, .blacklink a:visited, .blacklink a:hover, .blacklink a:active { +.blacklink a:link, +.blacklink a:visited, +.blacklink a:hover, +.blacklink a:active { color: #000; } - -table, th, td { - border: 1px solid black; +table, +th, +td { + border: 1px solid black; } - button.accept { - background-color: #5757D2; + background-color: #5757d2; border: 1px solid black; border-radius: 5px; margin: 1em 0; @@ -157,17 +170,16 @@ button.accept { color: white; } button.linky { - background:none!important; - border:none; - padding:0!important; + background: none !important; + border: none; + padding: 0 !important; - font-family:arial,sans-serif; - color:#069; - text-decoration:underline; - cursor:pointer; + font-family: arial, sans-serif; + color: #069; + text-decoration: underline; + cursor: pointer; } - button.accept:disabled { background-color: #dedbe8; border: 1px solid white; @@ -175,7 +187,7 @@ button.accept:disabled { margin: 1em 0; padding: 0.5em; font-weight: bold; - color: #2C2C2C; + color: #2c2c2c; } input.url { @@ -202,39 +214,38 @@ span.spacer { .button-destructive, .button-warning, .button-secondary { - color: white; - border-radius: 4px; - text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); + color: white; + border-radius: 4px; + text-shadow: 0 1px 1px rgba(0, 0, 0, 0.2); } .button-success { - background: rgb(28, 184, 65); + background: rgb(28, 184, 65); } .button-destructive { - background: rgb(202, 60, 60); + background: rgb(202, 60, 60); } .button-warning { - background: rgb(223, 117, 20); + background: rgb(223, 117, 20); } .button-secondary { - background: rgb(66, 184, 221); + background: rgb(66, 184, 221); } a.actionLink { color: black; } - .errorbox { border: 1px solid; display: inline-block; margin: 1em; padding: 1em; font-weight: bold; - background: #FF8A8A; + background: #ff8a8a; } .okaybox { @@ -243,18 +254,17 @@ a.actionLink { margin: 1em; padding: 1em; font-weight: bold; - background: #00FA9A; + background: #00fa9a; } - -a.opener { +a.opener { color: black; } .opener-open::before { - content: "\25bc" + content: "\25bc"; } .opener-collapsed::before { - content: "\25b6 " + content: "\25b6 "; } .svg-icon { @@ -265,8 +275,8 @@ a.opener { width: 1em; } .svg-icon svg { - height:1em; - width:1em; + height: 1em; + width: 1em; } object.svg-icon.svg-baseline { transform: translate(0, 0.125em); diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts index 5edd1907b..a530b7506 100644 --- a/src/webex/wxApi.ts +++ b/src/webex/wxApi.ts @@ -79,7 +79,7 @@ async function callBackend( detail: MessageMap[T]["request"], ): Promise { return new Promise((resolve, reject) => { - chrome.runtime.sendMessage({ type, detail }, resp => { + chrome.runtime.sendMessage({ type, detail }, (resp) => { if (chrome.runtime.lastError) { console.log("Error calling backend"); reject( diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts index 248e6dfba..dd0b91683 100644 --- a/src/webex/wxBackend.ts +++ b/src/webex/wxBackend.ts @@ -406,7 +406,7 @@ async function reinitWallet() { http, new BrowserCryptoWorkerFactory(), ); - wallet.runRetryLoop().catch(e => { + wallet.runRetryLoop().catch((e) => { console.log("error during wallet retry loop", e); }); // Useful for debugging in the background page. @@ -443,7 +443,7 @@ function injectScript( try { // This needs to be outside of main, as Firefox won't fire the event if // the listener isn't created synchronously on loading the backend. - chrome.runtime.onInstalled.addListener(details => { + chrome.runtime.onInstalled.addListener((details) => { console.log("onInstalled with reason", details.reason); if (details.reason === "install") { const url = chrome.extension.getURL("/src/webex/pages/welcome.html"); @@ -462,12 +462,12 @@ try { export async function wxMain() { // Explicitly unload the extension page as soon as an update is available, // so the update gets installed as soon as possible. - chrome.runtime.onUpdateAvailable.addListener(details => { + chrome.runtime.onUpdateAvailable.addListener((details) => { console.log("update available:", details); chrome.runtime.reload(); }); - chrome.tabs.query({}, tabs => { + chrome.tabs.query({}, (tabs) => { console.log("got tabs", tabs); for (const tab of tabs) { if (!tab.url || !tab.id) { @@ -520,7 +520,7 @@ export async function wxMain() { const run = () => { timers.shift(); - chrome.tabs.get(tabId, tab => { + chrome.tabs.get(tabId, (tab) => { if (chrome.runtime.lastError) { return; } @@ -562,7 +562,7 @@ export async function wxMain() { // Handlers for catching HTTP requests chrome.webRequest.onHeadersReceived.addListener( - details => { + (details) => { const wallet = currentWallet; if (!wallet) { console.warn("wallet not available while handling header"); -- cgit v1.2.3