refactor / format

This commit is contained in:
Florian Dold 2019-09-05 16:23:54 +02:00
parent 8144b0f553
commit 51aa6d8146
No known key found for this signature in database
GPG Key ID: D2E4F00F29D02A4B
8 changed files with 149 additions and 174 deletions

View File

@ -23,14 +23,13 @@
import * as i18n from "../../i18n";
import { runOnceWhenReady } from "./common";
import { BenchmarkResult } from "../../walletTypes";
import * as wxApi from "../wxApi";
import * as React from "react";
import * as ReactDOM from "react-dom";
import { registerMountPage } from "../renderHtml";
interface BenchmarkRunnerState {
@ -103,9 +102,6 @@ class BenchmarkRunner extends React.Component<any, BenchmarkRunnerState> {
}
}
runOnceWhenReady(() => {
ReactDOM.render(<BenchmarkRunner />, document.getElementById("container")!);
// Will be used by the backend to detect when the popup gets closed,
// so we can clear notifications
registerMountPage(() => {
return <BenchmarkRunner />;
});

View File

@ -1,31 +0,0 @@
/*
This file is part of TALER
(C) 2018 GNUnet e.V.
TALER is free software; you can redistribute it and/or modify it under the
terms of the GNU General Public License as published by the Free Software
Foundation; either version 3, or (at your option) any later version.
TALER is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
/**
* Common helper functions for all web extension pages.
*/
/**
* Make sure that a function is executed exactly once
* after the DOM has been loaded.
*/
export function runOnceWhenReady(f: () => void): void {
if (document.readyState === "loading") {
document.addEventListener("DOMContentLoaded", f);
return;
}
f();
}

View File

@ -72,7 +72,7 @@
<body>
<section id="main">
<h1>GNU Taler Wallet</h1>
<article id="contract" class="fade"></article>
<article id="container" class="fade"></article>
</section>
</body>

View File

@ -24,19 +24,13 @@
*/
import * as i18n from "../../i18n";
import { runOnceWhenReady } from "./common";
import { ExchangeRecord, ProposalDownloadRecord } from "../../dbTypes";
import { ContractTerms } from "../../talerTypes";
import { CheckPayResult, PreparePayResult } from "../../walletTypes";
import { renderAmount, ProgressButton } from "../renderHtml";
import { renderAmount, ProgressButton, registerMountPage } from "../renderHtml";
import * as wxApi from "../wxApi";
import React, { useState, useEffect } from "react";
import * as ReactDOM from "react-dom";
import URI = require("urijs");
import { WalletApiError } from "../wxApi";
import * as Amounts from "../../amounts";
@ -153,22 +147,11 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) {
);
}
runOnceWhenReady(() => {
try {
registerMountPage(() => {
const url = new URI(document.location.href);
const query: any = URI.parseQuery(url.query());
let talerPayUri = query.talerPayUri;
ReactDOM.render(
<TalerPayDialog talerPayUri={talerPayUri} />,
document.getElementById("contract")!,
);
} catch (e) {
ReactDOM.render(
<span>Fatal error: {e.message}</span>,
document.getElementById("contract")!,
);
console.error(e);
}
return <TalerPayDialog talerPayUri={talerPayUri} />;
});

View File

@ -12,7 +12,7 @@
</head>
<body>
<div id="content" style="margin:0;padding:0"></div>
<div id="container" style="margin:0;padding:0"></div>
</body>
</html>

View File

@ -26,8 +26,6 @@
*/
import * as i18n from "../../i18n";
import { runOnceWhenReady } from "./common";
import { AmountJson } from "../../amounts";
import * as Amounts from "../../amounts";
@ -37,7 +35,12 @@ import {
WalletBalanceEntry,
} from "../../walletTypes";
import { abbrev, renderAmount, PageLink } from "../renderHtml";
import {
abbrev,
renderAmount,
PageLink,
registerMountPage,
} from "../renderHtml";
import * as wxApi from "../wxApi";
import * as React from "react";
@ -196,8 +199,7 @@ function EmptyBalanceView() {
<div>
<i18n.Translate wrap="p">
You have no balance to show. Need some{" "}
<PageLink pageName="welcome.html">help</PageLink> getting
started?
<PageLink pageName="welcome.html">help</PageLink> getting started?
</i18n.Translate>
</div>
);
@ -303,7 +305,8 @@ class WalletBalanceView extends React.Component<any, any> {
<div>
<p>{i18n.str`Error: could not retrieve balance information.`}</p>
<p>
Click <PageLink pageName="welcome.html">here</PageLink> for help and diagnostics.
Click <PageLink pageName="welcome.html">here</PageLink> for help and
diagnostics.
</p>
</div>
);
@ -551,7 +554,8 @@ function openTab(page: string) {
};
}
const el = (
function WalletPopup() {
return (
<div>
<WalletNavBar />
<div style={{ margin: "1em" }}>
@ -563,10 +567,9 @@ const el = (
</div>
</div>
);
}
runOnceWhenReady(() => {
ReactDOM.render(el, document.getElementById("content")!);
// Will be used by the backend to detect when the popup gets closed,
// so we can clear notifications
registerMountPage(() => {
chrome.runtime.connect({ name: "popup" });
return <WalletPopup />
});

View File

@ -20,24 +20,18 @@
* @author Florian Dold
*/
/**
* Imports.
*/
import { AmountJson } from "../amounts";
import * as Amounts from "../amounts";
import {
DenominationRecord,
} from "../dbTypes";
import {
ReserveCreationInfo,
} from "../walletTypes";
import { DenominationRecord } from "../dbTypes";
import { ReserveCreationInfo } from "../walletTypes";
import * as moment from "moment";
import * as i18n from "../i18n";
import React from "react";
import ReactDOM from "react-dom";
/**
* Render amount as HTML, which non-breaking space between
* decimal value and currency.
@ -53,11 +47,15 @@ export function renderAmount(amount: AmountJson | string) {
return <span>(invalid amount)</span>;
}
const x = a.value + a.fraction / Amounts.fractionalBase;
return <span>{x}&nbsp;{a.currency}</span>;
return (
<span>
{x}&nbsp;{a.currency}
</span>
);
}
export const AmountView = ({amount}: {amount: AmountJson | string}) => renderAmount(amount);
export const AmountView = ({ amount }: { amount: AmountJson | string }) =>
renderAmount(amount);
/**
* Abbreviate a string to a given length, and show the full
@ -75,23 +73,23 @@ export function abbrev(s: string, n: number = 5) {
);
}
interface CollapsibleState {
collapsed: boolean;
}
interface CollapsibleProps {
initiallyCollapsed: boolean;
title: string;
}
/**
* Component that shows/hides its children when clicking
* a heading.
*/
export class Collapsible extends React.Component<CollapsibleProps, CollapsibleState> {
export class Collapsible extends React.Component<
CollapsibleProps,
CollapsibleState
> {
constructor(props: CollapsibleProps) {
super(props);
this.state = { collapsed: props.initiallyCollapsed };
@ -106,19 +104,30 @@ export class Collapsible extends React.Component<CollapsibleProps, CollapsibleSt
e.preventDefault();
};
if (this.state.collapsed) {
return <h2><a className="opener opener-collapsed" href="#" onClick={doOpen}>{this.props.title}</a></h2>;
return (
<h2>
<a className="opener opener-collapsed" href="#" onClick={doOpen}>
{this.props.title}
</a>
</h2>
);
}
return (
<div>
<h2><a className="opener opener-open" href="#" onClick={doClose}>{this.props.title}</a></h2>
<h2>
<a className="opener opener-open" href="#" onClick={doClose}>
{this.props.title}
</a>
</h2>
{this.props.children}
</div>
);
}
}
function AuditorDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
function AuditorDetailsView(props: {
rci: ReserveCreationInfo | null;
}): JSX.Element {
const rci = props.rci;
console.log("rci", rci);
if (!rci) {
@ -129,27 +138,33 @@ function AuditorDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element
);
}
if (rci.exchangeInfo.auditors.length === 0) {
return (
<p>
The exchange is not audited by any auditors.
</p>
);
return <p>The exchange is not audited by any auditors.</p>;
}
return (
<div>
{rci.exchangeInfo.auditors.map((a) => (
{rci.exchangeInfo.auditors.map(a => (
<div>
<h3>Auditor {a.auditor_url}</h3>
<p>Public key: <ExpanderText text={a.auditor_pub} /></p>
<p>Trusted: {rci.trustedAuditorPubs.indexOf(a.auditor_pub) >= 0 ? "yes" : "no"}</p>
<p>Audits {a.denomination_keys.length} of {rci.numOfferedDenoms} denominations</p>
<p>
Public key: <ExpanderText text={a.auditor_pub} />
</p>
<p>
Trusted:{" "}
{rci.trustedAuditorPubs.indexOf(a.auditor_pub) >= 0 ? "yes" : "no"}
</p>
<p>
Audits {a.denomination_keys.length} of {rci.numOfferedDenoms}{" "}
denominations
</p>
</div>
))}
</div>
);
}
function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
function FeeDetailsView(props: {
rci: ReserveCreationInfo | null;
}): JSX.Element {
const rci = props.rci;
if (!rci) {
return (
@ -198,7 +213,7 @@ function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
</tr>
</thead>,
<tbody>
{rci!.wireFees.feesForType[s].map((f) => (
{rci!.wireFees.feesForType[s].map(f => (
<tr>
<td>{moment.unix(f.endStamp).format("llll")}</td>
<td>{renderAmount(f.wireFee)}</td>
@ -215,10 +230,18 @@ function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
return (
<div>
<h3>Overview</h3>
<p>Public key: <ExpanderText text={rci.exchangeInfo.masterPublicKey} /></p>
<p>{i18n.str`Withdrawal fees:`} {withdrawFee}</p>
<p>{i18n.str`Rounding loss:`} {overhead}</p>
<p>{i18n.str`Earliest expiration (for deposit): ${moment.unix(rci.earliestDepositExpiration).fromNow()}`}</p>
<p>
Public key: <ExpanderText text={rci.exchangeInfo.masterPublicKey} />
</p>
<p>
{i18n.str`Withdrawal fees:`} {withdrawFee}
</p>
<p>
{i18n.str`Rounding loss:`} {overhead}
</p>
<p>{i18n.str`Earliest expiration (for deposit): ${moment
.unix(rci.earliestDepositExpiration)
.fromNow()}`}</p>
<h3>Coin Fees</h3>
<div style={{ overflow: "auto" }}>
<table className="pure-table">
@ -231,9 +254,7 @@ function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
<th>{i18n.str`Deposit Fee`}</th>
</tr>
</thead>
<tbody>
{uniq.map(row)}
</tbody>
<tbody>{uniq.map(row)}</tbody>
</table>
</div>
<h3>Wire Fees</h3>
@ -249,7 +270,9 @@ function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
/**
* Shows details about a withdraw request.
*/
export function WithdrawDetailView(props: {rci: ReserveCreationInfo | null}): JSX.Element {
export function WithdrawDetailView(props: {
rci: ReserveCreationInfo | null;
}): JSX.Element {
const rci = props.rci;
return (
<div>
@ -263,12 +286,10 @@ export function WithdrawDetailView(props: {rci: ReserveCreationInfo | null}): JS
);
}
interface ExpanderTextProps {
text: string;
}
/**
* Show a heading with a toggle to show/hide the expandable content.
*/
@ -276,16 +297,13 @@ export function ExpanderText({ text }: ExpanderTextProps) {
return <span>{text}</span>;
}
export interface LoadingButtonProps {
loading: boolean;
}
export function ProgressButton(
props:
& React.PropsWithChildren<LoadingButtonProps>
& React.DetailedHTMLProps<
props: React.PropsWithChildren<LoadingButtonProps> &
React.DetailedHTMLProps<
React.ButtonHTMLAttributes<HTMLButtonElement>,
HTMLButtonElement
>,
@ -296,8 +314,14 @@ export function ProgressButton(
type="button"
{...props}
>
{props.loading ? <span><object className="svg-icon svg-baseline" data="/img/spinner-bars.svg" /></span> : null}
{" "}
{props.loading ? (
<span>
<object
className="svg-icon svg-baseline"
data="/img/spinner-bars.svg"
/>
</span>
) : null}{" "}
{props.children}
</button>
);
@ -311,10 +335,7 @@ export function registerMountPage(mainFn: () => React.ReactElement) {
if (!container) {
throw Error("container not found, can't mount page contents");
}
ReactDOM.render(
mainElement,
container,
);
ReactDOM.render(mainElement, container);
} catch (e) {
document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`;
console.error("got error", e);
@ -331,5 +352,9 @@ export function registerMountPage(mainFn: () => React.ReactElement) {
export function PageLink(props: React.PropsWithChildren<{ pageName: string }>) {
const url = chrome.extension.getURL(`/src/webex/pages/${props.pageName}`);
return <a className="actionLink" href={url} target="_blank">{props.children}</a>;
return (
<a className="actionLink" href={url} target="_blank">
{props.children}
</a>
);
}

View File

@ -71,7 +71,6 @@
"src/webex/pages/add-auditor.tsx",
"src/webex/pages/auditors.tsx",
"src/webex/pages/benchmark.tsx",
"src/webex/pages/common.ts",
"src/webex/pages/error.tsx",
"src/webex/pages/logs.tsx",
"src/webex/pages/pay.tsx",