diff options
Diffstat (limited to 'packages/taler-wallet-webextension/src/wallet')
13 files changed, 538 insertions, 58 deletions
diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx index 88a84d960..7ecec1cb7 100644 --- a/packages/taler-wallet-webextension/src/wallet/Application.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -39,7 +39,7 @@ import { RefundPage } from "../cta/Refund"; import { TipPage } from "../cta/Tip"; import { WithdrawPage } from "../cta/Withdraw"; import { Pages, WalletNavBar } from "../NavigationBar"; -import { DeveloperPage } from "../popup/DeveloperPage"; +import { DeveloperPage } from "./DeveloperPage"; import { BackupPage } from "./BackupPage"; import { DepositPage } from "./DepositPage"; import { ExchangeAddPage } from "./ExchangeAddPage"; diff --git a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx index bc4b0357a..2691fbdf5 100644 --- a/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx +++ b/packages/taler-wallet-webextension/src/wallet/CreateManualWithdraw.tsx @@ -32,6 +32,8 @@ import { InputWithLabel, LightText, LinkPrimary, + SubTitle, + Title, } from "../components/styled"; import { useTranslationContext } from "../context/translation"; import { Pages } from "../NavigationBar"; @@ -167,11 +169,11 @@ export function CreateManualWithdraw({ if (initialCurrency !== undefined) { return ( <section> - <h2> + <SubTitle> <i18n.Translate> Manual Withdrawal for {initialCurrency} </i18n.Translate> - </h2> + </SubTitle> <LightText> <i18n.Translate> Choose a exchange from where the coins will be withdrawn. The @@ -200,9 +202,9 @@ export function CreateManualWithdraw({ } return ( <section> - <h2> + <SubTitle> <i18n.Translate>Manual Withdrawal</i18n.Translate> - </h2> + </SubTitle> <LightText> <i18n.Translate> Choose a exchange from where the coins will be withdrawn. The @@ -234,9 +236,9 @@ export function CreateManualWithdraw({ description={error} /> )} - <h2> + <SubTitle> <i18n.Translate>Manual Withdrawal</i18n.Translate> - </h2> + </SubTitle> <LightText> <i18n.Translate> Choose a exchange from where the coins will be withdrawn. The diff --git a/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx b/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx index df93b0c4e..65cdee4e9 100644 --- a/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/DepositPage.tsx @@ -35,6 +35,7 @@ import { ErrorText, Input, InputWithLabel, + SubTitle, WarningBox, } from "../components/styled"; import { useTranslationContext } from "../context/translation"; @@ -265,9 +266,9 @@ export function View({ return ( <Fragment> - <h2> + <SubTitle> <i18n.Translate>Send {currency} to your account</i18n.Translate> - </h2> + </SubTitle> <section> <Input> <SelectList diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx new file mode 100644 index 000000000..4dcfe2316 --- /dev/null +++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.stories.tsx @@ -0,0 +1,49 @@ +/* + This file is part of GNU Taler + (C) 2021 Taler Systems S.A. + + GNU 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. + + GNU 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 + GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> + */ + +/** + * + * @author Sebastian Javier Marchano (sebasjm) + */ + +import { PendingTaskType } from "@gnu-taler/taler-wallet-core"; +import { createExample } from "../test-utils"; +import { View as TestedComponent } from "./DeveloperPage"; + +export default { + title: "wallet/developer", + component: TestedComponent, + argTypes: { + setDeviceName: () => Promise.resolve(), + }, +}; + +export const AllOff = createExample(TestedComponent, { + onDownloadDatabase: async () => "this is the content of the database", + operations: [ + { + type: PendingTaskType.ExchangeUpdate, + exchangeBaseUrl: "http://exchange.url.", + givesLifeness: false, + lastError: undefined, + timestampDue: { + t_ms: 123123213, + }, + retryInfo: undefined, + }, + ], + coins: [], +}); diff --git a/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx new file mode 100644 index 000000000..f4d717df6 --- /dev/null +++ b/packages/taler-wallet-webextension/src/wallet/DeveloperPage.tsx @@ -0,0 +1,384 @@ +/* + This file is part of TALER + (C) 2016 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/> + */ + +import { + Amounts, + CoinDumpJson, + ExchangeListItem, + NotificationType, +} from "@gnu-taler/taler-util"; +import { PendingTaskInfo } from "@gnu-taler/taler-wallet-core"; +import { format } from "date-fns"; +import { Fragment, h, VNode } from "preact"; +import { useRef, useState } from "preact/hooks"; +import { Diagnostics } from "../components/Diagnostics"; +import { NotifyUpdateFadeOut } from "../components/styled"; +import { Time } from "../components/Time"; +import { useTranslationContext } from "../context/translation"; +import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; +import { useDiagnostics } from "../hooks/useDiagnostics"; +import * as wxApi from "../wxApi"; + +export function DeveloperPage(): VNode { + const [status, timedOut] = useDiagnostics(); + + const listenAllEvents = Array.from<NotificationType>({ length: 1 }); + listenAllEvents.includes = () => true; // includes every event + + const response = useAsyncAsHook(async () => { + const op = await wxApi.getPendingOperations(); + const c = await wxApi.dumpCoins(); + const ex = await wxApi.listExchanges(); + return { + operations: op.pendingOperations, + coins: c.coins, + exchanges: ex.exchanges, + }; + }, listenAllEvents); + + const nonResponse = { operations: [], coins: [], exchanges: [] }; + const { operations, coins, exchanges } = + response === undefined + ? nonResponse + : response.hasError + ? nonResponse + : response.response; + + const balanceResponse = useAsyncAsHook(wxApi.getBalance); + + return ( + <View + status={status} + timedOut={timedOut} + operations={operations} + coins={coins} + exchanges={exchanges} + onDownloadDatabase={async () => { + const db = await wxApi.exportDB(); + return JSON.stringify(db); + }} + /> + ); +} + +type CoinsInfo = CoinDumpJson["coins"]; +type CalculatedCoinfInfo = { + denom_value: number; + remain_value: number; + status: string; + from_refresh: boolean; + id: string; +}; + +type SplitedCoinInfo = { + spent: CalculatedCoinfInfo[]; + usable: CalculatedCoinfInfo[]; +}; + +export interface Props { + status: any; + timedOut: boolean; + operations: PendingTaskInfo[]; + coins: CoinsInfo; + exchanges: ExchangeListItem[]; + onDownloadDatabase: () => Promise<string>; +} + +function hashObjectId(o: any): string { + return JSON.stringify(o); +} + +export function View({ + status, + timedOut, + operations, + coins, + onDownloadDatabase, +}: Props): VNode { + const { i18n } = useTranslationContext(); + const [downloadedDatabase, setDownloadedDatabase] = useState< + { time: Date; content: string } | undefined + >(undefined); + async function onExportDatabase(): Promise<void> { + const content = await onDownloadDatabase(); + setDownloadedDatabase({ + time: new Date(), + content, + }); + } + const fileRef = useRef<HTMLInputElement>(null); + async function onImportDatabase(str: string): Promise<void> { + return wxApi.importDB(JSON.parse(str)); + } + const currencies: { [ex: string]: string } = {}; + const money_by_exchange = coins.reduce( + (prev, cur) => { + const denom = Amounts.parseOrThrow(cur.denom_value); + if (!prev[cur.exchange_base_url]) { + prev[cur.exchange_base_url] = []; + currencies[cur.exchange_base_url] = denom.currency; + } + prev[cur.exchange_base_url].push({ + denom_value: parseFloat(Amounts.stringifyValue(denom)), + remain_value: parseFloat( + Amounts.stringifyValue(Amounts.parseOrThrow(cur.remaining_value)), + ), + status: cur.coin_suspended ? "suspended" : "ok", + from_refresh: cur.refresh_parent_coin_pub !== undefined, + id: cur.coin_pub, + }); + return prev; + }, + {} as { + [exchange_name: string]: CalculatedCoinfInfo[]; + }, + ); + + return ( + <div> + <p> + <i18n.Translate>Debug tools</i18n.Translate>: + </p> + <button + onClick={() => + confirmReset( + i18n.str`Do you want to IRREVOCABLY DESTROY everything inside your wallet and LOSE ALL YOUR COINS?`, + ) + } + > + <i18n.Translate>reset</i18n.Translate> + </button> + <br /> + <button onClick={() => fileRef?.current?.click()}> + <i18n.Translate>import database</i18n.Translate> + </button> + <input + ref={fileRef} + style={{ display: "none" }} + type="file" + onChange={async (e) => { + const f: FileList | null = e.currentTarget.files; + if (!f || f.length != 1) { + return Promise.reject(); + } + const buf = await f[0].arrayBuffer(); + const str = new Uint8Array(buf).reduce( + (data, byte) => data + String.fromCharCode(byte), + "", + ); + return onImportDatabase(str); + }} + /> + <br /> + <button onClick={onExportDatabase}> + <i18n.Translate>export database</i18n.Translate> + </button> + {downloadedDatabase && ( + <div> + <i18n.Translate> + Database exported at + <Time + timestamp={{ t_ms: downloadedDatabase.time.getTime() }} + format="yyyy/MM/dd HH:mm:ss" + /> + <a + href={`data:text/plain;charset=utf-8;base64,${toBase64( + downloadedDatabase.content, + )}`} + download={`taler-wallet-database-${format( + downloadedDatabase.time, + "yyyy/MM/dd_HH:mm", + )}.json`} + > + <i18n.Translate>click here</i18n.Translate> + </a> + to download + </i18n.Translate> + </div> + )} + <br /> + <p> + <i18n.Translate>Coins</i18n.Translate>: + </p> + {Object.keys(money_by_exchange).map((ex) => { + const allcoins = money_by_exchange[ex]; + allcoins.sort((a, b) => { + return b.denom_value - a.denom_value; + }); + + const coins = allcoins.reduce( + (prev, cur) => { + if (cur.remain_value > 0) prev.usable.push(cur); + if (cur.remain_value === 0) prev.spent.push(cur); + return prev; + }, + { + spent: [], + usable: [], + } as SplitedCoinInfo, + ); + + return <ShowAllCoins coins={coins} ex={ex} currencies={currencies} />; + })} + <br /> + <Diagnostics diagnostics={status} timedOut={timedOut} /> + {operations && operations.length > 0 && ( + <Fragment> + <p> + <i18n.Translate>Pending operations</i18n.Translate> + </p> + <dl> + {operations.reverse().map((o) => { + return ( + <NotifyUpdateFadeOut key={hashObjectId(o)}> + <dt> + {o.type}{" "} + <Time + timestamp={o.timestampDue} + format="yy/MM/dd hh:mm:ss" + /> + </dt> + <dd> + <pre>{JSON.stringify(o, undefined, 2)}</pre> + </dd> + </NotifyUpdateFadeOut> + ); + })} + </dl> + </Fragment> + )} + </div> + ); +} + +function ShowAllCoins({ + ex, + coins, + currencies, +}: { + ex: string; + coins: SplitedCoinInfo; + currencies: { [ex: string]: string }; +}) { + const { i18n } = useTranslationContext(); + const [collapsedSpent, setCollapsedSpent] = useState(true); + const [collapsedUnspent, setCollapsedUnspent] = useState(false); + const total = coins.usable.reduce((prev, cur) => prev + cur.denom_value, 0); + return ( + <Fragment> + <p> + <b>{ex}</b>: {total} {currencies[ex]} + </p> + <p> + <b> + <i18n.Translate>usable coins</i18n.Translate> + </b> + </p> + {collapsedUnspent ? ( + <div onClick={() => setCollapsedUnspent(false)}>click to show</div> + ) : ( + <table onClick={() => setCollapsedUnspent(true)}> + <tr> + <td> + <i18n.Translate>id</i18n.Translate> + </td> + <td> + <i18n.Translate>denom</i18n.Translate> + </td> + <td> + <i18n.Translate>value</i18n.Translate> + </td> + <td> + <i18n.Translate>status</i18n.Translate> + </td> + <td> + <i18n.Translate>from refresh?</i18n.Translate> + </td> + </tr> + {coins.usable.map((c) => { + return ( + <tr> + <td>{c.id.substring(0, 5)}</td> + <td>{c.denom_value}</td> + <td>{c.remain_value}</td> + <td>{c.status}</td> + <td>{c.from_refresh ? "true" : "false"}</td> + </tr> + ); + })} + </table> + )} + <p> + <i18n.Translate>spent coins</i18n.Translate> + </p> + {collapsedSpent ? ( + <div onClick={() => setCollapsedSpent(false)}> + <i18n.Translate>click to show</i18n.Translate> + </div> + ) : ( + <table onClick={() => setCollapsedSpent(true)}> + <tr> + <td> + <i18n.Translate>id</i18n.Translate> + </td> + <td> + <i18n.Translate>denom</i18n.Translate> + </td> + <td> + <i18n.Translate>value</i18n.Translate> + </td> + <td> + <i18n.Translate>status</i18n.Translate> + </td> + <td> + <i18n.Translate>from refresh?</i18n.Translate> + </td> + </tr> + {coins.spent.map((c) => { + return ( + <tr> + <td>{c.id.substring(0, 5)}</td> + <td>{c.denom_value}</td> + <td>{c.remain_value}</td> + <td>{c.status}</td> + <td>{c.from_refresh ? "true" : "false"}</td> + </tr> + ); + })} + </table> + )} + </Fragment> + ); +} + +function toBase64(str: string): string { + return btoa( + encodeURIComponent(str).replace(/%([0-9A-F]{2})/g, function (match, p1) { + return String.fromCharCode(parseInt(p1, 16)); + }), + ); +} + +function runIntegrationTest() {} + +export async function confirmReset( + confirmTheResetMessage: string, +): Promise<void> { + if (confirm(confirmTheResetMessage)) { + await wxApi.resetDb(); + window.close(); + } +} diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx index 1b40fe78e..e36fa112f 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeAddConfirm.tsx @@ -1,6 +1,11 @@ import { Fragment, h, VNode } from "preact"; import { useState } from "preact/hooks"; -import { Button, ButtonSuccess, ButtonWarning } from "../components/styled"; +import { + Button, + ButtonSuccess, + ButtonWarning, + Title, +} from "../components/styled"; import { useTranslationContext } from "../context/translation"; import { TermsOfServiceSection } from "../cta/TermsOfServiceSection"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook"; @@ -85,9 +90,9 @@ export function View({ return ( <Fragment> <section> - <h1> + <Title> <i18n.Translate>Review terms of service</i18n.Translate> - </h1> + </Title> <div> <i18n.Translate>Exchange URL</i18n.Translate>: <a href={url} target="_blank" rel="noreferrer"> diff --git a/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx b/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx index fae309ba7..6b8a6194d 100644 --- a/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ExchangeSetUrl.tsx @@ -10,6 +10,8 @@ import { ButtonPrimary, Input, LightText, + SubTitle, + Title, WarningBox, } from "../components/styled"; import { useTranslationContext } from "../context/translation"; @@ -92,13 +94,13 @@ export function ExchangeSetUrlPage({ <Fragment> <section> {!expectedCurrency ? ( - <h1> + <Title> <i18n.Translate>Add new exchange</i18n.Translate> - </h1> + </Title> ) : ( - <h2> + <SubTitle> <i18n.Translate>Add exchange for {expectedCurrency}</i18n.Translate> - </h2> + </SubTitle> )} {!result && ( <LightText> diff --git a/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx b/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx index 136521e6b..ae4ba7e1e 100644 --- a/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ProviderAddPage.tsx @@ -30,6 +30,8 @@ import { Input, LightText, SmallLightText, + SubTitle, + Title, } from "../components/styled"; import { useTranslationContext } from "../context/translation"; import { queryToSlashConfig } from "../utils/index"; @@ -115,9 +117,9 @@ export function SetUrlView({ return ( <Fragment> <section> - <h1> + <Title> <i18n.Translate>Add backup provider</i18n.Translate> - </h1> + </Title> {error && ( <ErrorMessage title={ @@ -196,9 +198,9 @@ export function ConfirmProviderView({ return ( <Fragment> <section> - <h1> + <Title> <i18n.Translate>Review terms of service</i18n.Translate> - </h1> + </Title> <div> <i18n.Translate>Provider URL</i18n.Translate>:{" "} <a href={url} target="_blank"> @@ -210,9 +212,9 @@ export function ConfirmProviderView({ Please review and accept this provider's terms of service </i18n.Translate> </SmallLightText> - <h2> + <SubTitle> 1. <i18n.Translate>Pricing</i18n.Translate> - </h2> + </SubTitle> <p> {Amounts.isZero(provider.annual_fee) ? ( <i18n.Translate>free of charge</i18n.Translate> @@ -222,9 +224,9 @@ export function ConfirmProviderView({ </i18n.Translate> )} </p> - <h2> + <SubTitle> 2. <i18n.Translate>Storage</i18n.Translate> - </h2> + </SubTitle> <p> <i18n.Translate> {provider.storage_limit_in_megabytes} megabytes of storage per year diff --git a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx index 84a2a7441..83ebfb51a 100644 --- a/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx +++ b/packages/taler-wallet-webextension/src/wallet/ReserveCreated.tsx @@ -9,7 +9,7 @@ import { import { Fragment, h, VNode } from "preact"; import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType"; import { QR } from "../components/QR"; -import { ButtonDestructive, WarningBox } from "../components/styled"; +import { ButtonDestructive, Title, WarningBox } from "../components/styled"; import { useTranslationContext } from "../context/translation"; import { amountToString } from "../utils/index"; export interface Props { @@ -115,9 +115,9 @@ export function ReserveCreated({ return ( <Fragment> <section> - <h1> + <Title> <i18n.Translate>Exchange is ready for withdrawal</i18n.Translate> - </h1> + </Title> <p> <i18n.Translate> To complete the process you need to wire{` `} diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx index 840e95651..478ce00a8 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx @@ -23,6 +23,7 @@ import { DestructiveText, Input, LinkPrimary, + SubTitle, SuccessText, WarningText, } from "../components/styled"; @@ -86,9 +87,9 @@ export function SettingsView({ return ( <Fragment> <section> - <h2> + <SubTitle> <i18n.Translate>Navigator</i18n.Translate> - </h2> + </SubTitle> <Checkbox label={ <i18n.Translate> @@ -106,9 +107,9 @@ export function SettingsView({ onToggle={togglePermissions} /> - <h2> + <SubTitle> <i18n.Translate>Trust</i18n.Translate> - </h2> + </SubTitle> {!knownExchanges || !knownExchanges.length ? ( <div> <i18n.Translate>No exchange yet</i18n.Translate> @@ -184,7 +185,7 @@ export function SettingsView({ </LinkPrimary> </div> - <h2>Troubleshooting</h2> + <SubTitle>Troubleshooting</SubTitle> <Checkbox label={<i18n.Translate>Developer mode</i18n.Translate>} name="devMode" @@ -198,9 +199,9 @@ export function SettingsView({ /> <JustInDevMode> - <h2> + <SubTitle> <i18n.Translate>Display</i18n.Translate> - </h2> + </SubTitle> <Input> <SelectList label={<i18n.Translate>Current Language</i18n.Translate>} diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx index 0e58aaf61..5cef86da8 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx @@ -43,6 +43,7 @@ import { Overlay, RowBorderGray, SmallLightText, + SubTitle, WarningBox, } from "../components/styled"; import { Time } from "../components/Time"; @@ -216,10 +217,13 @@ export function TransactionView({ </CenteredDialog> </Overlay> ) : undefined} - <h2> + <SubTitle> <i18n.Translate>Withdrawal</i18n.Translate> - </h2> - <Time timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} format="dd MMMM yyyy, HH:mm" /> + </SubTitle> + <Time + timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} + format="dd MMMM yyyy, HH:mm" + /> {transaction.pending ? ( transaction.withdrawalDetails.type === WithdrawalType.ManualTransfer ? ( @@ -340,10 +344,13 @@ export function TransactionView({ return ( <TransactionTemplate> - <h2> + <SubTitle> <i18n.Translate>Payment</i18n.Translate> - </h2> - <Time timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} format="dd MMMM yyyy, HH:mm" /> + </SubTitle> + <Time + timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} + format="dd MMMM yyyy, HH:mm" + /> <br /> <Part big @@ -423,10 +430,13 @@ export function TransactionView({ ).amount; return ( <TransactionTemplate> - <h2> + <SubTitle> <i18n.Translate>Deposit</i18n.Translate> - </h2> - <Time timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} format="dd MMMM yyyy, HH:mm" /> + </SubTitle> + <Time + timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} + format="dd MMMM yyyy, HH:mm" + /> <br /> <Part big @@ -457,10 +467,13 @@ export function TransactionView({ ).amount; return ( <TransactionTemplate> - <h2> + <SubTitle> <i18n.Translate>Refresh</i18n.Translate> - </h2> - <Time timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} format="dd MMMM yyyy, HH:mm" /> + </SubTitle> + <Time + timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} + format="dd MMMM yyyy, HH:mm" + /> <br /> <Part big @@ -491,10 +504,13 @@ export function TransactionView({ ).amount; return ( <TransactionTemplate> - <h2> + <SubTitle> <i18n.Translate>Tip</i18n.Translate> - </h2> - <Time timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} format="dd MMMM yyyy, HH:mm" /> + </SubTitle> + <Time + timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} + format="dd MMMM yyyy, HH:mm" + /> <br /> <Part big @@ -525,9 +541,9 @@ export function TransactionView({ ).amount; return ( <TransactionTemplate> - <h2> + <SubTitle> <i18n.Translate>Refund</i18n.Translate> - </h2> + </SubTitle> <Time timestamp={AbsoluteTime.fromTimestamp(transaction.timestamp)} format="dd MMMM yyyy, HH:mm" diff --git a/packages/taler-wallet-webextension/src/wallet/Welcome.tsx b/packages/taler-wallet-webextension/src/wallet/Welcome.tsx index 36b4b13fc..1c068cfa3 100644 --- a/packages/taler-wallet-webextension/src/wallet/Welcome.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Welcome.tsx @@ -24,6 +24,7 @@ import { WalletDiagnostics } from "@gnu-taler/taler-util"; import { Fragment, h, VNode } from "preact"; import { Checkbox } from "../components/Checkbox"; import { Diagnostics } from "../components/Diagnostics"; +import { SubTitle, Title } from "../components/styled"; import { useTranslationContext } from "../context/translation"; import { useDiagnostics } from "../hooks/useDiagnostics"; import { useExtendedPermissions } from "../hooks/useExtendedPermissions"; @@ -56,16 +57,16 @@ export function View({ const { i18n } = useTranslationContext(); return ( <Fragment> - <h1> + <Title> <i18n.Translate>Browser Extension Installed!</i18n.Translate> - </h1> + </Title> <div> <p> <i18n.Translate>Thank you for installing the wallet.</i18n.Translate> </p> - <h2> + <SubTitle> <i18n.Translate>Permissions</i18n.Translate> - </h2> + </SubTitle> <Checkbox label={ <i18n.Translate> @@ -82,9 +83,9 @@ export function View({ enabled={permissionsEnabled} onToggle={togglePermissions} /> - <h2> + <SubTitle> <i18n.Translate>Next Steps</i18n.Translate> - </h2> + </SubTitle> <a href="https://demo.taler.net/" style={{ display: "block" }}> <i18n.Translate>Try the demo</i18n.Translate> ยป </a> diff --git a/packages/taler-wallet-webextension/src/wallet/index.stories.tsx b/packages/taler-wallet-webextension/src/wallet/index.stories.tsx index 1e19445f8..b03177825 100644 --- a/packages/taler-wallet-webextension/src/wallet/index.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/index.stories.tsx @@ -33,5 +33,22 @@ import * as a12 from "./Settings.stories"; import * as a13 from "./Transaction.stories"; import * as a14 from "./Welcome.stories"; import * as a15 from "./AddNewActionView.stories"; +import * as a16 from "./DeveloperPage.stories"; -export default [a1, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12, a13, a14, a15]; +export default [ + a1, + a3, + a4, + a5, + a6, + a7, + a8, + a9, + a10, + a11, + a12, + a13, + a14, + a15, + a16, +]; |