aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2022-08-15 23:01:05 -0300
committerSebastian <sebasjm@gmail.com>2022-08-15 23:01:05 -0300
commitfb8372dfbf27b7b4e8b2fe4f81aa2ba18bfcf638 (patch)
tree604fca93fdb0ff3ac21803941a49e073011da56c
parent0798aa5cedad2a599829f2b13d4573c64a081c29 (diff)
default exchange and select currency
-rw-r--r--packages/taler-wallet-webextension/src/mui/Modal.tsx38
-rw-r--r--packages/taler-wallet-webextension/src/mui/ModalManager.ts16
-rw-r--r--packages/taler-wallet-webextension/src/mui/Popover.tsx18
-rw-r--r--packages/taler-wallet-webextension/src/mui/Portal.tsx65
-rw-r--r--packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx135
5 files changed, 207 insertions, 65 deletions
diff --git a/packages/taler-wallet-webextension/src/mui/Modal.tsx b/packages/taler-wallet-webextension/src/mui/Modal.tsx
index 5a30bcf26..b24a45d61 100644
--- a/packages/taler-wallet-webextension/src/mui/Modal.tsx
+++ b/packages/taler-wallet-webextension/src/mui/Modal.tsx
@@ -1,9 +1,25 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
import { css } from "@linaria/core";
import { h, JSX, VNode, ComponentChildren } from "preact";
import { useCallback, useEffect, useRef, useState } from "preact/hooks";
// eslint-disable-next-line import/extensions
import { alpha } from "./colors/manipulation";
-import { ModalManager } from "./ModalManager";
+import { ModalManager } from "./ModalManager.js";
import { Portal } from "./Portal.js";
// eslint-disable-next-line import/extensions
import { theme } from "./style";
@@ -22,12 +38,16 @@ interface Props {
children: ComponentChildren;
open?: boolean;
exited?: boolean;
- container?: HTMLElement;
+ container?: VNode;
}
const defaultManager = new ModalManager();
const manager = defaultManager;
+function getModal(): any {
+ return null; //TODO: fix
+}
+
export function Modal({
open,
// exited,
@@ -52,18 +72,18 @@ export function Modal({
return;
}
- if (open && isTopModal()) {
- handleMounted();
- } else {
- ariaHidden(modalRef.current, true);
- }
+ // if (open && isTopModal()) {
+ // handleMounted();
+ // } else {
+ // ariaHidden(modalRef.current, true);
+ // }
});
return (
<Portal
ref={handlePortalRef}
container={container}
- disablePortal={disablePortal}
+ // disablePortal={disablePortal}
>
<div
class={[_class, baseStyle].join(" ")}
@@ -105,7 +125,7 @@ function getOffsetLeft(rect: any, horizontal: any): number {
return offset;
}
-function getTransformOriginValue(transformOrigin): string {
+function getTransformOriginValue(transformOrigin: any): string {
return [transformOrigin.horizontal, transformOrigin.vertical]
.map((n) => (typeof n === "number" ? `${n}px` : n))
.join(" ");
diff --git a/packages/taler-wallet-webextension/src/mui/ModalManager.ts b/packages/taler-wallet-webextension/src/mui/ModalManager.ts
index 2894ffa7a..b4a3ee597 100644
--- a/packages/taler-wallet-webextension/src/mui/ModalManager.ts
+++ b/packages/taler-wallet-webextension/src/mui/ModalManager.ts
@@ -1,3 +1,19 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
////////////////////
function ownerDocument(node: Node | null | undefined): Document {
return (node && node.ownerDocument) || document;
diff --git a/packages/taler-wallet-webextension/src/mui/Popover.tsx b/packages/taler-wallet-webextension/src/mui/Popover.tsx
index 408f87987..69e0ab10a 100644
--- a/packages/taler-wallet-webextension/src/mui/Popover.tsx
+++ b/packages/taler-wallet-webextension/src/mui/Popover.tsx
@@ -1,3 +1,19 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
import { css } from "@linaria/core";
import { h, JSX, VNode, ComponentChildren } from "preact";
// eslint-disable-next-line import/extensions
@@ -48,7 +64,7 @@ function getOffsetLeft(rect: any, horizontal: any): number {
return offset;
}
-function getTransformOriginValue(transformOrigin): string {
+function getTransformOriginValue(transformOrigin: any): string {
return [transformOrigin.horizontal, transformOrigin.vertical]
.map((n) => (typeof n === "number" ? `${n}px` : n))
.join(" ");
diff --git a/packages/taler-wallet-webextension/src/mui/Portal.tsx b/packages/taler-wallet-webextension/src/mui/Portal.tsx
index 828a574fd..f9be021f0 100644
--- a/packages/taler-wallet-webextension/src/mui/Portal.tsx
+++ b/packages/taler-wallet-webextension/src/mui/Portal.tsx
@@ -1,3 +1,19 @@
+/*
+ This file is part of GNU Taler
+ (C) 2022 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE. See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
+ */
+
import { css } from "@linaria/core";
import { createPortal, forwardRef } from "preact/compat";
import {
@@ -26,7 +42,7 @@ const baseStyle = css`
`;
interface Props {
- class: string;
+ // class: string;
children: ComponentChildren;
disablePortal?: boolean;
container?: VNode;
@@ -39,10 +55,11 @@ export const Portal = forwardRef(function Portal(
const [mountNode, setMountNode] = useState<HTMLElement | undefined>(
undefined,
);
- const handleRef = useForkRef(
- isValidElement(children) ? children.ref : null,
- ref,
- );
+ const handleRef = null;
+ // useForkRef(
+ // isValidElement(children) ? children.ref : null,
+ // ref,
+ // );
useEffect(() => {
if (!disablePortal) {
@@ -81,25 +98,25 @@ function getContainer(container: any): any {
return typeof container === "function" ? container() : container;
}
-function useForkRef<Instance>(
- refA: React.Ref<Instance> | null | undefined,
- refB: React.Ref<Instance> | null | undefined,
-): React.Ref<Instance> | null {
- /**
- * This will create a new function if the ref props change and are defined.
- * This means react will call the old forkRef with `null` and the new forkRef
- * with the ref. Cleanup naturally emerges from this behavior.
- */
- return useMemo(() => {
- if (refA == null && refB == null) {
- return null;
- }
- return (refValue) => {
- setRef(refA, refValue);
- setRef(refB, refValue);
- };
- }, [refA, refB]);
-}
+// function useForkRef<Instance>(
+// refA: React.Ref<Instance> | null | undefined,
+// refB: React.Ref<Instance> | null | undefined,
+// ): React.Ref<Instance> | null {
+// /**
+// * This will create a new function if the ref props change and are defined.
+// * This means react will call the old forkRef with `null` and the new forkRef
+// * with the ref. Cleanup naturally emerges from this behavior.
+// */
+// return useMemo(() => {
+// if (refA == null && refB == null) {
+// return null;
+// }
+// return (refValue) => {
+// setRef(refA, refValue);
+// setRef(refB, refValue);
+// };
+// }, [refA, refB]);
+// }
function setRef<T>(
ref: RefObject<T | null> | ((instance: T | null) => void) | null | undefined,
diff --git a/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx b/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx
index 5f9c5065c..ba5dcf1da 100644
--- a/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/DestinationSelection.tsx
@@ -18,18 +18,29 @@ import { Amounts } from "@gnu-taler/taler-util";
import { styled } from "@linaria/react";
import { Fragment, h, VNode } from "preact";
import { useState } from "preact/hooks";
+import { ErrorMessage } from "../components/ErrorMessage.js";
+import { Loading } from "../components/Loading.js";
+import { LoadingError } from "../components/LoadingError.js";
+import { SelectList } from "../components/SelectList.js";
import {
+ Input,
InputWithLabel,
LightText,
+ LinkPrimary,
+ SubTitle,
SvgIcon,
} from "../components/styled/index.js";
import { useTranslationContext } from "../context/translation.js";
+import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
+import { Alert } from "../mui/Alert.js";
import { Button } from "../mui/Button.js";
import { Grid } from "../mui/Grid.js";
import { Paper } from "../mui/Paper.js";
import { TextField } from "../mui/TextField.js";
+import { Pages } from "../NavigationBar.js";
import arrowIcon from "../svg/chevron-down.svg";
import bankIcon from "../svg/ri-bank-line.svg";
+import * as wxApi from "../wxApi.js";
const Container = styled.div`
display: flex;
@@ -152,6 +163,57 @@ const CircleDiv = styled.div`
border: none;
`;
+export function SelectCurrency({
+ onChange,
+}: {
+ onChange: (s: string) => void;
+}): VNode {
+ const { i18n } = useTranslationContext();
+
+ const hook = useAsyncAsHook(wxApi.listExchanges);
+
+ if (!hook) {
+ return <Loading />;
+ }
+ if (hook.hasError) {
+ return (
+ <LoadingError
+ error={hook}
+ title={<i18n.Translate>Could not load list of exchange</i18n.Translate>}
+ />
+ );
+ }
+ const list: Record<string, string> = {};
+ hook.response.exchanges.forEach((e) => (list[e.currency] = e.currency));
+ list[""] = "Select a currency";
+ return (
+ <Fragment>
+ <h1>
+ <i18n.Translate>Specify the amount and the origin</i18n.Translate>
+ </h1>
+
+ <Alert severity="warning">
+ Choose a currency to proceed or add more exchanges in the settings tab
+ </Alert>
+ <Input>
+ <SelectList
+ label={<i18n.Translate>Known currencies</i18n.Translate>}
+ list={list}
+ name="lang"
+ value={""}
+ onChange={(v) => onChange(v)}
+ />
+ </Input>
+ <div style={{ display: "flex", justifyContent: "space-between" }}>
+ <div />
+ <LinkPrimary href={Pages.settingsExchangeAdd({})}>
+ <i18n.Translate>Add an exchange</i18n.Translate>
+ </LinkPrimary>
+ </div>
+ </Fragment>
+ );
+}
+
function RowExample({
info,
disabled,
@@ -194,9 +256,9 @@ export function DestinationSelectionGetCash({
? undefined
: Amounts.parse(initialAmount);
const parsedInitialAmountValue = !parsedInitialAmount
- ? ""
+ ? "0"
: Amounts.stringifyValue(parsedInitialAmount);
- const currency = parsedInitialAmount?.currency;
+ const [currency, setCurrency] = useState(parsedInitialAmount?.currency);
const [amount, setAmount] = useState(parsedInitialAmountValue);
const { i18n } = useTranslationContext();
@@ -220,7 +282,11 @@ export function DestinationSelectionGetCash({
];
if (!currency) {
- return <div>currency not provided</div>;
+ return (
+ <div>
+ <SelectCurrency onChange={(c) => setCurrency(c)} />
+ </div>
+ );
}
const currencyAndAmount = `${currency}:${amount}`;
const parsedAmount = Amounts.parse(currencyAndAmount);
@@ -231,20 +297,25 @@ export function DestinationSelectionGetCash({
<h1>
<i18n.Translate>Specify the amount and the origin</i18n.Translate>
</h1>
- <TextField
- label="Amount"
- type="number"
- variant="filled"
- error={invalid}
- required
- startAdornment={
- <div style={{ padding: "25px 12px 8px 12px" }}>{currency}</div>
- }
- value={amount}
- onChange={(e) => {
- setAmount(e);
- }}
- />
+ <Grid container columns={2} justifyContent="space-between">
+ <TextField
+ label="Amount"
+ type="number"
+ variant="filled"
+ error={invalid}
+ required
+ startAdornment={
+ <div style={{ padding: "25px 12px 8px 12px" }}>{currency}</div>
+ }
+ value={amount}
+ onChange={(e) => {
+ setAmount(e);
+ }}
+ />
+ <Button onClick={async () => setCurrency(undefined)}>
+ Change currency
+ </Button>
+ </Grid>
<Grid container spacing={1} columns={1}>
{previous2.length > 0 ? (
@@ -350,20 +421,22 @@ export function DestinationSelectionSendCash({
<i18n.Translate>Specify the amount and the destination</i18n.Translate>
</h1>
- <TextField
- label="Amount"
- type="number"
- variant="filled"
- required
- error={invalid}
- startAdornment={
- <div style={{ padding: "25px 12px 8px 12px" }}>{currency}</div>
- }
- value={amount}
- onChange={(e) => {
- setAmount(e);
- }}
- />
+ <div>
+ <TextField
+ label="Amount"
+ type="number"
+ variant="filled"
+ required
+ error={invalid}
+ startAdornment={
+ <div style={{ padding: "25px 12px 8px 12px" }}>{currency}</div>
+ }
+ value={amount}
+ onChange={(e) => {
+ setAmount(e);
+ }}
+ />
+ </div>
<Grid container spacing={1} columns={1}>
{previous2.length > 0 ? (