diff options
author | Florian Dold <florian.dold@gmail.com> | 2020-03-30 16:09:32 +0530 |
---|---|---|
committer | Florian Dold <florian.dold@gmail.com> | 2020-03-30 16:09:32 +0530 |
commit | aaf950e2ad5c07d4423f9822e3a0ae9f7b8d2bdf (patch) | |
tree | 9274139660f30c4857d80044eb4ac283aac1775a /src/webex | |
parent | 15e18440dbad55df19977a2eb7053681259afc18 (diff) |
re-format with prettier v2, fix HTML
Diffstat (limited to 'src/webex')
39 files changed, 1352 insertions, 1239 deletions
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 @@ <!DOCTYPE html> <html lang="en"> -<head> - <meta charset="UTF-8"> - <script src="../../dist/background-bundle.js"></script> - <title>(wallet bg page)</title> -</head> -<body> - <img id="taler-logo" src="/img/icon.png"> -</body> + <head> + <meta charset="UTF-8" /> + <script src="../../dist/background-bundle.js"></script> + <title>(wallet bg page)</title> + </head> + <body> + <img id="taler-logo" src="/img/icon.png" /> + </body> </html> 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 <http://www.gnu.org/licenses/> */ - 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<string>) { 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<TranslateProps, {}> { 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<TranslateProps, {}> { } } - /** * 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<TranslateProps, {}> { * </TranslateSwitch> * ``` */ -export class TranslateSwitch extends React.Component<TranslateSwitchProps, void> { +export class TranslateSwitch extends React.Component< + TranslateSwitchProps, + void +> { render(): JSX.Element { let singular: React.ReactElement<TranslationPluralProps> | undefined; let plural: React.ReactElement<TranslationPluralProps> | undefined; @@ -186,7 +191,7 @@ export class TranslateSwitch extends React.Component<TranslateSwitchProps, void> } }); } - 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<TranslateSwitchProps, void> } } - interface TranslationPluralProps { target: number; } @@ -206,14 +210,24 @@ interface TranslationPluralProps { /** * See [[TranslateSwitch]]. */ -export class TranslatePlural extends React.Component<TranslationPluralProps, void> { +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<TranslationPluralProps, voi } } - /** * See [[TranslateSwitch]]. */ -export class TranslateSingular extends React.Component<TranslationPluralProps, void> { +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<void>; + listener: (e: Event) => void | Promise<void>; } 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 (<link> or <style>)"); + throw Error( + "taler-presence-stylesheet should be a style sheet (<link> or <style>)", + ); } sheet = style.sheet as CSSStyleSheet; while (sheet.cssRules.length > 0) { @@ -77,7 +78,6 @@ function initStyle() { } } - function setStyles(installed: boolean) { if (!sheet || !sheet.cssRules) { return; @@ -93,7 +93,6 @@ function setStyles(installed: boolean) { } } - function onceOnComplete(cb: () => void) { if (document.readyState === "complete") { cb(); @@ -106,7 +105,6 @@ function onceOnComplete(cb: () => void) { } } - function init() { onceOnComplete(() => { if (document.documentElement.getAttribute("data-taler-nojs")) { @@ -131,7 +129,6 @@ function init() { type HandlerFn = (detail: any, sendResponse: (msg: any) => void) => void; - function registerHandlers() { /** * Add a handler for a DOM event, which automatically @@ -149,12 +146,16 @@ function registerHandlers() { } let callId: number | undefined; let detail; - if ((e instanceof CustomEvent) && e.detail && e.detail.callId !== undefined) { + if ( + e instanceof CustomEvent && + e.detail && + e.detail.callId !== undefined + ) { callId = e.detail.callId; detail = e.detail; } const responder = (msg?: any) => { - const fullMsg = Object.assign({}, msg, {callId}); + const fullMsg = Object.assign({}, msg, { callId }); let opts = { detail: fullMsg }; if ("function" === typeof cloneInto) { opts = cloneInto(opts, document.defaultView); @@ -165,7 +166,7 @@ function registerHandlers() { handler(detail, responder); }; document.addEventListener(type, handlerWrap); - handlers.push({type, listener: handlerWrap}); + handlers.push({ type, listener: handlerWrap }); } addHandler("taler-query-id", (msg: any, sendResponse: any) => { @@ -178,25 +179,34 @@ function registerHandlers() { }); addHandler("taler-create-reserve", (msg: any) => { - const uri = new URL(chrome.extension.getURL("/src/webex/pages/confirm-create-reserve.html")); + const uri = new URL( + chrome.extension.getURL("/src/webex/pages/confirm-create-reserve.html"), + ); uri.searchParams.set("amount", JSON.stringify(msg.amount)); uri.searchParams.set("bank_url", document.location.href); - uri.searchParams.set("callback_url", new URL(msg.callback_url, document.location.href).href); + uri.searchParams.set( + "callback_url", + new URL(msg.callback_url, document.location.href).href, + ); uri.searchParams.set("suggested_exchange_url", msg.suggested_exchange_url); uri.searchParams.set("wt_types", JSON.stringify(msg.wt_types)); window.location.href = uri.href; }); addHandler("taler-add-auditor", (msg: any) => { - const uri = new URL(chrome.extension.getURL("/src/webex/pages/add-auditor.html")); - uri.searchParams.set("req", JSON.stringify(msg)) + const uri = new URL( + chrome.extension.getURL("/src/webex/pages/add-auditor.html"), + ); + uri.searchParams.set("req", JSON.stringify(msg)); window.location.href = uri.href; }); addHandler("taler-confirm-reserve", async (msg: any, sendResponse: any) => { const reservePub = msg.reserve_pub; if (typeof reservePub !== "string") { - console.error("taler-confirm-reserve expects parameter reserve_pub of type 'string'"); + console.error( + "taler-confirm-reserve expects parameter reserve_pub of type 'string'", + ); return; } await wxApi.confirmReserve(msg.reserve_pub); diff --git a/src/webex/pages/add-auditor.html b/src/webex/pages/add-auditor.html index b7a9d041d..7f30b5fb6 100644 --- a/src/webex/pages/add-auditor.html +++ b/src/webex/pages/add-auditor.html @@ -1,32 +1,32 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> -<head> - <meta charset="UTF-8"> + <title>Taler Wallet: Add Auditor</title> - <title>Taler Wallet: Add Auditor</title> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> + <link rel="icon" href="/img/icon.png" /> - <link rel="icon" href="/img/icon.png"> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/add-auditor-bundle.js"></script> - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/add-auditor-bundle.js"></script> - - <style> - .tree-item { - margin: 2em; - border-radius: 5px; - border: 1px solid gray; - padding: 1em; - } - .button-linky { - background: none; - color: black; - text-decoration: underline; - border: none; - } - </style> + <style> + .tree-item { + margin: 2em; + border-radius: 5px; + border: 1px solid gray; + padding: 1em; + } + .button-linky { + background: none; + color: black; + text-decoration: underline; + border: none; + } + </style> + </head> <body> <div id="container"></div> 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 <ConfirmAuditor {...args}/>; + return <ConfirmAuditor {...args} />; }); 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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> + <title>Taler Wallet: Auditors</title> -<head> - <meta charset="UTF-8"> - <title>Taler Wallet: Auditors</title> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> + <link rel="icon" href="/img/icon.png" /> - <link rel="icon" href="/img/icon.png"> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/auditors-bundle.js"></script> - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/auditors-bundle.js"></script> - - <style> - body { - font-size: 100%; - } - .tree-item { - margin: 2em; - border-radius: 5px; - border: 1px solid gray; - padding: 1em; - } - .button-linky { - background: none; - color: black; - text-decoration: underline; - border: none; - } - </style> + <style> + body { + font-size: 100%; + } + .tree-item { + margin: 2em; + border-radius: 5px; + border: 1px solid gray; + padding: 1em; + } + .button-linky { + background: none; + color: black; + text-decoration: underline; + border: none; + } + </style> + </head> <body> <div id="container"></div> 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> { <div> <p>Trusted Auditors:</p> <ul> - {c.auditors.map((a) => ( - <li> - {a.baseUrl}{" "} - <button className="pure-button button-destructive" onClick={() => this.confirmRemoveAuditor(c, a)}> - Remove - </button> - <ul> - <li>valid until {new Date(a.expirationStamp).toString()}</li> - <li>public key {a.auditorPub}</li> - </ul> - </li> - ))} + {c.auditors.map((a) => ( + <li> + {a.baseUrl}{" "} + <button + className="pure-button button-destructive" + onClick={() => this.confirmRemoveAuditor(c, a)} + > + Remove + </button> + <ul> + <li>valid until {new Date(a.expirationStamp).toString()}</li> + <li>public key {a.auditorPub}</li> + </ul> + </li> + ))} </ul> </div> ); @@ -106,14 +113,17 @@ class CurrencyList extends React.Component<{}, CurrencyListState> { <div> <p>Trusted Exchanges:</p> <ul> - {c.exchanges.map((e) => ( - <li> - {e.baseUrl}{" "} - <button className="pure-button button-destructive" onClick={() => this.confirmRemoveExchange(c, e)}> - Remove - </button> - </li> - ))} + {c.exchanges.map((e) => ( + <li> + {e.baseUrl}{" "} + <button + className="pure-button button-destructive" + onClick={() => this.confirmRemoveExchange(c, e)} + > + Remove + </button> + </li> + ))} </ul> </div> ); @@ -126,16 +136,16 @@ class CurrencyList extends React.Component<{}, CurrencyListState> { } return ( <div id="main"> - {currencies.map((c) => ( - <div> - <h1>Currency {c.name}</h1> - <p>Displayed with {c.fractionalDigits} fractional digits.</p> - <h2>Auditors</h2> - <div>{this.renderAuditors(c)}</div> - <h2>Exchanges</h2> - <div>{this.renderExchanges(c)}</div> - </div> - ))} + {currencies.map((c) => ( + <div> + <h1>Currency {c.name}</h1> + <p>Displayed with {c.fractionalDigits} fractional digits.</p> + <h2>Auditors</h2> + <div>{this.renderAuditors(c)}</div> + <h2>Exchanges</h2> + <div>{this.renderExchanges(c)}</div> + </div> + ))} </div> ); } 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 @@ -<!doctype html> +<!DOCTYPE html> <html> <head> - <meta charset="UTF-8"> + <meta charset="UTF-8" /> <title>Taler Wallet: Benchmarks</title> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> - <link rel="icon" href="/img/icon.png"> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> + <link rel="icon" href="/img/icon.png" /> <script src="/dist/page-common-bundle.js"></script> <script src="/dist/benchmark-bundle.js"></script> </head> <body> - <section id="main"> - <h1>Benchmarks</h1> - <div id="container"></div> - </section> + <section id="main"> + <h1>Benchmarks</h1> + <div id="container"></div> + </section> </body> </html> 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 <http://www.gnu.org/licenses/> */ - /** * 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 ( <> - <h2>Results for {result.repetitions} repetitions</h2> - <table className="pure-table"> - <thead> - <tr> - <th>{i18n.str`Operation`}</th> - <th>{i18n.str`time (ms/op)`}</th> - </tr> - { - Object.keys(result.time).sort().map( - k => - <tr> - <td>{k}</td> - <td>{result.time[k] / result.repetitions}</td> - </tr> - ) - } - </thead> - </table> + <h2>Results for {result.repetitions} repetitions</h2> + <table className="pure-table"> + <thead> + <tr> + <th>{i18n.str`Operation`}</th> + <th>{i18n.str`time (ms/op)`}</th> + </tr> + {Object.keys(result.time) + .sort() + .map((k) => ( + <tr> + <td>{k}</td> + <td>{result.time[k] / result.repetitions}</td> + </tr> + ))} + </thead> + </table> </> ); } @@ -91,10 +87,13 @@ class BenchmarkRunner extends React.Component<any, BenchmarkRunnerState> { return ( <div> <label>Repetitions:</label> - <input type="number" - value={this.state.repetitions} - onChange={(evt) => this.setState({ repetitions: Number.parseInt(evt.target.value) })} /> - {" "} + <input + type="number" + value={this.state.repetitions} + onChange={(evt) => + this.setState({ repetitions: Number.parseInt(evt.target.value) }) + } + />{" "} <button onClick={() => this.run()}>Run</button> <BenchmarkDisplay {...this.state} /> </div> 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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> + <title>Taler Wallet: Confirm Contract</title> -<head> - <meta charset="UTF-8"> - <title>Taler Wallet: Confirm Contract</title> + <link rel="stylesheet" type="text/css" href="../style/pure.css" /> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> - <link rel="stylesheet" type="text/css" href="../style/pure.css"> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> + <link rel="icon" href="/img/icon.png" /> - <link rel="icon" href="/img/icon.png"> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/pay-bundle.js"></script> - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/pay-bundle.js"></script> + <style> + button.accept { + background-color: #5757d2; + border: 1px solid black; + border-radius: 5px; + margin: 1em 0; + padding: 0.5em; + font-weight: bold; + color: white; + } + button.linky { + background: none !important; + border: none; + padding: 0 !important; - <style> - button.accept { - background-color: #5757D2; - border: 1px solid black; - border-radius: 5px; - margin: 1em 0; - padding: 0.5em; - font-weight: bold; - color: white; - } - button.linky { - 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; - } + input.url { + width: 25em; + } - input.url { - width: 25em; - } + button.accept:disabled { + background-color: #dedbe8; + border: 1px solid white; + border-radius: 5px; + margin: 1em 0; + padding: 0.5em; + font-weight: bold; + color: #2c2c2c; + } + .errorbox { + border: 1px solid; + display: inline-block; + margin: 1em; + padding: 1em; + font-weight: bold; + background: #ff8a8a; + } - button.accept:disabled { - background-color: #dedbe8; - border: 1px solid white; - border-radius: 5px; - margin: 1em 0; - padding: 0.5em; - font-weight: bold; - color: #2C2C2C; - } - - .errorbox { - border: 1px solid; - display: inline-block; - margin: 1em; - padding: 1em; - font-weight: bold; - background: #FF8A8A; - } - - .okaybox { - border: 1px solid; - display: inline-block; - margin: 1em; - padding: 1em; - font-weight: bold; - background: #00FA9A; - } - </style> -</head> - -<body> - <section id="main"> - <h1>GNU Taler Wallet</h1> - <article id="container" class="fade"></article> - </section> -</body> + .okaybox { + border: 1px solid; + display: inline-block; + margin: 1em; + padding: 1em; + font-weight: bold; + background: #00fa9a; + } + </style> + </head> + <body> + <section id="main"> + <h1>GNU Taler Wallet</h1> + <article id="container" class="fade"></article> + </section> + </body> </html> 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 ( - <span> - Invalid contract terms. - </span> - ); + return <span>Invalid contract terms.</span>; } if (!contractTerms) { @@ -149,7 +147,9 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) { {insufficientBalance ? ( <div> - <p style={{color: "red", fontWeight: "bold"}}>Unable to pay: Your balance is insufficient.</p> + <p style={{ color: "red", fontWeight: "bold" }}> + Unable to pay: Your balance is insufficient. + </p> </div> ) : null} @@ -168,7 +168,8 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) { <ProgressButton loading={loading} disabled={insufficientBalance} - onClick={() => doPayment()}> + onClick={() => doPayment()} + > {i18n.str`Confirm payment`} </ProgressButton> </div> 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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> + <title>Taler Wallet: Payback</title> -<head> - <meta charset="UTF-8"> - <title>Taler Wallet: Payback</title> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> + <link rel="icon" href="/img/icon.png" /> - <link rel="icon" href="/img/icon.png"> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/payback-bundle.js"></script> - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/payback-bundle.js"></script> - - <style> - body { - font-size: 100%; - } - .tree-item { - margin: 2em; - border-radius: 5px; - border: 1px solid gray; - padding: 1em; - } - .button-linky { - background: none; - color: black; - text-decoration: underline; - border: none; - } - </style> + <style> + body { + font-size: 100%; + } + .tree-item { + margin: 2em; + border-radius: 5px; + border: 1px solid gray; + padding: 1em; + } + .button-linky { + background: none; + color: black; + text-decoration: underline; + border: none; + } + </style> + </head> <body> <div id="container"></div> 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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="utf-8" /> -<head> - <meta charset="utf-8"> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> + <link rel="stylesheet" type="text/css" href="popup.css" /> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> - <link rel="stylesheet" type="text/css" href="popup.css"> - - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/popup-bundle.js"></script> -</head> - -<body> - <div id="container" style="margin:0;padding:0"></div> -</body> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/popup-bundle.js"></script> + </head> + <body> + <div id="container" style="margin: 0; padding: 0;"></div> + </body> </html> 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<any, any> { 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 ( <span> - <span style={{ fontSize: "5em", display: 'block'}}>{v}</span>{" "} + <span style={{ fontSize: "5em", display: "block" }}>{v}</span>{" "} <span>{amount.currency}</span> </span> ); @@ -281,7 +278,7 @@ class WalletBalanceView extends React.Component<any, any> { ); } - const l = [incoming, payment].filter(x => x !== undefined); + const l = [incoming, payment].filter((x) => x !== undefined); if (l.length === 0) { return <span />; } @@ -300,7 +297,7 @@ class WalletBalanceView extends React.Component<any, any> { const wallet = this.balance; if (this.gotError) { return ( - <div className='balance'> + <div className="balance"> <p>{i18n.str`Error: could not retrieve balance information.`}</p> <p> Click <PageLink pageName="welcome.html">here</PageLink> for help and @@ -313,7 +310,7 @@ class WalletBalanceView extends React.Component<any, any> { return <span></span>; } 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 ( <p> @@ -321,7 +318,11 @@ class WalletBalanceView extends React.Component<any, any> { </p> ); }); - return listing.length > 0 ? <div className='balance'>{listing}</div> : <EmptyBalanceView />; + return listing.length > 0 ? ( + <div className="balance">{listing}</div> + ) : ( + <EmptyBalanceView /> + ); } } @@ -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 ( <HistoryItem @@ -477,7 +477,7 @@ function formatHistoryItem(historyItem: HistoryEvent) { case "order-redirected": { const { merchant, item } = parseSummary( - historyItem.newOrderShortInfo.summary + historyItem.newOrderShortInfo.summary, ); return ( <HistoryItem @@ -492,7 +492,7 @@ function formatHistoryItem(historyItem: HistoryEvent) { case "payment-aborted": { const { merchant, item } = parseSummary( - historyItem.orderShortInfo.summary + historyItem.orderShortInfo.summary, ); return ( <HistoryItem @@ -510,18 +510,15 @@ function formatHistoryItem(historyItem: HistoryEvent) { case "payment-sent": { const url = historyItem.orderShortInfo.fulfillmentUrl; const { merchant, item } = parseSummary( - historyItem.orderShortInfo.summary + historyItem.orderShortInfo.summary, ); const fees = amountDiff( historyItem.amountPaidWithFees, - historyItem.orderShortInfo.amount + historyItem.orderShortInfo.amount, ); const fulfillmentLinkElem = ( <Fragment> - <a - href={url} - onClick={openTab(url)} - > + <a href={url} onClick={openTab(url)}> {item ? abbrev(item, 30) : null} </a> </Fragment> @@ -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 = ( <Fragment> - <a - href={url} - onClick={openTab(url)} - > + <a href={url} onClick={openTab(url)}> {item ? abbrev(item, 40) : null} </a> </Fragment> @@ -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 ( <HistoryItem @@ -663,9 +657,9 @@ class WalletHistory extends React.Component<any, any> { "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<any, any> { } 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<any, any> { } 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 = (<HistoryComponent key={record.eventId} record={record} />); + const item = <HistoryComponent key={record.eventId} record={record} />; listing.push(item); } @@ -821,5 +813,5 @@ function WalletPopup() { registerMountPage(() => { chrome.runtime.connect({ name: "popup" }); - return <WalletPopup /> + return <WalletPopup />; }); 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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="utf-8" /> -<head> - <meta charset="utf-8"> - - <script src="/src/webex/pages/redirect.js"></script> -</head> - -<body> - Redirecting to extension page ... -</body> + <script src="/src/webex/pages/redirect.js"></script> + </head> + <body> + Redirecting to extension page ... + </body> </html> 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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> + <title>Taler Wallet: Refund Status</title> -<head> - <meta charset="UTF-8"> - <title>Taler Wallet: Refund Status</title> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> + <link rel="icon" href="/img/icon.png" /> - <link rel="icon" href="/img/icon.png"> - - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/refund-bundle.js"></script> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/refund-bundle.js"></script> + </head> <body> <section id="main"> 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 }) { <h2>Refund Status</h2> <p> The product <em>{purchaseDetails.contractTerms.summary!}</em> has - received a total refund of <AmountView amount={purchaseDetails.totalRefundAmount} />. - </p> - <p> - Note that additional fees from the exchange may apply. + received a total refund of{" "} + <AmountView amount={purchaseDetails.totalRefundAmount} />. </p> + <p>Note that additional fees from the exchange may apply.</p> </> ); } 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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> + <title>Taler Wallet: Select Taler Provider</title> -<head> - <meta charset="UTF-8"> - <title>Taler Wallet: Select Taler Provider</title> + <link rel="icon" href="/img/icon.png" /> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> + <link rel="stylesheet" type="text/css" href="../style/pure.css" /> - <link rel="icon" href="/img/icon.png"> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> - <link rel="stylesheet" type="text/css" href="../style/pure.css"> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/reset-required-bundle.js"></script> - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/reset-required-bundle.js"></script> - - <style> - body { - font-size: 100%; - overflow-y: scroll; - } - </style> - -</head> - -<body> - <section id="main"> - <div id="container"></div> - </section> -</body> + <style> + body { + font-size: 100%; + overflow-y: scroll; + } + </style> + </head> + <body> + <section id="main"> + <div id="container"></div> + </section> + </body> </html> 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 <http://www.gnu.org/licenses/> */ - /** * Page to inform the user when a database reset is required. * @@ -38,16 +37,15 @@ class State { resetRequired: boolean; } - class ResetNotification extends React.Component<any, State> { 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<any, State> { <div> <h1>Manual Reset Reqired</h1> <p> - 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. </p> - <p>Once the database format has stabilized, we will provide automatic upgrades.</p> - <input id="check" - type="checkbox" - checked={this.state.checked} - onChange={(e) => this.setState({checked: e.target.checked})} />{" "} + <p> + Once the database format has stabilized, we will provide automatic + upgrades. + </p> + <input + id="check" + type="checkbox" + checked={this.state.checked} + onChange={(e) => this.setState({ checked: e.target.checked })} + />{" "} <label htmlFor="check"> I understand that I will lose all my data </label> <br /> - <button className="pure-button" disabled={!this.state.checked} onClick={() => wxApi.resetDb()}>Reset</button> + <button + className="pure-button" + disabled={!this.state.checked} + onClick={() => wxApi.resetDb()} + > + Reset + </button> </div> ); } return ( <div> - <h1>Everything is fine!</h1> - A reset is not required anymore, you can close this page. + <h1>Everything is fine!</h1>A reset is not required anymore, you can + close this page. </div> ); } } - document.addEventListener("DOMContentLoaded", () => { - ReactDOM.render(<ResetNotification />, document.getElementById( "container")!); + ReactDOM.render(<ResetNotification />, 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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> + <title>Taler Wallet: Return Coins to Bank Account</title> -<head> - <meta charset="UTF-8"> - <title>Taler Wallet: Return Coins to Bank Account</title> + <link rel="stylesheet" type="text/css" href="../style/pure.css" /> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> - <link rel="stylesheet" type="text/css" href="../style/pure.css"> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> + <link rel="icon" href="/img/icon.png" /> - <link rel="icon" href="/img/icon.png"> - - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/return-coins-bundle.js"></script> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/return-coins-bundle.js"></script> + </head> <body> <div id="container"></div> 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<ReturnSelectionItemProps, ReturnSelectionItemState> { +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<ReturnSelectionItemProps, Retu <div key={exchange}> <h2>Exchange {exchange}</h2> <p>Available amount: {renderAmount(byExchange[exchange].available)}</p> - <p>Supported wire methods: {wireTypes[exchange].length ? wireTypes[exchange].join(", ") : "none"}</p> - <p>Wire {""} - <input - type="text" - size={this.state.selectedValue.length || 1} - value={this.state.selectedValue} - onChange={(evt) => this.setState({selectedValue: evt.target.value})} - style={{textAlign: "center"}} - /> {this.props.balance.byExchange[exchange].available.currency} {""} - to account {""} - <select value={this.state.selectedWire} onChange={(evt) => this.setState({selectedWire: evt.target.value})}> - <option style={{display: "none"}}>Select account</option> - {this.state.supportedWires.map((w, n) => - <option value={n.toString()} key={JSON.stringify(w)}>{n + 1}: {wire.summarizeWire(w)}</option>, - )} - </select>. + <p> + Supported wire methods:{" "} + {wireTypes[exchange].length ? wireTypes[exchange].join(", ") : "none"} + </p> + <p> + Wire {""} + <input + type="text" + size={this.state.selectedValue.length || 1} + value={this.state.selectedValue} + onChange={(evt) => + this.setState({ selectedValue: evt.target.value }) + } + style={{ textAlign: "center" }} + />{" "} + {this.props.balance.byExchange[exchange].available.currency} {""} + to account {""} + <select + value={this.state.selectedWire} + onChange={(evt) => + this.setState({ selectedWire: evt.target.value }) + } + > + <option style={{ display: "none" }}>Select account</option> + {this.state.supportedWires.map((w, n) => ( + <option value={n.toString()} key={JSON.stringify(w)}> + {n + 1}: {wire.summarizeWire(w)} + </option> + ))} + </select> + . </p> - {this.state.selectedWire - ? <button className="pure-button button-success" onClick={() => this.select()}> - {i18n.str`Wire to bank account`} - </button> - : null} + {this.state.selectedWire ? ( + <button + className="pure-button button-success" + onClick={() => this.select()} + > + {i18n.str`Wire to bank account`} + </button> + ) : null} </div> ); } @@ -133,16 +153,23 @@ interface ReturnSelectionListProps { selectDetail(d: SelectedDetail): void; } -class ReturnSelectionList extends React.Component<ReturnSelectionListProps, {}> { +class ReturnSelectionList extends React.Component< + ReturnSelectionListProps, + {} +> { render(): JSX.Element { const byExchange = this.props.balance.byExchange; const exchanges = Object.keys(byExchange); if (!exchanges.length) { - return <p className="errorbox">Currently no funds available to transfer.</p>; + return ( + <p className="errorbox">Currently no funds available to transfer.</p> + ); } return ( <div> - {exchanges.map((e) => <ReturnSelectionItem key={e} exchangeUrl={e} {...this.props} />)} + {exchanges.map((e) => ( + <ReturnSelectionItem key={e} exchangeUrl={e} {...this.props} /> + ))} </div> ); } @@ -154,7 +181,6 @@ interface SelectedDetail { exchange: string; } - interface ReturnConfirmationProps { detail: SelectedDetail; cancel(): void; @@ -165,11 +191,19 @@ class ReturnConfirmation extends React.Component<ReturnConfirmationProps, {}> { render() { return ( <div> - <p>Please confirm if you want to transmit <strong>{renderAmount(this.props.detail.amount)}</strong> at {""} - {this.props.detail.exchange} to account {""} - <strong style={{whiteSpace: "nowrap"}}>{wire.summarizeWire(this.props.detail.senderWire)}</strong>. + <p> + Please confirm if you want to transmit{" "} + <strong>{renderAmount(this.props.detail.amount)}</strong> at {""} + {this.props.detail.exchange} to account {""} + <strong style={{ whiteSpace: "nowrap" }}> + {wire.summarizeWire(this.props.detail.senderWire)} + </strong> + . </p> - <button className="pure-button button-success" onClick={() => this.props.confirm()}> + <button + className="pure-button button-success" + onClick={() => this.props.confirm()} + > {i18n.str`Confirm`} </button> <button className="pure-button" onClick={() => this.props.cancel()}> @@ -213,7 +247,7 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> { } selectDetail(d: SelectedDetail) { - this.setState({selectedReturn: d}); + this.setState({ selectedReturn: d }); } async confirm() { @@ -223,11 +257,17 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> { } await returnCoins(selectedReturn); await this.update(); - this.setState({selectedReturn: undefined, lastConfirmedDetail: selectedReturn}); + this.setState({ + selectedReturn: undefined, + lastConfirmedDetail: selectedReturn, + }); } async cancel() { - this.setState({selectedReturn: undefined, lastConfirmedDetail: undefined}); + this.setState({ + selectedReturn: undefined, + lastConfirmedDetail: undefined, + }); } render() { @@ -248,25 +288,28 @@ class ReturnCoins extends React.Component<{}, ReturnCoinsState> { ); } return ( - <div id="main"> - <h1>Wire electronic cash back to own bank account</h1> - <p>You can send coins back into your own bank account. Note that - you're acting as a merchant when doing this, and thus the same fees apply.</p> - {this.state.lastConfirmedDetail - ? <p className="okaybox"> - Transfer of {renderAmount(this.state.lastConfirmedDetail.amount)} successfully initiated. - </p> - : null} - <ReturnSelectionList - selectDetail={(d) => this.selectDetail(d)} - balance={balance} - senderWireInfos={senderWireInfos} /> - </div> + <div id="main"> + <h1>Wire electronic cash back to own bank account</h1> + <p> + You can send coins back into your own bank account. Note that you're + acting as a merchant when doing this, and thus the same fees apply. + </p> + {this.state.lastConfirmedDetail ? ( + <p className="okaybox"> + Transfer of {renderAmount(this.state.lastConfirmedDetail.amount)}{" "} + successfully initiated. + </p> + ) : null} + <ReturnSelectionList + selectDetail={(d) => this.selectDetail(d)} + balance={balance} + senderWireInfos={senderWireInfos} + /> + </div> ); } } - function main() { ReactDOM.render(<ReturnCoins />, document.getElementById("container")!); } diff --git a/src/webex/pages/show-db.html b/src/webex/pages/show-db.html index 714089553..ae77e3fb0 100644 --- a/src/webex/pages/show-db.html +++ b/src/webex/pages/show-db.html @@ -1,16 +1,16 @@ -<!doctype html> +<!DOCTYPE html> <html> <head> - <meta charset="UTF-8"> + <meta charset="UTF-8" /> <title>Taler Wallet: Reserve Created</title> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> - <link rel="icon" href="/img/icon.png"> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> + <link rel="icon" href="/img/icon.png" /> <script src="/dist/page-common-bundle.js"></script> <script src="/dist/show-db-bundle.js"></script> </head> <body> <h1>DB Dump</h1> - <input type="file" id="fileInput" style="display:none"> + <input type="file" id="fileInput" style="display: none;" /> <button id="import">Import Dump</button> <button id="download">Download Dump</button> <pre id="dump"></pre> 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 <http://www.gnu.org/licenses/> */ - /** * 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 = "<span class=json-key>"; const val = "<span class=json-value>"; const str = "<span class=json-string>"; @@ -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(/>/g, ">") - .replace(jsonLine, replacer); + .replace(/&/g, "&") + .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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> + <title>Taler Wallet: Received Tip</title> -<head> - <meta charset="UTF-8"> - <title>Taler Wallet: Received Tip</title> + <link rel="icon" href="/img/icon.png" /> + <link rel="stylesheet" type="text/css" href="../style/pure.css" /> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> - <link rel="icon" href="/img/icon.png"> - <link rel="stylesheet" type="text/css" href="../style/pure.css"> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> - - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/tip-bundle.js"></script> - -</head> - -<body> - <section id="main"> - <h1>GNU Taler Wallet</h1> - <div id="container"></div> - </section> -</body> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/tip-bundle.js"></script> + </head> + <body> + <section id="main"> + <h1>GNU Taler Wallet</h1> + <div id="container"></div> + </section> + </body> </html> 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<TipStatus | undefined>(undefined); const [discarded, setDiscarded] = useState(false); @@ -88,8 +91,7 @@ function TipDisplay(props: { talerTipUri: string }) { <form className="pure-form"> <ProgressButton loading={loading} onClick={() => accept()}> Accept Tip - </ProgressButton> - {" "} + </ProgressButton>{" "} <button className="pure-button" type="button" onClick={() => discard()}> Discard tip </button> 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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> + <title>Taler Wallet: Withdraw</title> -<head> - <meta charset="UTF-8"> - <title>Taler Wallet: Withdraw</title> + <link rel="icon" href="/img/icon.png" /> + <link rel="stylesheet" type="text/css" href="../style/pure.css" /> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> - <link rel="icon" href="/img/icon.png"> - <link rel="stylesheet" type="text/css" href="../style/pure.css"> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> - - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/welcome-bundle.js"></script> - -</head> - -<body> - <section id="main"> - <h1>GNU Taler Wallet Installed!</h1> - <div id="container">Loading...</div> - </section> -</body> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/welcome-bundle.js"></script> + </head> + <body> + <section id="main"> + <h1>GNU Taler Wallet Installed!</h1> + <div id="container">Loading...</div> + </section> + </body> </html> 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() { > <p>Problems detected:</p> <ol> - {diagnostics.errors.map(errMsg => ( + {diagnostics.errors.map((errMsg) => ( <li>{errMsg}</li> ))} </ol> 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 @@ <!DOCTYPE html> <html> + <head> + <meta charset="UTF-8" /> + <title>Taler Wallet: Withdraw</title> -<head> - <meta charset="UTF-8"> - <title>Taler Wallet: Withdraw</title> + <link rel="icon" href="/img/icon.png" /> + <link rel="stylesheet" type="text/css" href="../style/pure.css" /> + <link rel="stylesheet" type="text/css" href="../style/wallet.css" /> - <link rel="icon" href="/img/icon.png"> - <link rel="stylesheet" type="text/css" href="../style/pure.css"> - <link rel="stylesheet" type="text/css" href="../style/wallet.css"> + <script src="/dist/page-common-bundle.js"></script> + <script src="/dist/withdraw-bundle.js"></script> + </head> - <script src="/dist/page-common-bundle.js"></script> - <script src="/dist/withdraw-bundle.js"></script> - -</head> - -<body> - <section id="main"> - <h1>GNU Taler Wallet</h1> + <body> + <section id="main"> + <h1>GNU Taler Wallet</h1> <div class="fade" id="exchange-selection"></div> - </section> -</body> - + </section> + </body> </html> 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 }) { <p> <input type="text" - onChange={e => setCustomUrl(e.target.value)} + onChange={(e) => setCustomUrl(e.target.value)} value={customUrl} /> </p> 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 ( <div> - {(rci.exchangeInfo.details?.auditors ?? []).map(a => ( + {(rci.exchangeInfo.details?.auditors ?? []).map((a) => ( <div> <h3>Auditor {a.auditor_url}</h3> <p> @@ -214,7 +214,7 @@ function FeeDetailsView(props: { </tr> </thead>, <tbody> - {rci!.wireFees.feesForType[s].map(f => ( + {rci!.wireFees.feesForType[s].map((f) => ( <tr> <td>{stringifyTimestamp(f.endStamp)}</td> <td>{renderAmount(f.wireFee)}</td> @@ -232,7 +232,10 @@ function FeeDetailsView(props: { <div> <h3>Overview</h3> <p> - Public key: <ExpanderText text={rci.exchangeInfo.details?.masterPublicKey ?? "??"} /> + Public key:{" "} + <ExpanderText + text={rci.exchangeInfo.details?.masterPublicKey ?? "??"} + /> </p> <p> {i18n.str`Withdrawal fees:`} {withdrawFee} @@ -240,8 +243,9 @@ function FeeDetailsView(props: { <p> {i18n.str`Rounding loss:`} {overhead} </p> - <p>{i18n.str`Earliest expiration (for deposit): ${ - stringifyTimestamp(rci.earliestDepositExpiration)}`}</p> + <p>{i18n.str`Earliest expiration (for deposit): ${stringifyTimestamp( + rci.earliestDepositExpiration, + )}`}</p> <h3>Coin Fees</h3> <div style={{ overflow: "auto" }}> <table className="pure-table"> 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<T extends MessageType>( detail: MessageMap[T]["request"], ): Promise<MessageMap[T]["response"]> { return new Promise<MessageMap[T]["response"]>((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"); |