we are force to use i18n.Translate, otherwise pogen won't find the tag

This commit is contained in:
Sebastian 2022-02-23 15:44:14 -03:00
parent 8e01ea5433
commit 8c3e572934
No known key found for this signature in database
GPG Key ID: BE4FF68352439FC1
37 changed files with 496 additions and 424 deletions

View File

@ -67,10 +67,10 @@ export function PopupNavBar({ path = "" }: { path?: string }): VNode {
return ( return (
<NavigationHeader> <NavigationHeader>
<a href="/balance" class={path.startsWith("/balance") ? "active" : ""}> <a href="/balance" class={path.startsWith("/balance") ? "active" : ""}>
<Translate>Balance</Translate> <i18n.Translate>Balance</i18n.Translate>
</a> </a>
<a href="/backup" class={path.startsWith("/backup") ? "active" : ""}> <a href="/backup" class={path.startsWith("/backup") ? "active" : ""}>
<Translate>Backup</Translate> <i18n.Translate>Backup</i18n.Translate>
</a> </a>
<a /> <a />
<a href={innerUrl} target="_blank" rel="noreferrer"> <a href={innerUrl} target="_blank" rel="noreferrer">
@ -85,15 +85,15 @@ export function WalletNavBar({ path = "" }: { path?: string }): VNode {
<NavigationHeaderHolder> <NavigationHeaderHolder>
<NavigationHeader> <NavigationHeader>
<a href="/balance" class={path.startsWith("/balance") ? "active" : ""}> <a href="/balance" class={path.startsWith("/balance") ? "active" : ""}>
<Translate>Balance</Translate> <i18n.Translate>Balance</i18n.Translate>
</a> </a>
<a href="/backup" class={path.startsWith("/backup") ? "active" : ""}> <a href="/backup" class={path.startsWith("/backup") ? "active" : ""}>
<Translate>Backup</Translate> <i18n.Translate>Backup</i18n.Translate>
</a> </a>
<JustInDevMode> <JustInDevMode>
<a href="/dev" class={path.startsWith("/dev") ? "active" : ""}> <a href="/dev" class={path.startsWith("/dev") ? "active" : ""}>
<Translate>Dev</Translate> <i18n.Translate>Dev</i18n.Translate>
</a> </a>
</JustInDevMode> </JustInDevMode>
@ -102,7 +102,7 @@ export function WalletNavBar({ path = "" }: { path?: string }): VNode {
href="/settings" href="/settings"
class={path.startsWith("/settings") ? "active" : ""} class={path.startsWith("/settings") ? "active" : ""}
> >
<Translate>Settings</Translate> <i18n.Translate>Settings</i18n.Translate>
</a> </a>
</NavigationHeader> </NavigationHeader>
</NavigationHeaderHolder> </NavigationHeaderHolder>

View File

@ -14,7 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { PaytoUri, Translate } from "@gnu-taler/taler-util"; import { PaytoUri, i18n } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { CopiedIcon, CopyIcon } from "../svg"; import { CopiedIcon, CopyIcon } from "../svg";
@ -34,23 +34,42 @@ export function BankDetailsByPaytoType({
amount, amount,
}: BankDetailsProps): VNode { }: BankDetailsProps): VNode {
const firstPart = !payto ? undefined : !payto.isKnown ? ( const firstPart = !payto ? undefined : !payto.isKnown ? (
<Row name={<Translate>Account</Translate>} value={payto.targetPath} /> <Row
name={<i18n.Translate>Account</i18n.Translate>}
value={payto.targetPath}
/>
) : payto.targetType === "x-taler-bank" ? ( ) : payto.targetType === "x-taler-bank" ? (
<Fragment> <Fragment>
<Row name={<Translate>Bank host</Translate>} value={payto.host} /> <Row
<Row name={<Translate>Bank account</Translate>} value={payto.account} /> name={<i18n.Translate>Bank host</i18n.Translate>}
value={payto.host}
/>
<Row
name={<i18n.Translate>Bank account</i18n.Translate>}
value={payto.account}
/>
</Fragment> </Fragment>
) : payto.targetType === "iban" ? ( ) : payto.targetType === "iban" ? (
<Row name={<Translate>IBAN</Translate>} value={payto.iban} /> <Row name={<i18n.Translate>IBAN</i18n.Translate>} value={payto.iban} />
) : undefined; ) : undefined;
return ( return (
<div style={{ textAlign: "left" }}> <div style={{ textAlign: "left" }}>
<p>Bank transfer details</p> <p>Bank transfer details</p>
<table> <table>
{firstPart} {firstPart}
<Row name={<Translate>Exchange</Translate>} value={exchangeBaseUrl} /> <Row
<Row name={<Translate>Chosen amount</Translate>} value={amount} /> name={<i18n.Translate>Exchange</i18n.Translate>}
<Row name={<Translate>Subject</Translate>} value={subject} literal /> value={exchangeBaseUrl}
/>
<Row
name={<i18n.Translate>Chosen amount</i18n.Translate>}
value={amount}
/>
<Row
name={<i18n.Translate>Subject</i18n.Translate>}
value={subject}
literal
/>
</table> </table>
</div> </div>
); );

View File

@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { Translate } from "@gnu-taler/taler-util"; import { i18n } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
export function DebugCheckbox({ export function DebugCheckbox({
@ -37,7 +37,9 @@ export function DebugCheckbox({
htmlFor="checkbox-perm" htmlFor="checkbox-perm"
style={{ marginLeft: "0.5em", fontWeight: "bold" }} style={{ marginLeft: "0.5em", fontWeight: "bold" }}
> >
<Translate>Automatically open wallet based on page content</Translate> <i18n.Translate>
Automatically open wallet based on page content
</i18n.Translate>
</label> </label>
<span <span
style={{ style={{
@ -48,10 +50,10 @@ export function DebugCheckbox({
}} }}
> >
( (
<Translate> <i18n.Translate>
Enabling this option below will make using the wallet faster, but Enabling this option below will make using the wallet faster, but
requires more permissions from your browser. requires more permissions from your browser.
</Translate> </i18n.Translate>
) )
</span> </span>
</div> </div>

View File

@ -14,7 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { Translate, WalletDiagnostics } from "@gnu-taler/taler-util"; import { i18n, WalletDiagnostics } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { PageLink } from "../renderHtml"; import { PageLink } from "../renderHtml";
@ -27,9 +27,9 @@ export function Diagnostics({ timedOut, diagnostics }: Props): VNode {
if (timedOut) { if (timedOut) {
return ( return (
<p> <p>
<Translate> <i18n.Translate>
Diagnostics timed out. Could not talk to the wallet backend. Diagnostics timed out. Could not talk to the wallet backend.
</Translate> </i18n.Translate>
</p> </p>
); );
} }
@ -48,7 +48,7 @@ export function Diagnostics({ timedOut, diagnostics }: Props): VNode {
}} }}
> >
<p> <p>
<Translate>Problems detected:</Translate> <i18n.Translate>Problems detected:</i18n.Translate>
</p> </p>
<ol> <ol>
{diagnostics.errors.map((errMsg) => ( {diagnostics.errors.map((errMsg) => (
@ -57,23 +57,23 @@ export function Diagnostics({ timedOut, diagnostics }: Props): VNode {
</ol> </ol>
{diagnostics.firefoxIdbProblem ? ( {diagnostics.firefoxIdbProblem ? (
<p> <p>
<Translate> <i18n.Translate>
Please check in your <code>about:config</code> settings that you Please check in your <code>about:config</code> settings that you
have IndexedDB enabled (check the preference name{" "} have IndexedDB enabled (check the preference name{" "}
<code>dom.indexedDB.enabled</code>). <code>dom.indexedDB.enabled</code>).
</Translate> </i18n.Translate>
</p> </p>
) : null} ) : null}
{diagnostics.dbOutdated ? ( {diagnostics.dbOutdated ? (
<p> <p>
<Translate> <i18n.Translate>
Your wallet database is outdated. Currently automatic migration is Your wallet database is outdated. Currently automatic migration is
not supported. Please go{" "} not supported. Please go{" "}
<PageLink pageName="/reset-required"> <PageLink pageName="/reset-required">
<Translate>here</Translate> <i18n.Translate>here</i18n.Translate>
</PageLink>{" "} </PageLink>{" "}
to reset the wallet database. to reset the wallet database.
</Translate> </i18n.Translate>
</p> </p>
) : null} ) : null}
</div> </div>
@ -82,7 +82,7 @@ export function Diagnostics({ timedOut, diagnostics }: Props): VNode {
return ( return (
<p> <p>
<Translate>Running diagnostics</Translate> ... <i18n.Translate>Running diagnostics</i18n.Translate> ...
</p> </p>
); );
} }

View File

@ -14,7 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { Translate } from "@gnu-taler/taler-util"; import { i18n } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
import { useRef, useState } from "preact/hooks"; import { useRef, useState } from "preact/hooks";
@ -41,7 +41,7 @@ export function EditableText({
<div style={{ display: "flex", justifyContent: "space-between" }}> <div style={{ display: "flex", justifyContent: "space-between" }}>
<p>{value}</p> <p>{value}</p>
<button onClick={() => setEditing(true)}> <button onClick={() => setEditing(true)}>
<Translate>Edit</Translate> <i18n.Translate>Edit</i18n.Translate>
</button> </button>
</div> </div>
); );
@ -57,7 +57,7 @@ export function EditableText({
onChange(ref.current.value).then(() => setEditing(false)); onChange(ref.current.value).then(() => setEditing(false));
}} }}
> >
<Translate>Confirm</Translate> <i18n.Translate>Confirm</i18n.Translate>
</button> </button>
</div> </div>
); );

View File

@ -13,13 +13,13 @@
You should have received a copy of the GNU General Public License along with 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/> TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { Translate } from "@gnu-taler/taler-util"; import { i18n } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
export function Loading(): VNode { export function Loading(): VNode {
return ( return (
<div> <div>
<Translate>Loading</Translate>... <i18n.Translate>Loading</i18n.Translate>...
</div> </div>
); );
} }

View File

@ -14,7 +14,7 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/> GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { Translate } from "@gnu-taler/taler-util"; import { i18n } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { NiceSelect } from "./styled"; import { NiceSelect } from "./styled";
@ -59,7 +59,7 @@ export function SelectList({
{value === undefined || {value === undefined ||
(canBeNull && ( (canBeNull && (
<option selected disabled> <option selected disabled>
<Translate>Select one option</Translate> <i18n.Translate>Select one option</i18n.Translate>
</option> </option>
// ) : ( // ) : (
// <option selected>{list[value]}</option> // <option selected>{list[value]}</option>

View File

@ -21,7 +21,7 @@ import {
Timestamp, Timestamp,
Transaction, Transaction,
TransactionType, TransactionType,
Translate, i18n,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
import imageBank from "../../static/img/ri-bank-line.svg"; import imageBank from "../../static/img/ri-bank-line.svg";
@ -134,7 +134,7 @@ function TransactionLayout(props: TransactionLayoutProps): VNode {
</LargeText> </LargeText>
{props.pending && ( {props.pending && (
<LightText style={{ marginTop: 5, marginBottom: 5 }}> <LightText style={{ marginTop: 5, marginBottom: 5 }}>
<Translate>Waiting for confirmation</Translate> <i18n.Translate>Waiting for confirmation</i18n.Translate>
</LightText> </LightText>
)} )}
<SmallLightText style={{ marginTop: 5 }}> <SmallLightText style={{ marginTop: 5 }}>
@ -198,7 +198,7 @@ function TransactionAmount(props: TransactionAmountProps): VNode {
</ExtraLargeText> </ExtraLargeText>
{props.pending && ( {props.pending && (
<div> <div>
<Translate>PENDING</Translate> <i18n.Translate>PENDING</i18n.Translate>
</div> </div>
)} )}
</Column> </Column>

View File

@ -111,7 +111,7 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
if (!talerPayUri) { if (!talerPayUri) {
return ( return (
<span> <span>
<Translate>missing pay uri</Translate> <i18n.Translate>missing pay uri</i18n.Translate>
</span> </span>
); );
} }
@ -122,14 +122,14 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
<WalletAction> <WalletAction>
<LogoHeader /> <LogoHeader />
<h2> <h2>
<Translate>Digital cash payment</Translate> <i18n.Translate>Digital cash payment</i18n.Translate>
</h2> </h2>
<section> <section>
<ErrorTalerOperation <ErrorTalerOperation
title={ title={
<Translate> <i18n.Translate>
Could not get the payment information for this order Could not get the payment information for this order
</Translate> </i18n.Translate>
} }
error={payErrMsg?.operationError} error={payErrMsg?.operationError}
/> />
@ -142,13 +142,13 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
<WalletAction> <WalletAction>
<LogoHeader /> <LogoHeader />
<h2> <h2>
<Translate>Digital cash payment</Translate> <i18n.Translate>Digital cash payment</i18n.Translate>
</h2> </h2>
<section> <section>
<p> <p>
<Translate> <i18n.Translate>
Could not get the payment information for this order Could not get the payment information for this order
</Translate> </i18n.Translate>
</p> </p>
<ErrorBox>{payErrMsg}</ErrorBox> <ErrorBox>{payErrMsg}</ErrorBox>
</section> </section>
@ -157,7 +157,7 @@ export function DepositPage({ talerPayUri, goBack }: Props): VNode {
} }
return ( return (
<span> <span>
<Translate>Loading payment information</Translate> ... <i18n.Translate>Loading payment information</i18n.Translate> ...
</span> </span>
); );
} }
@ -205,28 +205,28 @@ export function PaymentRequestView({
<LogoHeader /> <LogoHeader />
<h2> <h2>
<Translate>Digital cash deposit</Translate> <i18n.Translate>Digital cash deposit</i18n.Translate>
</h2> </h2>
{payStatus.status === PreparePayResultType.AlreadyConfirmed && {payStatus.status === PreparePayResultType.AlreadyConfirmed &&
(payStatus.paid ? ( (payStatus.paid ? (
<SuccessBox> <SuccessBox>
<Translate>Already paid</Translate> <i18n.Translate>Already paid</i18n.Translate>
</SuccessBox> </SuccessBox>
) : ( ) : (
<WarningBox> <WarningBox>
<Translate>Already claimed</Translate> <i18n.Translate>Already claimed</i18n.Translate>
</WarningBox> </WarningBox>
))} ))}
{payResult && payResult.type === ConfirmPayResultType.Done && ( {payResult && payResult.type === ConfirmPayResultType.Done && (
<SuccessBox> <SuccessBox>
<h3> <h3>
<Translate>Payment complete</Translate> <i18n.Translate>Payment complete</i18n.Translate>
</h3> </h3>
<p> <p>
{!payResult.contractTerms.fulfillment_message ? ( {!payResult.contractTerms.fulfillment_message ? (
<Translate> <i18n.Translate>
You will now be sent back to the merchant you came from. You will now be sent back to the merchant you came from.
</Translate> </i18n.Translate>
) : ( ) : (
payResult.contractTerms.fulfillment_message payResult.contractTerms.fulfillment_message
)} )}
@ -238,7 +238,7 @@ export function PaymentRequestView({
Amounts.isNonZero(totalFees) && ( Amounts.isNonZero(totalFees) && (
<Part <Part
big big
title={<Translate>Total to pay</Translate>} title={<i18n.Translate>Total to pay</i18n.Translate>}
text={amountToPretty( text={amountToPretty(
Amounts.parseOrThrow(payStatus.amountEffective), Amounts.parseOrThrow(payStatus.amountEffective),
)} )}
@ -247,7 +247,7 @@ export function PaymentRequestView({
)} )}
<Part <Part
big big
title={<Translate>Purchase amount</Translate>} title={<i18n.Translate>Purchase amount</i18n.Translate>}
text={amountToPretty(Amounts.parseOrThrow(payStatus.amountRaw))} text={amountToPretty(Amounts.parseOrThrow(payStatus.amountRaw))}
kind="neutral" kind="neutral"
/> />
@ -255,25 +255,25 @@ export function PaymentRequestView({
<Fragment> <Fragment>
<Part <Part
big big
title={<Translate>Fee</Translate>} title={<i18n.Translate>Fee</i18n.Translate>}
text={amountToPretty(totalFees)} text={amountToPretty(totalFees)}
kind="negative" kind="negative"
/> />
</Fragment> </Fragment>
)} )}
<Part <Part
title={<Translate>Merchant</Translate>} title={<i18n.Translate>Merchant</i18n.Translate>}
text={contractTerms.merchant.name} text={contractTerms.merchant.name}
kind="neutral" kind="neutral"
/> />
<Part <Part
title={<Translate>Purchase</Translate>} title={<i18n.Translate>Purchase</i18n.Translate>}
text={contractTerms.summary} text={contractTerms.summary}
kind="neutral" kind="neutral"
/> />
{contractTerms.order_id && ( {contractTerms.order_id && (
<Part <Part
title={<Translate>Receipt</Translate>} title={<i18n.Translate>Receipt</i18n.Translate>}
text={`#${contractTerms.order_id}`} text={`#${contractTerms.order_id}`}
kind="neutral" kind="neutral"
/> />

View File

@ -110,7 +110,7 @@ export function PayPage({
if (hook.hasError) { if (hook.hasError) {
return ( return (
<LoadingError <LoadingError
title={<Translate>Could not load pay status</Translate>} title={<i18n.Translate>Could not load pay status</i18n.Translate>}
error={hook} error={hook}
/> />
); );
@ -187,9 +187,9 @@ export function PaymentRequestView({
return ( return (
<ErrorMessage <ErrorMessage
title={ title={
<Translate> <i18n.Translate>
Could not load contract terms from merchant or wallet backend. Could not load contract terms from merchant or wallet backend.
</Translate> </i18n.Translate>
} }
/> />
); );
@ -214,20 +214,20 @@ export function PaymentRequestView({
<section> <section>
<LinkSuccess upperCased onClick={() => setShowQR((qr) => !qr)}> <LinkSuccess upperCased onClick={() => setShowQR((qr) => !qr)}>
{!showQR ? ( {!showQR ? (
<Translate>Pay with a mobile phone</Translate> <i18n.Translate>Pay with a mobile phone</i18n.Translate>
) : ( ) : (
<Translate>Hide QR</Translate> <i18n.Translate>Hide QR</i18n.Translate>
)} )}
</LinkSuccess> </LinkSuccess>
{showQR && ( {showQR && (
<div> <div>
<QR text={privateUri} /> <QR text={privateUri} />
<Translate> <i18n.Translate>
Scan the QR code or Scan the QR code or
<a href={privateUri}> <a href={privateUri}>
<Translate>click here</Translate> <i18n.Translate>click here</i18n.Translate>
</a> </a>
</Translate> </i18n.Translate>
</div> </div>
)} )}
</section> </section>
@ -241,7 +241,7 @@ export function PaymentRequestView({
<section> <section>
<div> <div>
<p> <p>
<Translate>Processing</Translate>... <i18n.Translate>Processing</i18n.Translate>...
</p> </p>
</div> </div>
</section> </section>
@ -254,9 +254,9 @@ export function PaymentRequestView({
<Fragment> <Fragment>
<section> <section>
<ButtonSuccess upperCased onClick={onClick}> <ButtonSuccess upperCased onClick={onClick}>
<Translate> <i18n.Translate>
Pay {amountToString(payStatus.amountEffective)} Pay {amountToString(payStatus.amountEffective)}
</Translate> </i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</section> </section>
<Alternative /> <Alternative />
@ -269,22 +269,22 @@ export function PaymentRequestView({
<section> <section>
{balance ? ( {balance ? (
<WarningBox> <WarningBox>
<Translate> <i18n.Translate>
Your balance of {amountToString(balance)} is not enough to pay Your balance of {amountToString(balance)} is not enough to pay
for this purchase for this purchase
</Translate> </i18n.Translate>
</WarningBox> </WarningBox>
) : ( ) : (
<WarningBox> <WarningBox>
<Translate> <i18n.Translate>
Your balance is not enough to pay for this purchase. Your balance is not enough to pay for this purchase.
</Translate> </i18n.Translate>
</WarningBox> </WarningBox>
)} )}
</section> </section>
<section> <section>
<ButtonSuccess upperCased onClick={goToWalletManualWithdraw}> <ButtonSuccess upperCased onClick={goToWalletManualWithdraw}>
<Translate>Withdraw digital cash</Translate> <i18n.Translate>Withdraw digital cash</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</section> </section>
<Alternative /> <Alternative />
@ -297,7 +297,7 @@ export function PaymentRequestView({
<section> <section>
{payStatus.paid && contractTerms.fulfillment_message && ( {payStatus.paid && contractTerms.fulfillment_message && (
<Part <Part
title={<Translate>Merchant message</Translate>} title={<i18n.Translate>Merchant message</i18n.Translate>}
text={contractTerms.fulfillment_message} text={contractTerms.fulfillment_message}
kind="neutral" kind="neutral"
/> />
@ -315,43 +315,43 @@ export function PaymentRequestView({
<LogoHeader /> <LogoHeader />
<h2> <h2>
<Translate>Digital cash payment</Translate> <i18n.Translate>Digital cash payment</i18n.Translate>
</h2> </h2>
{payStatus.status === PreparePayResultType.AlreadyConfirmed && {payStatus.status === PreparePayResultType.AlreadyConfirmed &&
(payStatus.paid ? ( (payStatus.paid ? (
payStatus.contractTerms.fulfillment_url ? ( payStatus.contractTerms.fulfillment_url ? (
<SuccessBox> <SuccessBox>
<Translate> <i18n.Translate>
Already paid, you are going to be redirected to{" "} Already paid, you are going to be redirected to{" "}
<a href={payStatus.contractTerms.fulfillment_url}> <a href={payStatus.contractTerms.fulfillment_url}>
{payStatus.contractTerms.fulfillment_url} {payStatus.contractTerms.fulfillment_url}
</a> </a>
</Translate> </i18n.Translate>
</SuccessBox> </SuccessBox>
) : ( ) : (
<SuccessBox> <SuccessBox>
<Translate>Already paid</Translate> <i18n.Translate>Already paid</i18n.Translate>
</SuccessBox> </SuccessBox>
) )
) : ( ) : (
<WarningBox> <WarningBox>
<Translate>Already claimed</Translate> <i18n.Translate>Already claimed</i18n.Translate>
</WarningBox> </WarningBox>
))} ))}
{payResult && payResult.type === ConfirmPayResultType.Done && ( {payResult && payResult.type === ConfirmPayResultType.Done && (
<SuccessBox> <SuccessBox>
<h3> <h3>
<Translate>Payment complete</Translate> <i18n.Translate>Payment complete</i18n.Translate>
</h3> </h3>
<p> <p>
{!payResult.contractTerms.fulfillment_message ? ( {!payResult.contractTerms.fulfillment_message ? (
payResult.contractTerms.fulfillment_url ? ( payResult.contractTerms.fulfillment_url ? (
<Translate> <i18n.Translate>
You are going to be redirected to $ You are going to be redirected to $
{payResult.contractTerms.fulfillment_url} {payResult.contractTerms.fulfillment_url}
</Translate> </i18n.Translate>
) : ( ) : (
<Translate>You can close this page.</Translate> <i18n.Translate>You can close this page.</i18n.Translate>
) )
) : ( ) : (
payResult.contractTerms.fulfillment_message payResult.contractTerms.fulfillment_message
@ -364,14 +364,14 @@ export function PaymentRequestView({
Amounts.isNonZero(totalFees) && ( Amounts.isNonZero(totalFees) && (
<Part <Part
big big
title={<Translate>Total to pay</Translate>} title={<i18n.Translate>Total to pay</i18n.Translate>}
text={amountToString(payStatus.amountEffective)} text={amountToString(payStatus.amountEffective)}
kind="negative" kind="negative"
/> />
)} )}
<Part <Part
big big
title={<Translate>Purchase amount</Translate>} title={<i18n.Translate>Purchase amount</i18n.Translate>}
text={amountToString(payStatus.amountRaw)} text={amountToString(payStatus.amountRaw)}
kind="neutral" kind="neutral"
/> />
@ -379,25 +379,25 @@ export function PaymentRequestView({
<Fragment> <Fragment>
<Part <Part
big big
title={<Translate>Fee</Translate>} title={<i18n.Translate>Fee</i18n.Translate>}
text={amountToString(totalFees)} text={amountToString(totalFees)}
kind="negative" kind="negative"
/> />
</Fragment> </Fragment>
)} )}
<Part <Part
title={<Translate>Merchant</Translate>} title={<i18n.Translate>Merchant</i18n.Translate>}
text={contractTerms.merchant.name} text={contractTerms.merchant.name}
kind="neutral" kind="neutral"
/> />
<Part <Part
title={<Translate>Purchase</Translate>} title={<i18n.Translate>Purchase</i18n.Translate>}
text={contractTerms.summary} text={contractTerms.summary}
kind="neutral" kind="neutral"
/> />
{contractTerms.order_id && ( {contractTerms.order_id && (
<Part <Part
title={<Translate>Receipt</Translate>} title={<i18n.Translate>Receipt</i18n.Translate>}
text={`#${contractTerms.order_id}`} text={`#${contractTerms.order_id}`}
kind="neutral" kind="neutral"
/> />
@ -415,7 +415,7 @@ function ProductList({ products }: { products: Product[] }): VNode {
return ( return (
<Fragment> <Fragment>
<SmallLightText style={{ margin: ".5em" }}> <SmallLightText style={{ margin: ".5em" }}>
<Translate>List of products</Translate> <i18n.Translate>List of products</i18n.Translate>
</SmallLightText> </SmallLightText>
<dl> <dl>
{products.map((p, i) => { {products.map((p, i) => {
@ -457,7 +457,7 @@ function ProductList({ products }: { products: Product[] }): VNode {
{p.quantity ?? 1} x {p.description} {p.quantity ?? 1} x {p.description}
</dt> </dt>
<dd> <dd>
<Translate>Total</Translate> <i18n.Translate>Total</i18n.Translate>
{` `} {` `}
{p.price ? ( {p.price ? (
`${Amounts.stringifyValue( `${Amounts.stringifyValue(
@ -467,7 +467,7 @@ function ProductList({ products }: { products: Product[] }): VNode {
).amount, ).amount,
)} ${p}` )} ${p}`
) : ( ) : (
<Translate>free</Translate> <i18n.Translate>free</i18n.Translate>
)} )}
</dd> </dd>
</div> </div>

View File

@ -20,7 +20,7 @@
* @author sebasjm * @author sebasjm
*/ */
import { Amounts, ApplyRefundResponse, Translate } from "@gnu-taler/taler-util"; import { Amounts, ApplyRefundResponse, i18n } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { AmountView } from "../renderHtml"; import { AmountView } from "../renderHtml";
@ -38,27 +38,29 @@ export function View({ applyResult }: ViewProps): VNode {
<h1>GNU Taler Wallet</h1> <h1>GNU Taler Wallet</h1>
<article class="fade"> <article class="fade">
<h2> <h2>
<Translate>Refund Status</Translate> <i18n.Translate>Refund Status</i18n.Translate>
</h2> </h2>
<p> <p>
<Translate> <i18n.Translate>
The product <em>{applyResult.info.summary}</em> has received a total The product <em>{applyResult.info.summary}</em> has received a total
effective refund of{" "} effective refund of{" "}
</Translate> </i18n.Translate>
<AmountView amount={applyResult.amountRefundGranted} />. <AmountView amount={applyResult.amountRefundGranted} />.
</p> </p>
{applyResult.pendingAtExchange ? ( {applyResult.pendingAtExchange ? (
<p> <p>
<Translate>Refund processing is still in progress.</Translate> <i18n.Translate>
Refund processing is still in progress.
</i18n.Translate>
</p> </p>
) : null} ) : null}
{!Amounts.isZero(applyResult.amountRefundGone) ? ( {!Amounts.isZero(applyResult.amountRefundGone) ? (
<p> <p>
<Translate> <i18n.Translate>
The refund amount of{" "} The refund amount of{" "}
<AmountView amount={applyResult.amountRefundGone} /> could not be <AmountView amount={applyResult.amountRefundGone} /> could not be
applied. applied.
</Translate> </i18n.Translate>
</p> </p>
) : null} ) : null}
</article> </article>
@ -92,7 +94,7 @@ export function RefundPage({ talerRefundUri }: Props): VNode {
if (!talerRefundUri) { if (!talerRefundUri) {
return ( return (
<span> <span>
<Translate>missing taler refund uri</Translate> <i18n.Translate>missing taler refund uri</i18n.Translate>
</span> </span>
); );
} }
@ -100,7 +102,7 @@ export function RefundPage({ talerRefundUri }: Props): VNode {
if (errMsg) { if (errMsg) {
return ( return (
<span> <span>
<Translate>Error: {errMsg}</Translate> <i18n.Translate>Error: {errMsg}</i18n.Translate>
</span> </span>
); );
} }
@ -108,7 +110,7 @@ export function RefundPage({ talerRefundUri }: Props): VNode {
if (!applyResult) { if (!applyResult) {
return ( return (
<span> <span>
<Translate>Updating refund status</Translate> <i18n.Translate>Updating refund status</i18n.Translate>
</span> </span>
); );
} }

View File

@ -34,7 +34,9 @@ export function TermsOfServiceSection({
{terms.status === "notfound" && ( {terms.status === "notfound" && (
<section> <section>
<WarningText> <WarningText>
<Translate>Exchange doesn't have terms of service</Translate> <i18n.Translate>
Exchange doesn't have terms of service
</i18n.Translate>
</WarningText> </WarningText>
</section> </section>
)} )}
@ -46,21 +48,27 @@ export function TermsOfServiceSection({
{terms.status === "notfound" && ( {terms.status === "notfound" && (
<section> <section>
<WarningText> <WarningText>
<Translate>Exchange doesn't have terms of service</Translate> <i18n.Translate>
Exchange doesn't have terms of service
</i18n.Translate>
</WarningText> </WarningText>
</section> </section>
)} )}
{terms.status === "new" && ( {terms.status === "new" && (
<section> <section>
<ButtonSuccess upperCased onClick={() => onReview(true)}> <ButtonSuccess upperCased onClick={() => onReview(true)}>
<Translate>Review exchange terms of service</Translate> <i18n.Translate>
Review exchange terms of service
</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</section> </section>
)} )}
{terms.status === "changed" && ( {terms.status === "changed" && (
<section> <section>
<ButtonWarning upperCased onClick={() => onReview(true)}> <ButtonWarning upperCased onClick={() => onReview(true)}>
<Translate>Review new version of terms of service</Translate> <i18n.Translate>
Review new version of terms of service
</i18n.Translate>
</ButtonWarning> </ButtonWarning>
</section> </section>
)} )}
@ -72,7 +80,7 @@ export function TermsOfServiceSection({
{onReview && ( {onReview && (
<section> <section>
<LinkSuccess upperCased onClick={() => onReview(true)}> <LinkSuccess upperCased onClick={() => onReview(true)}>
<Translate>Show terms of service</Translate> <i18n.Translate>Show terms of service</i18n.Translate>
</LinkSuccess> </LinkSuccess>
</section> </section>
)} )}
@ -81,7 +89,9 @@ export function TermsOfServiceSection({
name="terms" name="terms"
enabled={reviewed} enabled={reviewed}
label={ label={
<Translate>I accept the exchange terms of service</Translate> <i18n.Translate>
I accept the exchange terms of service
</i18n.Translate>
} }
onToggle={() => { onToggle={() => {
onAccept(!reviewed); onAccept(!reviewed);
@ -97,9 +107,9 @@ export function TermsOfServiceSection({
{terms.status !== "notfound" && !terms.content && ( {terms.status !== "notfound" && !terms.content && (
<section> <section>
<WarningBox> <WarningBox>
<Translate> <i18n.Translate>
The exchange reply with a empty terms of service The exchange reply with a empty terms of service
</Translate> </i18n.Translate>
</WarningBox> </WarningBox>
</section> </section>
)} )}
@ -120,7 +130,7 @@ export function TermsOfServiceSection({
)} )}
{terms.content.type === "pdf" && ( {terms.content.type === "pdf" && (
<a href={terms.content.location.toString()} download="tos.pdf"> <a href={terms.content.location.toString()} download="tos.pdf">
<Translate>Download Terms of Service</Translate> <i18n.Translate>Download Terms of Service</i18n.Translate>
</a> </a>
)} )}
</section> </section>
@ -128,7 +138,7 @@ export function TermsOfServiceSection({
{reviewed && onReview && ( {reviewed && onReview && (
<section> <section>
<LinkSuccess upperCased onClick={() => onReview(false)}> <LinkSuccess upperCased onClick={() => onReview(false)}>
<Translate>Hide terms of service</Translate> <i18n.Translate>Hide terms of service</i18n.Translate>
</LinkSuccess> </LinkSuccess>
</section> </section>
)} )}
@ -138,7 +148,9 @@ export function TermsOfServiceSection({
name="terms" name="terms"
enabled={reviewed} enabled={reviewed}
label={ label={
<Translate>I accept the exchange terms of service</Translate> <i18n.Translate>
I accept the exchange terms of service
</i18n.Translate>
} }
onToggle={() => { onToggle={() => {
onAccept(!reviewed); onAccept(!reviewed);

View File

@ -20,7 +20,7 @@
* @author sebasjm <dold@taler.net> * @author sebasjm <dold@taler.net>
*/ */
import { PrepareTipResult, Translate } from "@gnu-taler/taler-util"; import { PrepareTipResult, i18n } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
import { useEffect, useState } from "preact/hooks"; import { useEffect, useState } from "preact/hooks";
import { Loading } from "../components/Loading"; import { Loading } from "../components/Loading";
@ -46,28 +46,28 @@ export function View({
<article class="fade"> <article class="fade">
{prepareTipResult.accepted ? ( {prepareTipResult.accepted ? (
<span> <span>
<Translate> <i18n.Translate>
Tip from <code>{prepareTipResult.merchantBaseUrl}</code> accepted. Tip from <code>{prepareTipResult.merchantBaseUrl}</code> accepted.
Check your transactions list for more details. Check your transactions list for more details.
</Translate> </i18n.Translate>
</span> </span>
) : ( ) : (
<div> <div>
<p> <p>
<Translate> <i18n.Translate>
The merchant <code>{prepareTipResult.merchantBaseUrl}</code> is The merchant <code>{prepareTipResult.merchantBaseUrl}</code> is
offering you a tip of{" "} offering you a tip of{" "}
<strong> <strong>
<AmountView amount={prepareTipResult.tipAmountEffective} /> <AmountView amount={prepareTipResult.tipAmountEffective} />
</strong>{" "} </strong>{" "}
via the exchange <code>{prepareTipResult.exchangeBaseUrl}</code> via the exchange <code>{prepareTipResult.exchangeBaseUrl}</code>
</Translate> </i18n.Translate>
</p> </p>
<button onClick={onAccept}> <button onClick={onAccept}>
<Translate>Accept tip</Translate> <i18n.Translate>Accept tip</i18n.Translate>
</button> </button>
<button onClick={onIgnore}> <button onClick={onIgnore}>
<Translate>Ignore</Translate> <i18n.Translate>Ignore</i18n.Translate>
</button> </button>
</div> </div>
)} )}
@ -108,7 +108,7 @@ export function TipPage({ talerTipUri }: Props): VNode {
if (!talerTipUri) { if (!talerTipUri) {
return ( return (
<span> <span>
<Translate>missing tip uri</Translate> <i18n.Translate>missing tip uri</i18n.Translate>
</span> </span>
); );
} }
@ -116,7 +116,7 @@ export function TipPage({ talerTipUri }: Props): VNode {
if (tipIgnored) { if (tipIgnored) {
return ( return (
<span> <span>
<Translate>You've ignored the tip.</Translate> <i18n.Translate>You've ignored the tip.</i18n.Translate>
</span> </span>
); );
} }

View File

@ -119,13 +119,15 @@ export function View({
<WalletAction> <WalletAction>
<LogoHeader /> <LogoHeader />
<h2> <h2>
<Translate>Digital cash withdrawal</Translate> <i18n.Translate>Digital cash withdrawal</i18n.Translate>
</h2> </h2>
{withdrawError && ( {withdrawError && (
<ErrorTalerOperation <ErrorTalerOperation
title={ title={
<Translate>Could not finish the withdrawal operation</Translate> <i18n.Translate>
Could not finish the withdrawal operation
</i18n.Translate>
} }
error={withdrawError.operationError} error={withdrawError.operationError}
/> />
@ -133,19 +135,19 @@ export function View({
<section> <section>
<Part <Part
title={<Translate>Total to withdraw</Translate>} title={<i18n.Translate>Total to withdraw</i18n.Translate>}
text={amountToString(Amounts.sub(amount, withdrawalFee).amount)} text={amountToString(Amounts.sub(amount, withdrawalFee).amount)}
kind="positive" kind="positive"
/> />
{Amounts.isNonZero(withdrawalFee) && ( {Amounts.isNonZero(withdrawalFee) && (
<Fragment> <Fragment>
<Part <Part
title={<Translate>Chosen amount</Translate>} title={<i18n.Translate>Chosen amount</i18n.Translate>}
text={amountToString(amount)} text={amountToString(amount)}
kind="neutral" kind="neutral"
/> />
<Part <Part
title={<Translate>Exchange fee</Translate>} title={<i18n.Translate>Exchange fee</i18n.Translate>}
text={amountToString(withdrawalFee)} text={amountToString(withdrawalFee)}
kind="negative" kind="negative"
/> />
@ -153,7 +155,7 @@ export function View({
)} )}
{exchangeBaseUrl && ( {exchangeBaseUrl && (
<Part <Part
title={<Translate>Exchange</Translate>} title={<i18n.Translate>Exchange</i18n.Translate>}
text={exchangeBaseUrl} text={exchangeBaseUrl}
kind="neutral" kind="neutral"
big big
@ -166,7 +168,7 @@ export function View({
<Fragment> <Fragment>
<div> <div>
<SelectList <SelectList
label={<Translate>Known exchanges</Translate>} label={<i18n.Translate>Known exchanges</i18n.Translate>}
list={exchanges} list={exchanges}
value={nextExchange} value={nextExchange}
name="switchingExchange" name="switchingExchange"
@ -183,15 +185,15 @@ export function View({
}} }}
> >
{nextExchange === undefined ? ( {nextExchange === undefined ? (
<Translate>Cancel exchange selection</Translate> <i18n.Translate>Cancel exchange selection</i18n.Translate>
) : ( ) : (
<Translate>Confirm exchange selection</Translate> <i18n.Translate>Confirm exchange selection</i18n.Translate>
)} )}
</LinkSuccess> </LinkSuccess>
</Fragment> </Fragment>
) : ( ) : (
<LinkSuccess upperCased onClick={() => setSwitchingExchange(true)}> <LinkSuccess upperCased onClick={() => setSwitchingExchange(true)}>
<Translate>Switch exchange</Translate> <i18n.Translate>Switch exchange</i18n.Translate>
</LinkSuccess> </LinkSuccess>
)} )}
</section> </section>
@ -210,7 +212,7 @@ export function View({
disabled={!exchangeBaseUrl || confirmDisabled} disabled={!exchangeBaseUrl || confirmDisabled}
onClick={doWithdrawAndCheckError} onClick={doWithdrawAndCheckError}
> >
<Translate>Confirm withdrawal</Translate> <i18n.Translate>Confirm withdrawal</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
)} )}
{terms.status === "notfound" && ( {terms.status === "notfound" && (
@ -219,7 +221,7 @@ export function View({
disabled={!exchangeBaseUrl} disabled={!exchangeBaseUrl}
onClick={doWithdrawAndCheckError} onClick={doWithdrawAndCheckError}
> >
<Translate>Withdraw anyway</Translate> <i18n.Translate>Withdraw anyway</i18n.Translate>
</ButtonWarning> </ButtonWarning>
)} )}
</section> </section>
@ -282,7 +284,9 @@ export function WithdrawPageWithParsedURI({
if (detailsHook.hasError) { if (detailsHook.hasError) {
return ( return (
<LoadingError <LoadingError
title={<Translate>Could not load the withdrawal details</Translate>} title={
<i18n.Translate>Could not load the withdrawal details</i18n.Translate>
}
error={detailsHook} error={detailsHook}
/> />
); );
@ -337,7 +341,7 @@ export function WithdrawPage({ talerWithdrawUri }: Props): VNode {
if (!talerWithdrawUri) { if (!talerWithdrawUri) {
return ( return (
<span> <span>
<Translate>missing withdraw uri</Translate> <i18n.Translate>missing withdraw uri</i18n.Translate>
</span> </span>
); );
} }
@ -347,7 +351,9 @@ export function WithdrawPage({ talerWithdrawUri }: Props): VNode {
if (uriInfoHook.hasError) { if (uriInfoHook.hasError) {
return ( return (
<LoadingError <LoadingError
title={<Translate>Could not get the info from the URI</Translate>} title={
<i18n.Translate>Could not get the info from the URI</i18n.Translate>
}
error={uriInfoHook} error={uriInfoHook}
/> />
); );

View File

@ -20,7 +20,7 @@
* @author sebasjm * @author sebasjm
*/ */
import { Translate } from "@gnu-taler/taler-util"; import { i18n } from "@gnu-taler/taler-util";
import { Component, h, VNode } from "preact"; import { Component, h, VNode } from "preact";
import * as wxApi from "../wxApi"; import * as wxApi from "../wxApi";
@ -51,19 +51,19 @@ class ResetNotification extends Component<any, State> {
return ( return (
<div> <div>
<h1> <h1>
<Translate>Manual Reset Required</Translate> <i18n.Translate>Manual Reset Required</i18n.Translate>
</h1> </h1>
<p> <p>
<Translate> <i18n.Translate>
The wallet&apos;s database in your browser is incompatible with The wallet&apos;s database in your browser is incompatible with
the currently installed wallet. Please reset manually. the currently installed wallet. Please reset manually.
</Translate> </i18n.Translate>
</p> </p>
<p> <p>
<Translate> <i18n.Translate>
Once the database format has stabilized, we will provide automatic Once the database format has stabilized, we will provide automatic
upgrades. upgrades.
</Translate> </i18n.Translate>
</p> </p>
<input <input
id="check" id="check"
@ -74,7 +74,9 @@ class ResetNotification extends Component<any, State> {
}} }}
/>{" "} />{" "}
<label htmlFor="check"> <label htmlFor="check">
<Translate>I understand that I will lose all my data</Translate> <i18n.Translate>
I understand that I will lose all my data
</i18n.Translate>
</label> </label>
<br /> <br />
<button <button
@ -82,7 +84,7 @@ class ResetNotification extends Component<any, State> {
disabled={!this.state.checked} disabled={!this.state.checked}
onClick={() => wxApi.resetDb()} onClick={() => wxApi.resetDb()}
> >
<Translate>Reset</Translate> <i18n.Translate>Reset</i18n.Translate>
</button> </button>
</div> </div>
); );
@ -90,12 +92,12 @@ class ResetNotification extends Component<any, State> {
return ( return (
<div> <div>
<h1> <h1>
<Translate>Everything is fine!</Translate> <i18n.Translate>Everything is fine!</i18n.Translate>
</h1> </h1>
<p> <p>
<Translate> <i18n.Translate>
A reset is not required anymore, you can close this page. A reset is not required anymore, you can close this page.
</Translate> </i18n.Translate>
</p> </p>
</div> </div>
); );

View File

@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { Translate } from "@gnu-taler/taler-util"; import { i18n } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
/** /**
* Return coins to own bank account. * Return coins to own bank account.
@ -28,7 +28,7 @@ import { h, VNode } from "preact";
export function createReturnCoinsPage(): VNode { export function createReturnCoinsPage(): VNode {
return ( return (
<span> <span>
<Translate>Not implemented yet.</Translate> <i18n.Translate>Not implemented yet.</i18n.Translate>
</span> </span>
); );
} }

View File

@ -1,3 +1,5 @@
export const strings: any = {}
strings['de'] = { strings['de'] = {
"domain": "messages", "domain": "messages",
"locale_data": { "locale_data": {

View File

@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { Amounts, Balance, Translate } from "@gnu-taler/taler-util"; import { Amounts, Balance, i18n } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
import { BalanceTable } from "../components/BalanceTable"; import { BalanceTable } from "../components/BalanceTable";
@ -49,7 +49,7 @@ export function BalancePage({
if (state.hasError) { if (state.hasError) {
return ( return (
<LoadingError <LoadingError
title={<Translate>Could not load balance page</Translate>} title={<i18n.Translate>Could not load balance page</i18n.Translate>}
error={state} error={state}
/> />
); );
@ -104,18 +104,18 @@ export function BalanceView({
</section> </section>
<footer style={{ justifyContent: "space-between" }}> <footer style={{ justifyContent: "space-between" }}>
<ButtonPrimary onClick={goToWalletManualWithdraw}> <ButtonPrimary onClick={goToWalletManualWithdraw}>
<Translate>Withdraw</Translate> <i18n.Translate>Withdraw</i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
{currencyWithNonZeroAmount.length > 0 && ( {currencyWithNonZeroAmount.length > 0 && (
<MultiActionButton <MultiActionButton
label={(s) => <Translate>Deposit {s}</Translate>} label={(s) => <i18n.Translate>Deposit {s}</i18n.Translate>}
actions={currencyWithNonZeroAmount} actions={currencyWithNonZeroAmount}
onClick={(c) => goToWalletDeposit(c)} onClick={(c) => goToWalletDeposit(c)}
/> />
)} )}
<JustInDevMode> <JustInDevMode>
<ButtonBoxPrimary onClick={goToAddAction}> <ButtonBoxPrimary onClick={goToAddAction}>
<Translate>Enter URI</Translate> <i18n.Translate>Enter URI</i18n.Translate>
</ButtonBoxPrimary> </ButtonBoxPrimary>
</JustInDevMode> </JustInDevMode>
</footer> </footer>

View File

@ -151,14 +151,14 @@ export function View({
return ( return (
<div> <div>
<p> <p>
<Translate>Debug tools</Translate>: <i18n.Translate>Debug tools</i18n.Translate>:
</p> </p>
<button onClick={confirmReset}> <button onClick={confirmReset}>
<Translate>reset</Translate> <i18n.Translate>reset</i18n.Translate>
</button> </button>
<br /> <br />
<button onClick={() => fileRef?.current?.click()}> <button onClick={() => fileRef?.current?.click()}>
<Translate>import database</Translate> <i18n.Translate>import database</i18n.Translate>
</button> </button>
<input <input
ref={fileRef} ref={fileRef}
@ -179,11 +179,11 @@ export function View({
/> />
<br /> <br />
<button onClick={onExportDatabase}> <button onClick={onExportDatabase}>
<Translate>export database</Translate> <i18n.Translate>export database</i18n.Translate>
</button> </button>
{downloadedDatabase && ( {downloadedDatabase && (
<div> <div>
<Translate> <i18n.Translate>
Database exported at Database exported at
<Time <Time
timestamp={{ t_ms: downloadedDatabase.time.getTime() }} timestamp={{ t_ms: downloadedDatabase.time.getTime() }}
@ -198,15 +198,15 @@ export function View({
"yyyy/MM/dd_HH:mm", "yyyy/MM/dd_HH:mm",
)}.json`} )}.json`}
> >
<Translate>click here</Translate> <i18n.Translate>click here</i18n.Translate>
</a> </a>
to download to download
</Translate> </i18n.Translate>
</div> </div>
)} )}
<br /> <br />
<p> <p>
<Translate>Coins</Translate>: <i18n.Translate>Coins</i18n.Translate>:
</p> </p>
{Object.keys(money_by_exchange).map((ex) => { {Object.keys(money_by_exchange).map((ex) => {
const allcoins = money_by_exchange[ex]; const allcoins = money_by_exchange[ex];
@ -233,7 +233,7 @@ export function View({
{operations && operations.length > 0 && ( {operations && operations.length > 0 && (
<Fragment> <Fragment>
<p> <p>
<Translate>Pending operations</Translate> <i18n.Translate>Pending operations</i18n.Translate>
</p> </p>
<dl> <dl>
{operations.reverse().map((o) => { {operations.reverse().map((o) => {
@ -272,7 +272,7 @@ function ShowAllCoins({
</p> </p>
<p> <p>
<b> <b>
<Translate>usable coins</Translate> <i18n.Translate>usable coins</i18n.Translate>
</b> </b>
</p> </p>
{collapsedUnspent ? ( {collapsedUnspent ? (
@ -281,19 +281,19 @@ function ShowAllCoins({
<table onClick={() => setCollapsedUnspent(true)}> <table onClick={() => setCollapsedUnspent(true)}>
<tr> <tr>
<td> <td>
<Translate>id</Translate> <i18n.Translate>id</i18n.Translate>
</td> </td>
<td> <td>
<Translate>denom</Translate> <i18n.Translate>denom</i18n.Translate>
</td> </td>
<td> <td>
<Translate>value</Translate> <i18n.Translate>value</i18n.Translate>
</td> </td>
<td> <td>
<Translate>status</Translate> <i18n.Translate>status</i18n.Translate>
</td> </td>
<td> <td>
<Translate>from refresh?</Translate> <i18n.Translate>from refresh?</i18n.Translate>
</td> </td>
</tr> </tr>
{coins.usable.map((c) => { {coins.usable.map((c) => {
@ -310,29 +310,29 @@ function ShowAllCoins({
</table> </table>
)} )}
<p> <p>
<Translate>spent coins</Translate> <i18n.Translate>spent coins</i18n.Translate>
</p> </p>
{collapsedSpent ? ( {collapsedSpent ? (
<div onClick={() => setCollapsedSpent(false)}> <div onClick={() => setCollapsedSpent(false)}>
<Translate>click to show</Translate> <i18n.Translate>click to show</i18n.Translate>
</div> </div>
) : ( ) : (
<table onClick={() => setCollapsedSpent(true)}> <table onClick={() => setCollapsedSpent(true)}>
<tr> <tr>
<td> <td>
<Translate>id</Translate> <i18n.Translate>id</i18n.Translate>
</td> </td>
<td> <td>
<Translate>denom</Translate> <i18n.Translate>denom</i18n.Translate>
</td> </td>
<td> <td>
<Translate>value</Translate> <i18n.Translate>value</i18n.Translate>
</td> </td>
<td> <td>
<Translate>status</Translate> <i18n.Translate>status</i18n.Translate>
</td> </td>
<td> <td>
<Translate>from refresh?</Translate> <i18n.Translate>from refresh?</i18n.Translate>
</td> </td>
</tr> </tr>
{coins.spent.map((c) => { {coins.spent.map((c) => {

View File

@ -1,4 +1,4 @@
import { Translate } from "@gnu-taler/taler-util"; import { i18n } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
import { ButtonBoxWarning, WarningBox } from "../components/styled"; import { ButtonBoxWarning, WarningBox } from "../components/styled";
@ -11,16 +11,16 @@ export function NoBalanceHelp({
<WarningBox> <WarningBox>
<p> <p>
<b> <b>
<Translate>You have no balance to show.</Translate> <i18n.Translate>You have no balance to show.</i18n.Translate>
</b> </b>
<br /> <br />
<Translate> <i18n.Translate>
To withdraw money you can start from your bank site or click the To withdraw money you can start from your bank site or click the
"withdraw" button to use a known exchange. "withdraw" button to use a known exchange.
</Translate> </i18n.Translate>
</p> </p>
<ButtonBoxWarning onClick={() => goToWalletManualWithdraw()}> <ButtonBoxWarning onClick={() => goToWalletManualWithdraw()}>
<Translate>Withdraw</Translate> <i18n.Translate>Withdraw</i18n.Translate>
</ButtonBoxWarning> </ButtonBoxWarning>
</WarningBox> </WarningBox>
); );

View File

@ -19,11 +19,7 @@
* @author Sebastian Javier Marchano (sebasjm) * @author Sebastian Javier Marchano (sebasjm)
*/ */
import { import { classifyTalerUri, TalerUriType, i18n } from "@gnu-taler/taler-util";
classifyTalerUri,
TalerUriType,
Translate,
} from "@gnu-taler/taler-util";
import { Fragment, h } from "preact"; import { Fragment, h } from "preact";
import { ButtonPrimary, ButtonSuccess } from "../components/styled"; import { ButtonPrimary, ButtonSuccess } from "../components/styled";
import { actionForTalerUri } from "../utils/index"; import { actionForTalerUri } from "../utils/index";
@ -57,54 +53,58 @@ export function TalerActionFound({ url, onDismiss }: Props) {
<Fragment> <Fragment>
<section> <section>
<h1> <h1>
<Translate>Taler Action</Translate> <i18n.Translate>Taler Action</i18n.Translate>
</h1> </h1>
{uriType === TalerUriType.TalerPay && ( {uriType === TalerUriType.TalerPay && (
<div> <div>
<p> <p>
<Translate>This page has pay action.</Translate> <i18n.Translate>This page has pay action.</i18n.Translate>
</p> </p>
<ButtonSuccess <ButtonSuccess
onClick={() => { onClick={() => {
navigateTo(actionForTalerUri(uriType, url)); navigateTo(actionForTalerUri(uriType, url));
}} }}
> >
<Translate>Open pay page</Translate> <i18n.Translate>Open pay page</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</div> </div>
)} )}
{uriType === TalerUriType.TalerWithdraw && ( {uriType === TalerUriType.TalerWithdraw && (
<div> <div>
<p> <p>
<Translate>This page has a withdrawal action.</Translate> <i18n.Translate>
This page has a withdrawal action.
</i18n.Translate>
</p> </p>
<ButtonSuccess <ButtonSuccess
onClick={() => { onClick={() => {
navigateTo(actionForTalerUri(uriType, url)); navigateTo(actionForTalerUri(uriType, url));
}} }}
> >
<Translate>Open withdraw page</Translate> <i18n.Translate>Open withdraw page</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</div> </div>
)} )}
{uriType === TalerUriType.TalerTip && ( {uriType === TalerUriType.TalerTip && (
<div> <div>
<p> <p>
<Translate>This page has a tip action.</Translate> <i18n.Translate>This page has a tip action.</i18n.Translate>
</p> </p>
<ButtonSuccess <ButtonSuccess
onClick={() => { onClick={() => {
navigateTo(actionForTalerUri(uriType, url)); navigateTo(actionForTalerUri(uriType, url));
}} }}
> >
<Translate>Open tip page</Translate> <i18n.Translate>Open tip page</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</div> </div>
)} )}
{uriType === TalerUriType.TalerNotifyReserve && ( {uriType === TalerUriType.TalerNotifyReserve && (
<div> <div>
<p> <p>
<Translate>This page has a notify reserve action.</Translate> <i18n.Translate>
This page has a notify reserve action.
</i18n.Translate>
</p> </p>
<ButtonSuccess <ButtonSuccess
onClick={() => { onClick={() => {
@ -118,21 +118,23 @@ export function TalerActionFound({ url, onDismiss }: Props) {
{uriType === TalerUriType.TalerRefund && ( {uriType === TalerUriType.TalerRefund && (
<div> <div>
<p> <p>
<Translate>This page has a refund action.</Translate> <i18n.Translate>This page has a refund action.</i18n.Translate>
</p> </p>
<ButtonSuccess <ButtonSuccess
onClick={() => { onClick={() => {
navigateTo(actionForTalerUri(uriType, url)); navigateTo(actionForTalerUri(uriType, url));
}} }}
> >
<Translate>Open refund page</Translate> <i18n.Translate>Open refund page</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</div> </div>
)} )}
{uriType === TalerUriType.Unknown && ( {uriType === TalerUriType.Unknown && (
<div> <div>
<p> <p>
<Translate>This page has a malformed taler uri.</Translate> <i18n.Translate>
This page has a malformed taler uri.
</i18n.Translate>
</p> </p>
<p>{url}</p> <p>{url}</p>
</div> </div>
@ -142,7 +144,7 @@ export function TalerActionFound({ url, onDismiss }: Props) {
<div /> <div />
<ButtonPrimary onClick={() => onDismiss()}> <ButtonPrimary onClick={() => onDismiss()}>
{" "} {" "}
<Translate>Dismiss</Translate>{" "} <i18n.Translate>Dismiss</i18n.Translate>{" "}
</ButtonPrimary> </ButtonPrimary>
</footer> </footer>
</Fragment> </Fragment>

View File

@ -20,7 +20,7 @@
* @author sebasjm <dold@taler.net> * @author sebasjm <dold@taler.net>
*/ */
import { setupI18n, Translate } from "@gnu-taler/taler-util"; import { setupI18n, i18n } from "@gnu-taler/taler-util";
import { createHashHistory } from "history"; import { createHashHistory } from "history";
import { Fragment, h, render, VNode } from "preact"; import { Fragment, h, render, VNode } from "preact";
import Router, { route, Route } from "preact-router"; import Router, { route, Route } from "preact-router";
@ -181,9 +181,9 @@ function RedirectToWalletPage(): VNode {
}); });
return ( return (
<span> <span>
<Translate> <i18n.Translate>
this popup is being closed and you are being redirected to {page} this popup is being closed and you are being redirected to {page}
</Translate> </i18n.Translate>
</span> </span>
); );
} }

View File

@ -1,8 +1,4 @@
import { import { classifyTalerUri, TalerUriType, i18n } from "@gnu-taler/taler-util";
classifyTalerUri,
TalerUriType,
Translate,
} from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
import { Button, ButtonSuccess, InputWithLabel } from "../components/styled"; import { Button, ButtonSuccess, InputWithLabel } from "../components/styled";
@ -15,15 +11,15 @@ export interface Props {
function buttonLabelByTalerType(type: TalerUriType): VNode { function buttonLabelByTalerType(type: TalerUriType): VNode {
switch (type) { switch (type) {
case TalerUriType.TalerNotifyReserve: case TalerUriType.TalerNotifyReserve:
return <Translate>Open reserve page</Translate>; return <i18n.Translate>Open reserve page</i18n.Translate>;
case TalerUriType.TalerPay: case TalerUriType.TalerPay:
return <Translate>Open pay page</Translate>; return <i18n.Translate>Open pay page</i18n.Translate>;
case TalerUriType.TalerRefund: case TalerUriType.TalerRefund:
return <Translate>Open refund page</Translate>; return <i18n.Translate>Open refund page</i18n.Translate>;
case TalerUriType.TalerTip: case TalerUriType.TalerTip:
return <Translate>Open tip page</Translate>; return <i18n.Translate>Open tip page</i18n.Translate>;
case TalerUriType.TalerWithdraw: case TalerUriType.TalerWithdraw:
return <Translate>Open withdraw page</Translate>; return <i18n.Translate>Open withdraw page</i18n.Translate>;
} }
return <Fragment />; return <Fragment />;
} }
@ -52,7 +48,7 @@ export function AddNewActionView({ onCancel }: Props): VNode {
</section> </section>
<footer> <footer>
<Button onClick={onCancel}> <Button onClick={onCancel}>
<Translate>Back</Translate> <i18n.Translate>Back</i18n.Translate>
</Button> </Button>
{uriType !== TalerUriType.Unknown && ( {uriType !== TalerUriType.Unknown && (
<ButtonSuccess <ButtonSuccess

View File

@ -72,7 +72,7 @@ export function BackupPage({ onAddProvider }: Props): VNode {
if (status.hasError) { if (status.hasError) {
return ( return (
<LoadingError <LoadingError
title={<Translate>Could not load backup providers</Translate>} title={<i18n.Translate>Could not load backup providers</i18n.Translate>}
error={status} error={status}
/> />
); );
@ -126,10 +126,10 @@ export function BackupView({
{!providers.length && ( {!providers.length && (
<Centered style={{ marginTop: 100 }}> <Centered style={{ marginTop: 100 }}>
<BoldLight> <BoldLight>
<Translate>No backup providers configured</Translate> <i18n.Translate>No backup providers configured</i18n.Translate>
</BoldLight> </BoldLight>
<ButtonSuccess onClick={onAddProvider}> <ButtonSuccess onClick={onAddProvider}>
<Translate>Add provider</Translate> <i18n.Translate>Add provider</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</Centered> </Centered>
)} )}
@ -140,13 +140,13 @@ export function BackupView({
<div> <div>
<ButtonPrimary onClick={onSyncAll}> <ButtonPrimary onClick={onSyncAll}>
{providers.length > 1 ? ( {providers.length > 1 ? (
<Translate>Sync all backups</Translate> <i18n.Translate>Sync all backups</i18n.Translate>
) : ( ) : (
<Translate>Sync now</Translate> <i18n.Translate>Sync now</i18n.Translate>
)} )}
</ButtonPrimary> </ButtonPrimary>
<ButtonSuccess onClick={onAddProvider}> <ButtonSuccess onClick={onAddProvider}>
<Translate>Add provider</Translate> <i18n.Translate>Add provider</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</div> </div>
</footer> </footer>
@ -184,12 +184,12 @@ function BackupLayout(props: TransactionLayoutProps): VNode {
{dateStr && ( {dateStr && (
<SmallText style={{ marginTop: 5 }}> <SmallText style={{ marginTop: 5 }}>
<Translate>Last synced</Translate>: {dateStr} <i18n.Translate>Last synced</i18n.Translate>: {dateStr}
</SmallText> </SmallText>
)} )}
{!dateStr && ( {!dateStr && (
<SmallLightText style={{ marginTop: 5 }}> <SmallLightText style={{ marginTop: 5 }}>
<Translate>Not synced</Translate> <i18n.Translate>Not synced</i18n.Translate>
</SmallLightText> </SmallLightText>
)} )}
</div> </div>
@ -208,7 +208,7 @@ function ExpirationText({ until }: { until: Timestamp }): VNode {
return ( return (
<Fragment> <Fragment>
<CenteredText> <CenteredText>
<Translate>Expires in</Translate> <i18n.Translate>Expires in</i18n.Translate>
</CenteredText> </CenteredText>
<CenteredBoldText {...{ color: colorByTimeToExpire(until) }}> <CenteredBoldText {...{ color: colorByTimeToExpire(until) }}>
{" "} {" "}

View File

@ -100,21 +100,21 @@ export function CreateManualWithdraw({
return ( return (
<section> <section>
<h2> <h2>
<Translate>Manual Withdrawal</Translate> <i18n.Translate>Manual Withdrawal</i18n.Translate>
</h2> </h2>
<LightText> <LightText>
<Translate> <i18n.Translate>
Choose a exchange from where the coins will be withdrawn. The Choose a exchange from where the coins will be withdrawn. The
exchange will send the coins to this wallet after receiving a wire exchange will send the coins to this wallet after receiving a wire
transfer with the correct subject. transfer with the correct subject.
</Translate> </i18n.Translate>
</LightText> </LightText>
<Centered style={{ marginTop: 100 }}> <Centered style={{ marginTop: 100 }}>
<BoldLight> <BoldLight>
<Translate>No exchange configured</Translate> <i18n.Translate>No exchange configured</i18n.Translate>
</BoldLight> </BoldLight>
<ButtonSuccess onClick={onAddExchange}> <ButtonSuccess onClick={onAddExchange}>
<Translate>Add exchange</Translate> <i18n.Translate>Add exchange</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
</Centered> </Centered>
</section> </section>
@ -126,24 +126,24 @@ export function CreateManualWithdraw({
<section> <section>
{error && ( {error && (
<ErrorMessage <ErrorMessage
title={<Translate>Can't create the reserve</Translate>} title={<i18n.Translate>Can't create the reserve</i18n.Translate>}
description={error} description={error}
/> />
)} )}
<h2> <h2>
<Translate>Manual Withdrawal</Translate> <i18n.Translate>Manual Withdrawal</i18n.Translate>
</h2> </h2>
<LightText> <LightText>
<Translate> <i18n.Translate>
Choose a exchange from where the coins will be withdrawn. The Choose a exchange from where the coins will be withdrawn. The
exchange will send the coins to this wallet after receiving a wire exchange will send the coins to this wallet after receiving a wire
transfer with the correct subject. transfer with the correct subject.
</Translate> </i18n.Translate>
</LightText> </LightText>
<p> <p>
<Input> <Input>
<SelectList <SelectList
label={<Translate>Currency</Translate>} label={<i18n.Translate>Currency</i18n.Translate>}
list={currencyMap} list={currencyMap}
name="currency" name="currency"
value={currency} value={currency}
@ -152,7 +152,7 @@ export function CreateManualWithdraw({
</Input> </Input>
<Input> <Input>
<SelectList <SelectList
label={<Translate>Exchange</Translate>} label={<i18n.Translate>Exchange</i18n.Translate>}
list={exchangeMap} list={exchangeMap}
name="currency" name="currency"
value={exchange} value={exchange}
@ -161,13 +161,13 @@ export function CreateManualWithdraw({
</Input> </Input>
<div style={{ display: "flex", justifyContent: "space-between" }}> <div style={{ display: "flex", justifyContent: "space-between" }}>
<LinkPrimary onClick={onAddExchange} style={{ marginLeft: "auto" }}> <LinkPrimary onClick={onAddExchange} style={{ marginLeft: "auto" }}>
<Translate>Add Exchange</Translate> <i18n.Translate>Add Exchange</i18n.Translate>
</LinkPrimary> </LinkPrimary>
</div> </div>
{currency && ( {currency && (
<InputWithLabel invalid={!!amount && !parsedAmount}> <InputWithLabel invalid={!!amount && !parsedAmount}>
<label> <label>
<Translate>Amount</Translate> <i18n.Translate>Amount</i18n.Translate>
</label> </label>
<div> <div>
<span>{currency}</span> <span>{currency}</span>
@ -187,7 +187,7 @@ export function CreateManualWithdraw({
disabled={!parsedAmount || !exchange} disabled={!parsedAmount || !exchange}
onClick={() => onCreate(exchange, parsedAmount!)} onClick={() => onCreate(exchange, parsedAmount!)}
> >
<Translate>Start withdrawal</Translate> <i18n.Translate>Start withdrawal</i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
</footer> </footer>
</Fragment> </Fragment>

View File

@ -19,7 +19,7 @@ import {
Amounts, Amounts,
AmountString, AmountString,
PaytoUri, PaytoUri,
Translate, i18n,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { DepositFee } from "@gnu-taler/taler-wallet-core/src/operations/deposits"; import { DepositFee } from "@gnu-taler/taler-wallet-core/src/operations/deposits";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
@ -135,7 +135,7 @@ export function View({
if (!balance) { if (!balance) {
return ( return (
<div> <div>
<Translate>no balance</Translate> <i18n.Translate>no balance</i18n.Translate>
</div> </div>
); );
} }
@ -143,10 +143,12 @@ export function View({
return ( return (
<WarningBox> <WarningBox>
<p> <p>
<Translate>There is no known bank account to send money to</Translate> <i18n.Translate>
There is no known bank account to send money to
</i18n.Translate>
</p> </p>
<ButtonBoxWarning> <ButtonBoxWarning>
<Translate>Withdraw</Translate> <i18n.Translate>Withdraw</i18n.Translate>
</ButtonBoxWarning> </ButtonBoxWarning>
</WarningBox> </WarningBox>
); );
@ -172,12 +174,12 @@ export function View({
return ( return (
<Fragment> <Fragment>
<h2> <h2>
<Translate>Send {currency} to your account</Translate> <i18n.Translate>Send {currency} to your account</i18n.Translate>
</h2> </h2>
<section> <section>
<Input> <Input>
<SelectList <SelectList
label={<Translate>Bank account IBAN number</Translate>} label={<i18n.Translate>Bank account IBAN number</i18n.Translate>}
list={accountMap} list={accountMap}
name="account" name="account"
value={String(accountIdx)} value={String(accountIdx)}
@ -186,7 +188,7 @@ export function View({
</Input> </Input>
<InputWithLabel invalid={!!error}> <InputWithLabel invalid={!!error}>
<label> <label>
<Translate>Amount</Translate> <i18n.Translate>Amount</i18n.Translate>
</label> </label>
<div> <div>
<span>{currency}</span> <span>{currency}</span>
@ -210,7 +212,7 @@ export function View({
<Fragment> <Fragment>
<InputWithLabel> <InputWithLabel>
<label> <label>
<Translate>Deposit fee</Translate> <i18n.Translate>Deposit fee</i18n.Translate>
</label> </label>
<div> <div>
<span>{currency}</span> <span>{currency}</span>
@ -224,7 +226,7 @@ export function View({
<InputWithLabel> <InputWithLabel>
<label> <label>
<Translate>Total deposit</Translate> <i18n.Translate>Total deposit</i18n.Translate>
</label> </label>
<div> <div>
<span>{currency}</span> <span>{currency}</span>
@ -242,13 +244,13 @@ export function View({
<div /> <div />
{unableToDeposit ? ( {unableToDeposit ? (
<ButtonPrimary disabled> <ButtonPrimary disabled>
<Translate>Deposit</Translate> <i18n.Translate>Deposit</i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
) : ( ) : (
<ButtonPrimary onClick={() => onSend(accountURI, amountStr)}> <ButtonPrimary onClick={() => onSend(accountURI, amountStr)}>
<Translate> <i18n.Translate>
Deposit {Amounts.stringifyValue(totalToDeposit)} {currency} Deposit {Amounts.stringifyValue(totalToDeposit)} {currency}
</Translate> </i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
)} )}
</footer> </footer>

View File

@ -85,10 +85,10 @@ export function View({
<Fragment> <Fragment>
<section> <section>
<h1> <h1>
<Translate>Review terms of service</Translate> <i18n.Translate>Review terms of service</i18n.Translate>
</h1> </h1>
<div> <div>
<Translate>Exchange URL</Translate>: <i18n.Translate>Exchange URL</i18n.Translate>:
<a href={url} target="_blank" rel="noreferrer"> <a href={url} target="_blank" rel="noreferrer">
{url} {url}
</a> </a>
@ -109,28 +109,28 @@ export function View({
<footer> <footer>
<Button onClick={onCancel}> <Button onClick={onCancel}>
<Translate>Cancel</Translate> <i18n.Translate>Cancel</i18n.Translate>
</Button> </Button>
{!terms && ( {!terms && (
<Button disabled> <Button disabled>
<Translate>Loading terms..</Translate> <i18n.Translate>Loading terms..</i18n.Translate>
</Button> </Button>
)} )}
{terms && ( {terms && (
<Fragment> <Fragment>
{needsReview && !reviewed && ( {needsReview && !reviewed && (
<ButtonSuccess disabled upperCased onClick={onConfirm}> <ButtonSuccess disabled upperCased onClick={onConfirm}>
<Translate>Add exchange</Translate> <i18n.Translate>Add exchange</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
)} )}
{(terms.status === "accepted" || (needsReview && reviewed)) && ( {(terms.status === "accepted" || (needsReview && reviewed)) && (
<ButtonSuccess upperCased onClick={onConfirm}> <ButtonSuccess upperCased onClick={onConfirm}>
<Translate>Add exchange</Translate> <i18n.Translate>Add exchange</i18n.Translate>
</ButtonSuccess> </ButtonSuccess>
)} )}
{terms.status === "notfound" && ( {terms.status === "notfound" && (
<ButtonWarning upperCased onClick={onConfirm}> <ButtonWarning upperCased onClick={onConfirm}>
<Translate>Add exchange anyway</Translate> <i18n.Translate>Add exchange anyway</i18n.Translate>
</ButtonWarning> </ButtonWarning>
)} )}
</Fragment> </Fragment>

View File

@ -93,42 +93,46 @@ export function ExchangeSetUrlPage({
<section> <section>
{!expectedCurrency ? ( {!expectedCurrency ? (
<h1> <h1>
<Translate>Add new exchange</Translate> <i18n.Translate>Add new exchange</i18n.Translate>
</h1> </h1>
) : ( ) : (
<h2> <h2>
<Translate>Add exchange for {expectedCurrency}</Translate> <i18n.Translate>Add exchange for {expectedCurrency}</i18n.Translate>
</h2> </h2>
)} )}
{!result && ( {!result && (
<LightText> <LightText>
<Translate>Enter the URL of an exchange you trust.</Translate> <i18n.Translate>
Enter the URL of an exchange you trust.
</i18n.Translate>
</LightText> </LightText>
)} )}
{result && ( {result && (
<LightText> <LightText>
<Translate> <i18n.Translate>
An exchange has been found! Review the information and click next An exchange has been found! Review the information and click next
</Translate> </i18n.Translate>
</LightText> </LightText>
)} )}
{result && expectedCurrency && expectedCurrency !== result.currency && ( {result && expectedCurrency && expectedCurrency !== result.currency && (
<WarningBox> <WarningBox>
<Translate> <i18n.Translate>
This exchange doesn't match the expected currency This exchange doesn't match the expected currency
<b>{expectedCurrency}</b> <b>{expectedCurrency}</b>
</Translate> </i18n.Translate>
</WarningBox> </WarningBox>
)} )}
{error && ( {error && (
<ErrorMessage <ErrorMessage
title={<Translate>Unable to verify this exchange</Translate>} title={
<i18n.Translate>Unable to verify this exchange</i18n.Translate>
}
description={error} description={error}
/> />
)} )}
{confirmationError && ( {confirmationError && (
<ErrorMessage <ErrorMessage
title={<Translate>Unable to add this exchange</Translate>} title={<i18n.Translate>Unable to add this exchange</i18n.Translate>}
description={confirmationError} description={confirmationError}
/> />
)} )}
@ -144,20 +148,20 @@ export function ExchangeSetUrlPage({
</Input> </Input>
{loading && ( {loading && (
<div> <div>
<Translate>loading</Translate>... <i18n.Translate>loading</i18n.Translate>...
</div> </div>
)} )}
{result && !loading && ( {result && !loading && (
<Fragment> <Fragment>
<Input> <Input>
<label> <label>
<Translate>Version</Translate> <i18n.Translate>Version</i18n.Translate>
</label> </label>
<input type="text" disabled value={result.version} /> <input type="text" disabled value={result.version} />
</Input> </Input>
<Input> <Input>
<label> <label>
<Translate>Currency</Translate> <i18n.Translate>Currency</i18n.Translate>
</label> </label>
<input type="text" disabled value={result.currency} /> <input type="text" disabled value={result.currency} />
</Input> </Input>
@ -167,7 +171,7 @@ export function ExchangeSetUrlPage({
</section> </section>
<footer> <footer>
<Button onClick={onCancel}> <Button onClick={onCancel}>
<Translate>Cancel</Translate> <i18n.Translate>Cancel</i18n.Translate>
</Button> </Button>
<ButtonPrimary <ButtonPrimary
disabled={ disabled={
@ -183,7 +187,7 @@ export function ExchangeSetUrlPage({
); );
}} }}
> >
<Translate>Next</Translate> <i18n.Translate>Next</i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
</footer> </footer>
</Fragment> </Fragment>

View File

@ -19,7 +19,7 @@ import {
Balance, Balance,
NotificationType, NotificationType,
Transaction, Transaction,
Translate, i18n,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
@ -67,7 +67,11 @@ export function HistoryPage({
if (transactionQuery.hasError) { if (transactionQuery.hasError) {
return ( return (
<LoadingError <LoadingError
title={<Translate>Could not load the list of transactions</Translate>} title={
<i18n.Translate>
Could not load the list of transactions
</i18n.Translate>
}
error={transactionQuery} error={transactionQuery}
/> />
); );
@ -194,14 +198,14 @@ export function HistoryView({
style={{ marginLeft: 0, marginTop: 8 }} style={{ marginLeft: 0, marginTop: 8 }}
onClick={() => goToWalletManualWithdraw(selectedCurrency)} onClick={() => goToWalletManualWithdraw(selectedCurrency)}
> >
<Translate>Withdraw</Translate> <i18n.Translate>Withdraw</i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
{currencyAmount && Amounts.isNonZero(currencyAmount) && ( {currencyAmount && Amounts.isNonZero(currencyAmount) && (
<ButtonBoxPrimary <ButtonBoxPrimary
style={{ marginLeft: 0, marginTop: 8 }} style={{ marginLeft: 0, marginTop: 8 }}
onClick={() => goToWalletDeposit(selectedCurrency)} onClick={() => goToWalletDeposit(selectedCurrency)}
> >
<Translate>Deposit</Translate> <i18n.Translate>Deposit</i18n.Translate>
</ButtonBoxPrimary> </ButtonBoxPrimary>
)} )}
</div> </div>
@ -209,7 +213,7 @@ export function HistoryView({
</section> </section>
{datesWithTransaction.length === 0 ? ( {datesWithTransaction.length === 0 ? (
<section> <section>
<Translate>There is no history for this currency</Translate> <i18n.Translate>There is no history for this currency</i18n.Translate>
</section> </section>
) : ( ) : (
<section> <section>

View File

@ -19,7 +19,7 @@ import {
AmountJson, AmountJson,
Amounts, Amounts,
NotificationType, NotificationType,
Translate, i18n,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { h, VNode } from "preact"; import { h, VNode } from "preact";
import { useState } from "preact/hooks"; import { useState } from "preact/hooks";
@ -97,7 +97,9 @@ export function ManualWithdrawPage({ currency, onCancel }: Props): VNode {
return ( return (
<LoadingError <LoadingError
title={ title={
<Translate>Could not load the list of known exchanges</Translate> <i18n.Translate>
Could not load the list of known exchanges
</i18n.Translate>
} }
error={state} error={state}
/> />

View File

@ -115,21 +115,27 @@ export function SetUrlView({
<Fragment> <Fragment>
<section> <section>
<h1> <h1>
<Translate>Add backup provider</Translate> <i18n.Translate>Add backup provider</i18n.Translate>
</h1> </h1>
{error && ( {error && (
<ErrorMessage <ErrorMessage
title={<Translate>Could not get provider information</Translate>} title={
<i18n.Translate>
Could not get provider information
</i18n.Translate>
}
description={error} description={error}
/> />
)} )}
<LightText> <LightText>
<Translate>Backup providers may charge for their service</Translate> <i18n.Translate>
Backup providers may charge for their service
</i18n.Translate>
</LightText> </LightText>
<p> <p>
<Input invalid={urlError}> <Input invalid={urlError}>
<label> <label>
<Translate>URL</Translate> <i18n.Translate>URL</i18n.Translate>
</label> </label>
<input <input
type="text" type="text"
@ -140,7 +146,7 @@ export function SetUrlView({
</Input> </Input>
<Input> <Input>
<label> <label>
<Translate>Name</Translate> <i18n.Translate>Name</i18n.Translate>
</label> </label>
<input <input
type="text" type="text"
@ -153,7 +159,7 @@ export function SetUrlView({
</section> </section>
<footer> <footer>
<Button onClick={onCancel}> <Button onClick={onCancel}>
&lt; <Translate>Back</Translate> &lt; <i18n.Translate>Back</i18n.Translate>
</Button> </Button>
<ButtonPrimary <ButtonPrimary
disabled={!value && !urlError} disabled={!value && !urlError}
@ -164,7 +170,7 @@ export function SetUrlView({
); );
}} }}
> >
<Translate>Next</Translate> <i18n.Translate>Next</i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
</footer> </footer>
</Fragment> </Fragment>
@ -189,40 +195,42 @@ export function ConfirmProviderView({
<Fragment> <Fragment>
<section> <section>
<h1> <h1>
<Translate>Review terms of service</Translate> <i18n.Translate>Review terms of service</i18n.Translate>
</h1> </h1>
<div> <div>
<Translate>Provider URL</Translate>:{" "} <i18n.Translate>Provider URL</i18n.Translate>:{" "}
<a href={url} target="_blank"> <a href={url} target="_blank">
{url} {url}
</a> </a>
</div> </div>
<SmallLightText> <SmallLightText>
<Translate> <i18n.Translate>
Please review and accept this provider's terms of service Please review and accept this provider's terms of service
</Translate> </i18n.Translate>
</SmallLightText> </SmallLightText>
<h2> <h2>
1. <Translate>Pricing</Translate> 1. <i18n.Translate>Pricing</i18n.Translate>
</h2> </h2>
<p> <p>
{Amounts.isZero(provider.annual_fee) ? ( {Amounts.isZero(provider.annual_fee) ? (
<Translate>free of charge</Translate> <i18n.Translate>free of charge</i18n.Translate>
) : ( ) : (
<Translate>{provider.annual_fee} per year of service</Translate> <i18n.Translate>
{provider.annual_fee} per year of service
</i18n.Translate>
)} )}
</p> </p>
<h2> <h2>
2. <Translate>Storage</Translate> 2. <i18n.Translate>Storage</i18n.Translate>
</h2> </h2>
<p> <p>
<Translate> <i18n.Translate>
{provider.storage_limit_in_megabytes} megabytes of storage per year {provider.storage_limit_in_megabytes} megabytes of storage per year
of service of service
</Translate> </i18n.Translate>
</p> </p>
<Checkbox <Checkbox
label={<Translate>Accept terms of service</Translate>} label={<i18n.Translate>Accept terms of service</i18n.Translate>}
name="terms" name="terms"
onToggle={() => setAccepted((old) => !old)} onToggle={() => setAccepted((old) => !old)}
enabled={accepted} enabled={accepted}
@ -230,10 +238,10 @@ export function ConfirmProviderView({
</section> </section>
<footer> <footer>
<Button onClick={onCancel}> <Button onClick={onCancel}>
&lt; <Translate>Back</Translate> &lt; <i18n.Translate>Back</i18n.Translate>
</Button> </Button>
<ButtonPrimary disabled={!accepted} onClick={onConfirm}> <ButtonPrimary disabled={!accepted} onClick={onConfirm}>
<Translate>Add provider</Translate> <i18n.Translate>Add provider</i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
</footer> </footer>
</Fragment> </Fragment>

View File

@ -14,7 +14,7 @@
TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/> TALER; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/ */
import { Translate } from "@gnu-taler/taler-util"; import { i18n } from "@gnu-taler/taler-util";
import { import {
ProviderInfo, ProviderInfo,
ProviderPaymentStatus, ProviderPaymentStatus,
@ -60,9 +60,9 @@ export function ProviderDetailPage({ pid: providerURL, onBack }: Props): VNode {
return ( return (
<LoadingError <LoadingError
title={ title={
<Translate> <i18n.Translate>
There was an error loading the provider detail for "{providerURL}" There was an error loading the provider detail for "{providerURL}"
</Translate> </i18n.Translate>
} }
error={state} error={state}
/> />
@ -105,12 +105,14 @@ export function ProviderView({
<Fragment> <Fragment>
<section> <section>
<p> <p>
<Translate>There is not known provider with url "{url}".</Translate> <i18n.Translate>
There is not known provider with url "{url}".
</i18n.Translate>
</p> </p>
</section> </section>
<footer> <footer>
<Button onClick={onBack}> <Button onClick={onBack}>
&lt; <Translate>Back</Translate> &lt; <i18n.Translate>Back</i18n.Translate>
</Button> </Button>
<div /> <div />
</footer> </footer>
@ -136,54 +138,54 @@ export function ProviderView({
<section> <section>
<p> <p>
<b> <b>
<Translate>Last backup</Translate>: <i18n.Translate>Last backup</i18n.Translate>:
</b>{" "} </b>{" "}
<Time timestamp={lb} format="dd MMMM yyyy" /> <Time timestamp={lb} format="dd MMMM yyyy" />
</p> </p>
<ButtonPrimary onClick={onSync}> <ButtonPrimary onClick={onSync}>
<Translate>Back up</Translate> <i18n.Translate>Back up</i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
{info.terms && ( {info.terms && (
<Fragment> <Fragment>
<p> <p>
<b> <b>
<Translate>Provider fee</Translate>: <i18n.Translate>Provider fee</i18n.Translate>:
</b>{" "} </b>{" "}
{info.terms && info.terms.annualFee}{" "} {info.terms && info.terms.annualFee}{" "}
<Translate>per year</Translate> <i18n.Translate>per year</i18n.Translate>
</p> </p>
</Fragment> </Fragment>
)} )}
<p>{descriptionByStatus(info.paymentStatus)}</p> <p>{descriptionByStatus(info.paymentStatus)}</p>
<ButtonPrimary disabled onClick={onExtend}> <ButtonPrimary disabled onClick={onExtend}>
<Translate>Extend</Translate> <i18n.Translate>Extend</i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
{info.paymentStatus.type === ProviderPaymentType.TermsChanged && ( {info.paymentStatus.type === ProviderPaymentType.TermsChanged && (
<div> <div>
<p> <p>
<Translate> <i18n.Translate>
terms has changed, extending the service will imply accepting terms has changed, extending the service will imply accepting
the new terms of service the new terms of service
</Translate> </i18n.Translate>
</p> </p>
<table> <table>
<thead> <thead>
<tr> <tr>
<td>&nbsp;</td> <td>&nbsp;</td>
<td> <td>
<Translate>old</Translate> <i18n.Translate>old</i18n.Translate>
</td> </td>
<td> -&gt;</td> <td> -&gt;</td>
<td> <td>
<Translate>new</Translate> <i18n.Translate>new</i18n.Translate>
</td> </td>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
<tr> <tr>
<td> <td>
<Translate>fee</Translate> <i18n.Translate>fee</i18n.Translate>
</td> </td>
<td>{info.paymentStatus.oldTerms.annualFee}</td> <td>{info.paymentStatus.oldTerms.annualFee}</td>
<td>-&gt;</td> <td>-&gt;</td>
@ -191,7 +193,7 @@ export function ProviderView({
</tr> </tr>
<tr> <tr>
<td> <td>
<Translate>storage</Translate> <i18n.Translate>storage</i18n.Translate>
</td> </td>
<td>{info.paymentStatus.oldTerms.storageLimitInMegabytes}</td> <td>{info.paymentStatus.oldTerms.storageLimitInMegabytes}</td>
<td>-&gt;</td> <td>-&gt;</td>
@ -204,11 +206,11 @@ export function ProviderView({
</section> </section>
<footer> <footer>
<Button onClick={onBack}> <Button onClick={onBack}>
&lt; <Translate>back</Translate> &lt; <i18n.Translate>back</i18n.Translate>
</Button> </Button>
<div> <div>
<ButtonDestructive onClick={onDelete}> <ButtonDestructive onClick={onDelete}>
<Translate>Remove provider</Translate> <i18n.Translate>Remove provider</i18n.Translate>
</ButtonDestructive> </ButtonDestructive>
</div> </div>
</footer> </footer>
@ -220,7 +222,9 @@ function Error({ info }: { info: ProviderInfo }): VNode {
if (info.lastError) { if (info.lastError) {
return ( return (
<ErrorMessage <ErrorMessage
title={<Translate>This provider has reported an error</Translate>} title={
<i18n.Translate>This provider has reported an error</i18n.Translate>
}
description={info.lastError.hint} description={info.lastError.hint}
/> />
); );
@ -232,26 +236,28 @@ function Error({ info }: { info: ProviderInfo }): VNode {
<ErrorMessage <ErrorMessage
title={ title={
<Fragment> <Fragment>
<Translate> <i18n.Translate>
There is conflict with another backup from{" "} There is conflict with another backup from{" "}
<b>{info.backupProblem.otherDeviceId}</b> <b>{info.backupProblem.otherDeviceId}</b>
</Translate> </i18n.Translate>
</Fragment> </Fragment>
} }
/> />
); );
case "backup-unreadable": case "backup-unreadable":
return ( return (
<ErrorMessage title={<Translate>Backup is not readable</Translate>} /> <ErrorMessage
title={<i18n.Translate>Backup is not readable</i18n.Translate>}
/>
); );
default: default:
return ( return (
<ErrorMessage <ErrorMessage
title={ title={
<Fragment> <Fragment>
<Translate> <i18n.Translate>
Unknown backup problem: {JSON.stringify(info.backupProblem)} Unknown backup problem: {JSON.stringify(info.backupProblem)}
</Translate> </i18n.Translate>
</Fragment> </Fragment>
} }
/> />
@ -268,14 +274,14 @@ function descriptionByStatus(status: ProviderPaymentStatus): VNode {
if (status.paidUntil.t_ms === "never") { if (status.paidUntil.t_ms === "never") {
return ( return (
<span> <span>
<Translate>service paid</Translate> <i18n.Translate>service paid</i18n.Translate>
</span> </span>
); );
} }
return ( return (
<Fragment> <Fragment>
<b> <b>
<Translate>Backup valid until</Translate>: <i18n.Translate>Backup valid until</i18n.Translate>:
</b>{" "} </b>{" "}
<Time timestamp={status.paidUntil} format="dd MMM yyyy" /> <Time timestamp={status.paidUntil} format="dd MMM yyyy" />
</Fragment> </Fragment>

View File

@ -1,9 +1,4 @@
import { import { AmountJson, parsePaytoUri, i18n } from "@gnu-taler/taler-util";
AmountJson,
Amounts,
parsePaytoUri,
Translate,
} from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType"; import { BankDetailsByPaytoType } from "../components/BankDetailsByPaytoType";
import { QR } from "../components/QR"; import { QR } from "../components/QR";
@ -29,7 +24,9 @@ export function ReserveCreated({
if (!paytoURI) { if (!paytoURI) {
return ( return (
<div> <div>
<Translate>could not parse payto uri from exchange {payto}</Translate> <i18n.Translate>
could not parse payto uri from exchange {payto}
</i18n.Translate>
</div> </div>
); );
} }
@ -37,13 +34,13 @@ export function ReserveCreated({
<Fragment> <Fragment>
<section> <section>
<h1> <h1>
<Translate>Exchange is ready for withdrawal</Translate> <i18n.Translate>Exchange is ready for withdrawal</i18n.Translate>
</h1> </h1>
<p> <p>
<Translate> <i18n.Translate>
To complete the process you need to wire To complete the process you need to wire
<b>{amountToString(amount)}</b> to the exchange bank account <b>{amountToString(amount)}</b> to the exchange bank account
</Translate> </i18n.Translate>
</p> </p>
<BankDetailsByPaytoType <BankDetailsByPaytoType
amount={amountToString(amount)} amount={amountToString(amount)}
@ -53,27 +50,27 @@ export function ReserveCreated({
/> />
<p> <p>
<WarningBox> <WarningBox>
<Translate> <i18n.Translate>
Make sure to use the correct subject, otherwise the money will not Make sure to use the correct subject, otherwise the money will not
arrive in this wallet. arrive in this wallet.
</Translate> </i18n.Translate>
</WarningBox> </WarningBox>
</p> </p>
</section> </section>
<section> <section>
<p> <p>
<Translate> <i18n.Translate>
Alternative, you can also scan this QR code or open Alternative, you can also scan this QR code or open
<a href={payto}>this link</a> if you have a banking app installed <a href={payto}>this link</a> if you have a banking app installed
that supports RFC 8905 that supports RFC 8905
</Translate> </i18n.Translate>
</p> </p>
<QR text={payto} /> <QR text={payto} />
</section> </section>
<footer> <footer>
<div /> <div />
<ButtonDestructive onClick={onCancel}> <ButtonDestructive onClick={onCancel}>
<Translate>Cancel withdrawal</Translate> <i18n.Translate>Cancel withdrawal</i18n.Translate>
</ButtonDestructive> </ButtonDestructive>
</footer> </footer>
</Fragment> </Fragment>

View File

@ -81,31 +81,31 @@ export function SettingsView({
<Fragment> <Fragment>
<section> <section>
<h2> <h2>
<Translate>Permissions</Translate> <i18n.Translate>Permissions</i18n.Translate>
</h2> </h2>
<Checkbox <Checkbox
label={ label={
<Translate> <i18n.Translate>
Automatically open wallet based on page content Automatically open wallet based on page content
</Translate> </i18n.Translate>
} }
name="perm" name="perm"
description={ description={
<Translate> <i18n.Translate>
Enabling this option below will make using the wallet faster, but Enabling this option below will make using the wallet faster, but
requires more permissions from your browser. requires more permissions from your browser.
</Translate> </i18n.Translate>
} }
enabled={permissionsEnabled} enabled={permissionsEnabled}
onToggle={togglePermissions} onToggle={togglePermissions}
/> />
<h2> <h2>
<Translate>Known exchanges</Translate> <i18n.Translate>Known exchanges</i18n.Translate>
</h2> </h2>
{!knownExchanges || !knownExchanges.length ? ( {!knownExchanges || !knownExchanges.length ? (
<div> <div>
<Translate>No exchange yet</Translate> <i18n.Translate>No exchange yet</i18n.Translate>
</div> </div>
) : ( ) : (
<Fragment> <Fragment>
@ -113,13 +113,13 @@ export function SettingsView({
<thead> <thead>
<tr> <tr>
<th> <th>
<Translate>Currency</Translate> <i18n.Translate>Currency</i18n.Translate>
</th> </th>
<th> <th>
<Translate>URL</Translate> <i18n.Translate>URL</i18n.Translate>
</th> </th>
<th> <th>
<Translate>Term of Service</Translate> <i18n.Translate>Term of Service</i18n.Translate>
</th> </th>
</tr> </tr>
</thead> </thead>
@ -135,20 +135,20 @@ export function SettingsView({
case "accepted": case "accepted":
return ( return (
<SuccessText> <SuccessText>
<Translate>ok</Translate> <i18n.Translate>ok</i18n.Translate>
</SuccessText> </SuccessText>
); );
case "changed": case "changed":
return ( return (
<WarningText> <WarningText>
<Translate>changed</Translate> <i18n.Translate>changed</i18n.Translate>
</WarningText> </WarningText>
); );
case "new": case "new":
case "notfound": case "notfound":
return ( return (
<DestructiveText> <DestructiveText>
<Translate>not accepted</Translate> <i18n.Translate>not accepted</i18n.Translate>
</DestructiveText> </DestructiveText>
); );
} }
@ -172,18 +172,18 @@ export function SettingsView({
<div style={{ display: "flex", justifyContent: "space-between" }}> <div style={{ display: "flex", justifyContent: "space-between" }}>
<div /> <div />
<LinkPrimary href={Pages.settings_exchange_add}> <LinkPrimary href={Pages.settings_exchange_add}>
<Translate>Add an exchange</Translate> <i18n.Translate>Add an exchange</i18n.Translate>
</LinkPrimary> </LinkPrimary>
</div> </div>
<h2>Config</h2> <h2>Config</h2>
<Checkbox <Checkbox
label={<Translate>Developer mode</Translate>} label={<i18n.Translate>Developer mode</i18n.Translate>}
name="devMode" name="devMode"
description={ description={
<Translate> <i18n.Translate>
(More options and information useful for debugging) (More options and information useful for debugging)
</Translate> </i18n.Translate>
} }
enabled={developerMode} enabled={developerMode}
onToggle={toggleDeveloperMode} onToggle={toggleDeveloperMode}

View File

@ -22,7 +22,6 @@ import {
parsePaytoUri, parsePaytoUri,
Transaction, Transaction,
TransactionType, TransactionType,
Translate,
WithdrawalType, WithdrawalType,
} from "@gnu-taler/taler-util"; } from "@gnu-taler/taler-util";
import { differenceInSeconds } from "date-fns"; import { differenceInSeconds } from "date-fns";
@ -77,7 +76,9 @@ export function TransactionPage({ tid, goToWalletHistory }: Props): VNode {
return ( return (
<LoadingError <LoadingError
title={ title={
<Translate>Could not load the transaction information</Translate> <i18n.Translate>
Could not load the transaction information
</i18n.Translate>
} }
error={state} error={state}
/> />
@ -142,15 +143,15 @@ export function TransactionView({
<section style={{ padding: 8, textAlign: "center" }}> <section style={{ padding: 8, textAlign: "center" }}>
<ErrorTalerOperation <ErrorTalerOperation
title={ title={
<Translate> <i18n.Translate>
There was an error trying to complete the transaction There was an error trying to complete the transaction
</Translate> </i18n.Translate>
} }
error={transaction?.error} error={transaction?.error}
/> />
{transaction.pending && ( {transaction.pending && (
<WarningBox> <WarningBox>
<Translate>This transaction is not completed</Translate> <i18n.Translate>This transaction is not completed</i18n.Translate>
</WarningBox> </WarningBox>
)} )}
</section> </section>
@ -159,16 +160,16 @@ export function TransactionView({
</section> </section>
<footer> <footer>
<Button onClick={onBack}> <Button onClick={onBack}>
&lt; <Translate> Back </Translate> &lt; <i18n.Translate> Back </i18n.Translate>
</Button> </Button>
<div> <div>
{showRetry ? ( {showRetry ? (
<ButtonPrimary onClick={onRetry}> <ButtonPrimary onClick={onRetry}>
<Translate>Retry</Translate> <i18n.Translate>Retry</i18n.Translate>
</ButtonPrimary> </ButtonPrimary>
) : null} ) : null}
<ButtonDestructive onClick={doCheckBeforeForget}> <ButtonDestructive onClick={doCheckBeforeForget}>
<Translate>Forget</Translate> <i18n.Translate>Forget</i18n.Translate>
</ButtonDestructive> </ButtonDestructive>
</div> </div>
</footer> </footer>
@ -193,28 +194,28 @@ export function TransactionView({
<Overlay> <Overlay>
<CenteredDialog> <CenteredDialog>
<header> <header>
<Translate>Caution!</Translate> <i18n.Translate>Caution!</i18n.Translate>
</header> </header>
<section> <section>
<Translate> <i18n.Translate>
If you have already wired money to the exchange you will loose If you have already wired money to the exchange you will loose
the chance to get the coins form it. the chance to get the coins form it.
</Translate> </i18n.Translate>
</section> </section>
<footer> <footer>
<Button onClick={() => setConfirmBeforeForget(false)}> <Button onClick={() => setConfirmBeforeForget(false)}>
<Translate>Cancel</Translate> <i18n.Translate>Cancel</i18n.Translate>
</Button> </Button>
<ButtonDestructive onClick={onDelete}> <ButtonDestructive onClick={onDelete}>
<Translate>Confirm</Translate> <i18n.Translate>Confirm</i18n.Translate>
</ButtonDestructive> </ButtonDestructive>
</footer> </footer>
</CenteredDialog> </CenteredDialog>
</Overlay> </Overlay>
) : undefined} ) : undefined}
<h2> <h2>
<Translate>Withdrawal</Translate> <i18n.Translate>Withdrawal</i18n.Translate>
</h2> </h2>
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" /> <Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
{transaction.pending ? ( {transaction.pending ? (
@ -231,21 +232,21 @@ export function TransactionView({
/> />
<p> <p>
<WarningBox> <WarningBox>
<Translate> <i18n.Translate>
Make sure to use the correct subject, otherwise the money Make sure to use the correct subject, otherwise the money
will not arrive in this wallet. will not arrive in this wallet.
</Translate> </i18n.Translate>
</WarningBox> </WarningBox>
</p> </p>
<Part <Part
big big
title={<Translate>Total withdrawn</Translate>} title={<i18n.Translate>Total withdrawn</i18n.Translate>}
text={amountToString(transaction.amountEffective)} text={amountToString(transaction.amountEffective)}
kind="positive" kind="positive"
/> />
<Part <Part
big big
title={<Translate>Exchange fee</Translate>} title={<i18n.Translate>Exchange fee</i18n.Translate>}
text={amountToString(fee)} text={amountToString(fee)}
kind="negative" kind="negative"
/> />
@ -255,38 +256,40 @@ export function TransactionView({
{!transaction.withdrawalDetails.confirmed && {!transaction.withdrawalDetails.confirmed &&
transaction.withdrawalDetails.bankConfirmationUrl ? ( transaction.withdrawalDetails.bankConfirmationUrl ? (
<InfoBox> <InfoBox>
<Translate> <i18n.Translate>
The bank is waiting for confirmation. Go to the The bank is waiting for confirmation. Go to the
<a <a
href={transaction.withdrawalDetails.bankConfirmationUrl} href={transaction.withdrawalDetails.bankConfirmationUrl}
target="_blank" target="_blank"
rel="noreferrer" rel="noreferrer"
> >
<Translate>bank site</Translate> <i18n.Translate>bank site</i18n.Translate>
</a> </a>
</Translate> </i18n.Translate>
</InfoBox> </InfoBox>
) : undefined} ) : undefined}
{transaction.withdrawalDetails.confirmed && ( {transaction.withdrawalDetails.confirmed && (
<InfoBox> <InfoBox>
<Translate>Waiting for the coins to arrive</Translate> <i18n.Translate>
Waiting for the coins to arrive
</i18n.Translate>
</InfoBox> </InfoBox>
)} )}
<Part <Part
big big
title={<Translate>Total withdrawn</Translate>} title={<i18n.Translate>Total withdrawn</i18n.Translate>}
text={amountToString(transaction.amountEffective)} text={amountToString(transaction.amountEffective)}
kind="positive" kind="positive"
/> />
<Part <Part
big big
title={<Translate>Chosen amount</Translate>} title={<i18n.Translate>Chosen amount</i18n.Translate>}
text={amountToString(transaction.amountRaw)} text={amountToString(transaction.amountRaw)}
kind="neutral" kind="neutral"
/> />
<Part <Part
big big
title={<Translate>Exchange fee</Translate>} title={<i18n.Translate>Exchange fee</i18n.Translate>}
text={amountToString(fee)} text={amountToString(fee)}
kind="negative" kind="negative"
/> />
@ -296,26 +299,26 @@ export function TransactionView({
<Fragment> <Fragment>
<Part <Part
big big
title={<Translate>Total withdrawn</Translate>} title={<i18n.Translate>Total withdrawn</i18n.Translate>}
text={amountToString(transaction.amountEffective)} text={amountToString(transaction.amountEffective)}
kind="positive" kind="positive"
/> />
<Part <Part
big big
title={<Translate>Chosen amount</Translate>} title={<i18n.Translate>Chosen amount</i18n.Translate>}
text={amountToString(transaction.amountRaw)} text={amountToString(transaction.amountRaw)}
kind="neutral" kind="neutral"
/> />
<Part <Part
big big
title={<Translate>Exchange fee</Translate>} title={<i18n.Translate>Exchange fee</i18n.Translate>}
text={amountToString(fee)} text={amountToString(fee)}
kind="negative" kind="negative"
/> />
</Fragment> </Fragment>
)} )}
<Part <Part
title={<Translate>Exchange</Translate>} title={<i18n.Translate>Exchange</i18n.Translate>}
text={new URL(transaction.exchangeBaseUrl).hostname} text={new URL(transaction.exchangeBaseUrl).hostname}
kind="neutral" kind="neutral"
/> />
@ -336,40 +339,40 @@ export function TransactionView({
return ( return (
<TransactionTemplate> <TransactionTemplate>
<h2> <h2>
<Translate>Payment</Translate> <i18n.Translate>Payment</i18n.Translate>
</h2> </h2>
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" /> <Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
<br /> <br />
<Part <Part
big big
title={<Translate>Total paid</Translate>} title={<i18n.Translate>Total paid</i18n.Translate>}
text={amountToString(transaction.amountEffective)} text={amountToString(transaction.amountEffective)}
kind="negative" kind="negative"
/> />
<Part <Part
big big
title={<Translate>Purchase amount</Translate>} title={<i18n.Translate>Purchase amount</i18n.Translate>}
text={amountToString(transaction.amountRaw)} text={amountToString(transaction.amountRaw)}
kind="neutral" kind="neutral"
/> />
<Part <Part
big big
title={<Translate>Fee</Translate>} title={<i18n.Translate>Fee</i18n.Translate>}
text={amountToString(fee)} text={amountToString(fee)}
kind="negative" kind="negative"
/> />
<Part <Part
title={<Translate>Merchant</Translate>} title={<i18n.Translate>Merchant</i18n.Translate>}
text={transaction.info.merchant.name} text={transaction.info.merchant.name}
kind="neutral" kind="neutral"
/> />
<Part <Part
title={<Translate>Purchase</Translate>} title={<i18n.Translate>Purchase</i18n.Translate>}
text={transaction.info.summary} text={transaction.info.summary}
kind="neutral" kind="neutral"
/> />
<Part <Part
title={<Translate>Receipt</Translate>} title={<i18n.Translate>Receipt</i18n.Translate>}
text={`#${transaction.info.orderId}`} text={`#${transaction.info.orderId}`}
kind="neutral" kind="neutral"
/> />
@ -407,25 +410,25 @@ export function TransactionView({
return ( return (
<TransactionTemplate> <TransactionTemplate>
<h2> <h2>
<Translate>Deposit</Translate> <i18n.Translate>Deposit</i18n.Translate>
</h2> </h2>
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" /> <Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
<br /> <br />
<Part <Part
big big
title={<Translate>Total send</Translate>} title={<i18n.Translate>Total send</i18n.Translate>}
text={amountToString(transaction.amountEffective)} text={amountToString(transaction.amountEffective)}
kind="neutral" kind="neutral"
/> />
<Part <Part
big big
title={<Translate>Deposit amount</Translate>} title={<i18n.Translate>Deposit amount</i18n.Translate>}
text={amountToString(transaction.amountRaw)} text={amountToString(transaction.amountRaw)}
kind="positive" kind="positive"
/> />
<Part <Part
big big
title={<Translate>Fee</Translate>} title={<i18n.Translate>Fee</i18n.Translate>}
text={amountToString(fee)} text={amountToString(fee)}
kind="negative" kind="negative"
/> />
@ -441,25 +444,25 @@ export function TransactionView({
return ( return (
<TransactionTemplate> <TransactionTemplate>
<h2> <h2>
<Translate>Refresh</Translate> <i18n.Translate>Refresh</i18n.Translate>
</h2> </h2>
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" /> <Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
<br /> <br />
<Part <Part
big big
title={<Translate>Total refresh</Translate>} title={<i18n.Translate>Total refresh</i18n.Translate>}
text={amountToString(transaction.amountEffective)} text={amountToString(transaction.amountEffective)}
kind="negative" kind="negative"
/> />
<Part <Part
big big
title={<Translate>Refresh amount</Translate>} title={<i18n.Translate>Refresh amount</i18n.Translate>}
text={amountToString(transaction.amountRaw)} text={amountToString(transaction.amountRaw)}
kind="neutral" kind="neutral"
/> />
<Part <Part
big big
title={<Translate>Fee</Translate>} title={<i18n.Translate>Fee</i18n.Translate>}
text={amountToString(fee)} text={amountToString(fee)}
kind="negative" kind="negative"
/> />
@ -475,25 +478,25 @@ export function TransactionView({
return ( return (
<TransactionTemplate> <TransactionTemplate>
<h2> <h2>
<Translate>Tip</Translate> <i18n.Translate>Tip</i18n.Translate>
</h2> </h2>
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" /> <Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
<br /> <br />
<Part <Part
big big
title={<Translate>Total tip</Translate>} title={<i18n.Translate>Total tip</i18n.Translate>}
text={amountToString(transaction.amountEffective)} text={amountToString(transaction.amountEffective)}
kind="positive" kind="positive"
/> />
<Part <Part
big big
title={<Translate>Received amount</Translate>} title={<i18n.Translate>Received amount</i18n.Translate>}
text={amountToString(transaction.amountRaw)} text={amountToString(transaction.amountRaw)}
kind="neutral" kind="neutral"
/> />
<Part <Part
big big
title={<Translate>Fee</Translate>} title={<i18n.Translate>Fee</i18n.Translate>}
text={amountToString(fee)} text={amountToString(fee)}
kind="negative" kind="negative"
/> />
@ -509,40 +512,40 @@ export function TransactionView({
return ( return (
<TransactionTemplate> <TransactionTemplate>
<h2> <h2>
<Translate>Refund</Translate> <i18n.Translate>Refund</i18n.Translate>
</h2> </h2>
<Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" /> <Time timestamp={transaction.timestamp} format="dd MMMM yyyy, HH:mm" />
<br /> <br />
<Part <Part
big big
title={<Translate>Total refund</Translate>} title={<i18n.Translate>Total refund</i18n.Translate>}
text={amountToString(transaction.amountEffective)} text={amountToString(transaction.amountEffective)}
kind="positive" kind="positive"
/> />
<Part <Part
big big
title={<Translate>Refund amount</Translate>} title={<i18n.Translate>Refund amount</i18n.Translate>}
text={amountToString(transaction.amountRaw)} text={amountToString(transaction.amountRaw)}
kind="neutral" kind="neutral"
/> />
<Part <Part
big big
title={<Translate>Fee</Translate>} title={<i18n.Translate>Fee</i18n.Translate>}
text={amountToString(fee)} text={amountToString(fee)}
kind="negative" kind="negative"
/> />
<Part <Part
title={<Translate>Merchant</Translate>} title={<i18n.Translate>Merchant</i18n.Translate>}
text={transaction.info.merchant.name} text={transaction.info.merchant.name}
kind="neutral" kind="neutral"
/> />
<Part <Part
title={<Translate>Purchase</Translate>} title={<i18n.Translate>Purchase</i18n.Translate>}
text={transaction.info.summary} text={transaction.info.summary}
kind="neutral" kind="neutral"
/> />
<Part <Part
title={<Translate>Receipt</Translate>} title={<i18n.Translate>Receipt</i18n.Translate>}
text={`#${transaction.info.orderId}`} text={`#${transaction.info.orderId}`}
kind="neutral" kind="neutral"
/> />

View File

@ -20,7 +20,7 @@
* @author sebasjm * @author sebasjm
*/ */
import { Translate, WalletDiagnostics } from "@gnu-taler/taler-util"; import { i18n, WalletDiagnostics } from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact"; import { Fragment, h, VNode } from "preact";
import { Checkbox } from "../components/Checkbox"; import { Checkbox } from "../components/Checkbox";
import { Diagnostics } from "../components/Diagnostics"; import { Diagnostics } from "../components/Diagnostics";
@ -55,40 +55,43 @@ export function View({
return ( return (
<Fragment> <Fragment>
<h1> <h1>
<Translate>Browser Extension Installed!</Translate> <i18n.Translate>Browser Extension Installed!</i18n.Translate>
</h1> </h1>
<div> <div>
<p> <p>
<Translate>Thank you for installing the wallet.</Translate> <i18n.Translate>Thank you for installing the wallet.</i18n.Translate>
</p> </p>
<Diagnostics diagnostics={diagnostics} timedOut={timedOut} /> <Diagnostics diagnostics={diagnostics} timedOut={timedOut} />
<h2> <h2>
<Translate>Permissions</Translate> <i18n.Translate>Permissions</i18n.Translate>
</h2> </h2>
<Checkbox <Checkbox
label={ label={
<Translate> <i18n.Translate>
Automatically open wallet based on page content Automatically open wallet based on page content
</Translate> </i18n.Translate>
} }
name="perm" name="perm"
description={ description={
<Translate> <i18n.Translate>
(Enabling this option below will make using the wallet faster, but (Enabling this option below will make using the wallet faster, but
requires more permissions from your browser.) requires more permissions from your browser.)
</Translate> </i18n.Translate>
} }
enabled={permissionsEnabled} enabled={permissionsEnabled}
onToggle={togglePermissions} onToggle={togglePermissions}
/> />
<h2> <h2>
<Translate>Next Steps</Translate> <i18n.Translate>Next Steps</i18n.Translate>
</h2> </h2>
<a href="https://demo.taler.net/" style={{ display: "block" }}> <a href="https://demo.taler.net/" style={{ display: "block" }}>
<Translate>Try the demo</Translate> » <i18n.Translate>Try the demo</i18n.Translate> »
</a> </a>
<a href="https://demo.taler.net/" style={{ display: "block" }}> <a href="https://demo.taler.net/" style={{ display: "block" }}>
<Translate>Learn how to top up your wallet balance</Translate> » <i18n.Translate>
Learn how to top up your wallet balance
</i18n.Translate>{" "}
»
</a> </a>
</div> </div>
</Fragment> </Fragment>

View File

@ -20,7 +20,7 @@
* @author sebasjm <dold@taler.net> * @author sebasjm <dold@taler.net>
*/ */
import { i18n, setupI18n, Translate } from "@gnu-taler/taler-util"; import { i18n, setupI18n } from "@gnu-taler/taler-util";
import { createHashHistory } from "history"; import { createHashHistory } from "history";
import { Fragment, h, render, VNode } from "preact"; import { Fragment, h, render, VNode } from "preact";
import Router, { route, Route } from "preact-router"; import Router, { route, Route } from "preact-router";
@ -169,9 +169,9 @@ function Application(): VNode {
onSuccess={(currency: string) => { onSuccess={(currency: string) => {
route(Pages.balance_history.replace(":currency", currency)); route(Pages.balance_history.replace(":currency", currency));
setGlobalNotification( setGlobalNotification(
<Translate> <i18n.Translate>
All done, your transaction is in progress All done, your transaction is in progress
</Translate>, </i18n.Translate>,
); );
}} }}
/> />