refactor / format
This commit is contained in:
parent
8144b0f553
commit
51aa6d8146
@ -23,14 +23,13 @@
|
|||||||
|
|
||||||
import * as i18n from "../../i18n";
|
import * as i18n from "../../i18n";
|
||||||
|
|
||||||
import { runOnceWhenReady } from "./common";
|
|
||||||
|
|
||||||
import { BenchmarkResult } from "../../walletTypes";
|
import { BenchmarkResult } from "../../walletTypes";
|
||||||
|
|
||||||
import * as wxApi from "../wxApi";
|
import * as wxApi from "../wxApi";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
import * as ReactDOM from "react-dom";
|
import * as ReactDOM from "react-dom";
|
||||||
|
import { registerMountPage } from "../renderHtml";
|
||||||
|
|
||||||
|
|
||||||
interface BenchmarkRunnerState {
|
interface BenchmarkRunnerState {
|
||||||
@ -103,9 +102,6 @@ class BenchmarkRunner extends React.Component<any, BenchmarkRunnerState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
registerMountPage(() => {
|
||||||
runOnceWhenReady(() => {
|
return <BenchmarkRunner />;
|
||||||
ReactDOM.render(<BenchmarkRunner />, document.getElementById("container")!);
|
|
||||||
// Will be used by the backend to detect when the popup gets closed,
|
|
||||||
// so we can clear notifications
|
|
||||||
});
|
});
|
||||||
|
@ -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();
|
|
||||||
}
|
|
@ -72,7 +72,7 @@
|
|||||||
<body>
|
<body>
|
||||||
<section id="main">
|
<section id="main">
|
||||||
<h1>GNU Taler Wallet</h1>
|
<h1>GNU Taler Wallet</h1>
|
||||||
<article id="contract" class="fade"></article>
|
<article id="container" class="fade"></article>
|
||||||
</section>
|
</section>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
@ -24,19 +24,13 @@
|
|||||||
*/
|
*/
|
||||||
import * as i18n from "../../i18n";
|
import * as i18n from "../../i18n";
|
||||||
|
|
||||||
import { runOnceWhenReady } from "./common";
|
|
||||||
|
|
||||||
import { ExchangeRecord, ProposalDownloadRecord } from "../../dbTypes";
|
|
||||||
import { ContractTerms } from "../../talerTypes";
|
|
||||||
import { CheckPayResult, PreparePayResult } from "../../walletTypes";
|
import { CheckPayResult, PreparePayResult } from "../../walletTypes";
|
||||||
|
|
||||||
import { renderAmount, ProgressButton } from "../renderHtml";
|
import { renderAmount, ProgressButton, registerMountPage } from "../renderHtml";
|
||||||
import * as wxApi from "../wxApi";
|
import * as wxApi from "../wxApi";
|
||||||
|
|
||||||
import React, { useState, useEffect } from "react";
|
import React, { useState, useEffect } from "react";
|
||||||
import * as ReactDOM from "react-dom";
|
|
||||||
import URI = require("urijs");
|
import URI = require("urijs");
|
||||||
import { WalletApiError } from "../wxApi";
|
|
||||||
|
|
||||||
import * as Amounts from "../../amounts";
|
import * as Amounts from "../../amounts";
|
||||||
|
|
||||||
@ -153,22 +147,11 @@ function TalerPayDialog({ talerPayUri }: { talerPayUri: string }) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
runOnceWhenReady(() => {
|
registerMountPage(() => {
|
||||||
try {
|
|
||||||
const url = new URI(document.location.href);
|
const url = new URI(document.location.href);
|
||||||
const query: any = URI.parseQuery(url.query());
|
const query: any = URI.parseQuery(url.query());
|
||||||
|
|
||||||
let talerPayUri = query.talerPayUri;
|
let talerPayUri = query.talerPayUri;
|
||||||
|
|
||||||
ReactDOM.render(
|
return <TalerPayDialog talerPayUri={talerPayUri} />;
|
||||||
<TalerPayDialog talerPayUri={talerPayUri} />,
|
|
||||||
document.getElementById("contract")!,
|
|
||||||
);
|
|
||||||
} catch (e) {
|
|
||||||
ReactDOM.render(
|
|
||||||
<span>Fatal error: {e.message}</span>,
|
|
||||||
document.getElementById("contract")!,
|
|
||||||
);
|
|
||||||
console.error(e);
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<div id="content" style="margin:0;padding:0"></div>
|
<div id="container" style="margin:0;padding:0"></div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -26,8 +26,6 @@
|
|||||||
*/
|
*/
|
||||||
import * as i18n from "../../i18n";
|
import * as i18n from "../../i18n";
|
||||||
|
|
||||||
import { runOnceWhenReady } from "./common";
|
|
||||||
|
|
||||||
import { AmountJson } from "../../amounts";
|
import { AmountJson } from "../../amounts";
|
||||||
import * as Amounts from "../../amounts";
|
import * as Amounts from "../../amounts";
|
||||||
|
|
||||||
@ -37,7 +35,12 @@ import {
|
|||||||
WalletBalanceEntry,
|
WalletBalanceEntry,
|
||||||
} from "../../walletTypes";
|
} from "../../walletTypes";
|
||||||
|
|
||||||
import { abbrev, renderAmount, PageLink } from "../renderHtml";
|
import {
|
||||||
|
abbrev,
|
||||||
|
renderAmount,
|
||||||
|
PageLink,
|
||||||
|
registerMountPage,
|
||||||
|
} from "../renderHtml";
|
||||||
import * as wxApi from "../wxApi";
|
import * as wxApi from "../wxApi";
|
||||||
|
|
||||||
import * as React from "react";
|
import * as React from "react";
|
||||||
@ -196,8 +199,7 @@ function EmptyBalanceView() {
|
|||||||
<div>
|
<div>
|
||||||
<i18n.Translate wrap="p">
|
<i18n.Translate wrap="p">
|
||||||
You have no balance to show. Need some{" "}
|
You have no balance to show. Need some{" "}
|
||||||
<PageLink pageName="welcome.html">help</PageLink> getting
|
<PageLink pageName="welcome.html">help</PageLink> getting started?
|
||||||
started?
|
|
||||||
</i18n.Translate>
|
</i18n.Translate>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -303,7 +305,8 @@ class WalletBalanceView extends React.Component<any, any> {
|
|||||||
<div>
|
<div>
|
||||||
<p>{i18n.str`Error: could not retrieve balance information.`}</p>
|
<p>{i18n.str`Error: could not retrieve balance information.`}</p>
|
||||||
<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>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
@ -551,7 +554,8 @@ function openTab(page: string) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const el = (
|
function WalletPopup() {
|
||||||
|
return (
|
||||||
<div>
|
<div>
|
||||||
<WalletNavBar />
|
<WalletNavBar />
|
||||||
<div style={{ margin: "1em" }}>
|
<div style={{ margin: "1em" }}>
|
||||||
@ -562,11 +566,10 @@ const el = (
|
|||||||
</Router>
|
</Router>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
runOnceWhenReady(() => {
|
registerMountPage(() => {
|
||||||
ReactDOM.render(el, document.getElementById("content")!);
|
|
||||||
// Will be used by the backend to detect when the popup gets closed,
|
|
||||||
// so we can clear notifications
|
|
||||||
chrome.runtime.connect({ name: "popup" });
|
chrome.runtime.connect({ name: "popup" });
|
||||||
|
return <WalletPopup />
|
||||||
});
|
});
|
||||||
|
@ -20,24 +20,18 @@
|
|||||||
* @author Florian Dold
|
* @author Florian Dold
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Imports.
|
* Imports.
|
||||||
*/
|
*/
|
||||||
import { AmountJson } from "../amounts";
|
import { AmountJson } from "../amounts";
|
||||||
import * as Amounts from "../amounts";
|
import * as Amounts from "../amounts";
|
||||||
import {
|
import { DenominationRecord } from "../dbTypes";
|
||||||
DenominationRecord,
|
import { ReserveCreationInfo } from "../walletTypes";
|
||||||
} from "../dbTypes";
|
|
||||||
import {
|
|
||||||
ReserveCreationInfo,
|
|
||||||
} from "../walletTypes";
|
|
||||||
import * as moment from "moment";
|
import * as moment from "moment";
|
||||||
import * as i18n from "../i18n";
|
import * as i18n from "../i18n";
|
||||||
import React from "react";
|
import React from "react";
|
||||||
import ReactDOM from "react-dom";
|
import ReactDOM from "react-dom";
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render amount as HTML, which non-breaking space between
|
* Render amount as HTML, which non-breaking space between
|
||||||
* decimal value and currency.
|
* decimal value and currency.
|
||||||
@ -53,11 +47,15 @@ export function renderAmount(amount: AmountJson | string) {
|
|||||||
return <span>(invalid amount)</span>;
|
return <span>(invalid amount)</span>;
|
||||||
}
|
}
|
||||||
const x = a.value + a.fraction / Amounts.fractionalBase;
|
const x = a.value + a.fraction / Amounts.fractionalBase;
|
||||||
return <span>{x} {a.currency}</span>;
|
return (
|
||||||
|
<span>
|
||||||
|
{x} {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
|
* Abbreviate a string to a given length, and show the full
|
||||||
@ -75,50 +73,61 @@ export function abbrev(s: string, n: number = 5) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface CollapsibleState {
|
interface CollapsibleState {
|
||||||
collapsed: boolean;
|
collapsed: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface CollapsibleProps {
|
interface CollapsibleProps {
|
||||||
initiallyCollapsed: boolean;
|
initiallyCollapsed: boolean;
|
||||||
title: string;
|
title: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that shows/hides its children when clicking
|
* Component that shows/hides its children when clicking
|
||||||
* a heading.
|
* a heading.
|
||||||
*/
|
*/
|
||||||
export class Collapsible extends React.Component<CollapsibleProps, CollapsibleState> {
|
export class Collapsible extends React.Component<
|
||||||
|
CollapsibleProps,
|
||||||
|
CollapsibleState
|
||||||
|
> {
|
||||||
constructor(props: CollapsibleProps) {
|
constructor(props: CollapsibleProps) {
|
||||||
super(props);
|
super(props);
|
||||||
this.state = { collapsed: props.initiallyCollapsed };
|
this.state = { collapsed: props.initiallyCollapsed };
|
||||||
}
|
}
|
||||||
render() {
|
render() {
|
||||||
const doOpen = (e: any) => {
|
const doOpen = (e: any) => {
|
||||||
this.setState({collapsed: false});
|
this.setState({ collapsed: false });
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
const doClose = (e: any) => {
|
const doClose = (e: any) => {
|
||||||
this.setState({collapsed: true});
|
this.setState({ collapsed: true });
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
};
|
};
|
||||||
if (this.state.collapsed) {
|
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 (
|
return (
|
||||||
<div>
|
<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}
|
{this.props.children}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function AuditorDetailsView(props: {
|
||||||
function AuditorDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
|
rci: ReserveCreationInfo | null;
|
||||||
|
}): JSX.Element {
|
||||||
const rci = props.rci;
|
const rci = props.rci;
|
||||||
console.log("rci", rci);
|
console.log("rci", rci);
|
||||||
if (!rci) {
|
if (!rci) {
|
||||||
@ -129,27 +138,33 @@ function AuditorDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (rci.exchangeInfo.auditors.length === 0) {
|
if (rci.exchangeInfo.auditors.length === 0) {
|
||||||
return (
|
return <p>The exchange is not audited by any auditors.</p>;
|
||||||
<p>
|
|
||||||
The exchange is not audited by any auditors.
|
|
||||||
</p>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
{rci.exchangeInfo.auditors.map((a) => (
|
{rci.exchangeInfo.auditors.map(a => (
|
||||||
<div>
|
<div>
|
||||||
<h3>Auditor {a.auditor_url}</h3>
|
<h3>Auditor {a.auditor_url}</h3>
|
||||||
<p>Public key: <ExpanderText text={a.auditor_pub} /></p>
|
<p>
|
||||||
<p>Trusted: {rci.trustedAuditorPubs.indexOf(a.auditor_pub) >= 0 ? "yes" : "no"}</p>
|
Public key: <ExpanderText text={a.auditor_pub} />
|
||||||
<p>Audits {a.denomination_keys.length} of {rci.numOfferedDenoms} denominations</p>
|
</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>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
|
function FeeDetailsView(props: {
|
||||||
|
rci: ReserveCreationInfo | null;
|
||||||
|
}): JSX.Element {
|
||||||
const rci = props.rci;
|
const rci = props.rci;
|
||||||
if (!rci) {
|
if (!rci) {
|
||||||
return (
|
return (
|
||||||
@ -161,7 +176,7 @@ function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
|
|||||||
|
|
||||||
const denoms = rci.selectedDenoms;
|
const denoms = rci.selectedDenoms;
|
||||||
|
|
||||||
const countByPub: {[s: string]: number} = {};
|
const countByPub: { [s: string]: number } = {};
|
||||||
const uniq: DenominationRecord[] = [];
|
const uniq: DenominationRecord[] = [];
|
||||||
|
|
||||||
denoms.forEach((x: DenominationRecord) => {
|
denoms.forEach((x: DenominationRecord) => {
|
||||||
@ -198,7 +213,7 @@ function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>,
|
</thead>,
|
||||||
<tbody>
|
<tbody>
|
||||||
{rci!.wireFees.feesForType[s].map((f) => (
|
{rci!.wireFees.feesForType[s].map(f => (
|
||||||
<tr>
|
<tr>
|
||||||
<td>{moment.unix(f.endStamp).format("llll")}</td>
|
<td>{moment.unix(f.endStamp).format("llll")}</td>
|
||||||
<td>{renderAmount(f.wireFee)}</td>
|
<td>{renderAmount(f.wireFee)}</td>
|
||||||
@ -215,12 +230,20 @@ function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<h3>Overview</h3>
|
<h3>Overview</h3>
|
||||||
<p>Public key: <ExpanderText text={rci.exchangeInfo.masterPublicKey} /></p>
|
<p>
|
||||||
<p>{i18n.str`Withdrawal fees:`} {withdrawFee}</p>
|
Public key: <ExpanderText text={rci.exchangeInfo.masterPublicKey} />
|
||||||
<p>{i18n.str`Rounding loss:`} {overhead}</p>
|
</p>
|
||||||
<p>{i18n.str`Earliest expiration (for deposit): ${moment.unix(rci.earliestDepositExpiration).fromNow()}`}</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>
|
<h3>Coin Fees</h3>
|
||||||
<div style={{overflow: "auto"}}>
|
<div style={{ overflow: "auto" }}>
|
||||||
<table className="pure-table">
|
<table className="pure-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -231,13 +254,11 @@ function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
|
|||||||
<th>{i18n.str`Deposit Fee`}</th>
|
<th>{i18n.str`Deposit Fee`}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>{uniq.map(row)}</tbody>
|
||||||
{uniq.map(row)}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<h3>Wire Fees</h3>
|
<h3>Wire Fees</h3>
|
||||||
<div style={{overflow: "auto"}}>
|
<div style={{ overflow: "auto" }}>
|
||||||
<table className="pure-table">
|
<table className="pure-table">
|
||||||
{Object.keys(rci.wireFees.feesForType).map(wireFee)}
|
{Object.keys(rci.wireFees.feesForType).map(wireFee)}
|
||||||
</table>
|
</table>
|
||||||
@ -249,7 +270,9 @@ function FeeDetailsView(props: {rci: ReserveCreationInfo|null}): JSX.Element {
|
|||||||
/**
|
/**
|
||||||
* Shows details about a withdraw request.
|
* 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;
|
const rci = props.rci;
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -263,12 +286,10 @@ export function WithdrawDetailView(props: {rci: ReserveCreationInfo | null}): JS
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface ExpanderTextProps {
|
interface ExpanderTextProps {
|
||||||
text: string;
|
text: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Show a heading with a toggle to show/hide the expandable content.
|
* 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>;
|
return <span>{text}</span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export interface LoadingButtonProps {
|
export interface LoadingButtonProps {
|
||||||
loading: boolean;
|
loading: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function ProgressButton(
|
export function ProgressButton(
|
||||||
props:
|
props: React.PropsWithChildren<LoadingButtonProps> &
|
||||||
& React.PropsWithChildren<LoadingButtonProps>
|
React.DetailedHTMLProps<
|
||||||
& React.DetailedHTMLProps<
|
|
||||||
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
React.ButtonHTMLAttributes<HTMLButtonElement>,
|
||||||
HTMLButtonElement
|
HTMLButtonElement
|
||||||
>,
|
>,
|
||||||
@ -296,8 +314,14 @@ export function ProgressButton(
|
|||||||
type="button"
|
type="button"
|
||||||
{...props}
|
{...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}
|
{props.children}
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
@ -311,10 +335,7 @@ export function registerMountPage(mainFn: () => React.ReactElement) {
|
|||||||
if (!container) {
|
if (!container) {
|
||||||
throw Error("container not found, can't mount page contents");
|
throw Error("container not found, can't mount page contents");
|
||||||
}
|
}
|
||||||
ReactDOM.render(
|
ReactDOM.render(mainElement, container);
|
||||||
mainElement,
|
|
||||||
container,
|
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`;
|
document.body.innerText = `Fatal error: "${e.message}". Please report this bug at https://bugs.gnunet.org/.`;
|
||||||
console.error("got error", e);
|
console.error("got error", e);
|
||||||
@ -329,7 +350,11 @@ export function registerMountPage(mainFn: () => React.ReactElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function PageLink(props: React.PropsWithChildren<{pageName: string}>) {
|
export function PageLink(props: React.PropsWithChildren<{ pageName: string }>) {
|
||||||
const url = chrome.extension.getURL(`/src/webex/pages/${props.pageName}`);
|
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>
|
||||||
|
);
|
||||||
}
|
}
|
@ -71,7 +71,6 @@
|
|||||||
"src/webex/pages/add-auditor.tsx",
|
"src/webex/pages/add-auditor.tsx",
|
||||||
"src/webex/pages/auditors.tsx",
|
"src/webex/pages/auditors.tsx",
|
||||||
"src/webex/pages/benchmark.tsx",
|
"src/webex/pages/benchmark.tsx",
|
||||||
"src/webex/pages/common.ts",
|
|
||||||
"src/webex/pages/error.tsx",
|
"src/webex/pages/error.tsx",
|
||||||
"src/webex/pages/logs.tsx",
|
"src/webex/pages/logs.tsx",
|
||||||
"src/webex/pages/pay.tsx",
|
"src/webex/pages/pay.tsx",
|
||||||
|
Loading…
Reference in New Issue
Block a user