gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: add a taler action from the h


From: gnunet
Subject: [taler-wallet-core] branch master updated: add a taler action from the history page
Date: Tue, 30 Nov 2021 21:29:50 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 54d4a1ef add a taler action from the history page
54d4a1ef is described below

commit 54d4a1efe0a55a80ed594f14698da16dfded8c47
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Tue Nov 30 17:29:33 2021 -0300

    add a taler action from the history page
---
 .../src/popup/AddNewActionView.stories.tsx         | 33 +++++++++++
 .../src/popup/AddNewActionView.tsx                 | 68 ++++++++++++++++++++++
 .../src/popup/History.tsx                          | 57 ++++++++++++------
 .../src/popup/TalerActionFound.tsx                 | 48 +--------------
 .../taler-wallet-webextension/src/utils/index.ts   | 51 +++++++++++++++-
 .../src/wallet/History.stories.tsx                 |  5 ++
 .../src/wallet/History.tsx                         | 60 ++++++++++++-------
 7 files changed, 235 insertions(+), 87 deletions(-)

diff --git 
a/packages/taler-wallet-webextension/src/popup/AddNewActionView.stories.tsx 
b/packages/taler-wallet-webextension/src/popup/AddNewActionView.stories.tsx
new file mode 100644
index 00000000..6ee56ef7
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/popup/AddNewActionView.stories.tsx
@@ -0,0 +1,33 @@
+/*
+ This file is part of GNU Taler
+ (C) 2021 Taler Systems S.A.
+
+ GNU Taler is free software; you can redistribute it and/or modify it under the
+ terms of the GNU General Public License as published by the Free Software
+ Foundation; either version 3, or (at your option) any later version.
+
+ GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
+ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+ A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along with
+ GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
+ */
+
+/**
+ *
+ * @author Sebastian Javier Marchano (sebasjm)
+ */
+
+import { createExample } from "../test-utils";
+import { AddNewActionView as TestedComponent } from "./AddNewActionView";
+
+export default {
+  title: "popup/add new action",
+  component: TestedComponent,
+  argTypes: {
+    setDeviceName: () => Promise.resolve(),
+  },
+};
+
+export const Initial = createExample(TestedComponent, {});
diff --git a/packages/taler-wallet-webextension/src/popup/AddNewActionView.tsx 
b/packages/taler-wallet-webextension/src/popup/AddNewActionView.tsx
new file mode 100644
index 00000000..876b1a83
--- /dev/null
+++ b/packages/taler-wallet-webextension/src/popup/AddNewActionView.tsx
@@ -0,0 +1,68 @@
+import { classifyTalerUri, TalerUriType } from "@gnu-taler/taler-util";
+import { Fragment, h, VNode } from "preact";
+import { useState } from "preact/hooks";
+import {
+  Button,
+  ButtonSuccess,
+  InputWithLabel,
+} from "../components/styled/index";
+import { actionForTalerUri } from "../utils/index";
+
+export interface Props {
+  onCancel: () => void;
+}
+
+function buttonLabelByTalerType(type: TalerUriType): string {
+  switch (type) {
+    case TalerUriType.TalerNotifyReserve:
+      return "Open reserve page";
+    case TalerUriType.TalerPay:
+      return "Open pay page";
+    case TalerUriType.TalerRefund:
+      return "Open refund page";
+    case TalerUriType.TalerTip:
+      return "Open tip page";
+    case TalerUriType.TalerWithdraw:
+      return "Open withdraw page";
+  }
+  return "";
+}
+
+export function AddNewActionView({ onCancel }: Props): VNode {
+  const [url, setUrl] = useState("");
+  const uriType = classifyTalerUri(url);
+
+  return (
+    <Fragment>
+      <section>
+        <InputWithLabel
+          invalid={url !== "" && uriType === TalerUriType.Unknown}
+        >
+          <label>GNU Taler URI</label>
+          <div>
+            <input
+              style={{ width: "100%" }}
+              type="text"
+              value={url}
+              placeholder="taler://pay/...."
+              onInput={(e) => setUrl(e.currentTarget.value)}
+            />
+          </div>
+        </InputWithLabel>
+      </section>
+      <footer>
+        <Button onClick={onCancel}>Back</Button>
+        {uriType !== TalerUriType.Unknown && (
+          <ButtonSuccess
+            onClick={() => {
+              // eslint-disable-next-line no-undef
+              chrome.tabs.create({ url: actionForTalerUri(uriType, url) });
+            }}
+          >
+            {buttonLabelByTalerType(uriType)}
+          </ButtonSuccess>
+        )}
+      </footer>
+    </Fragment>
+  );
+}
diff --git a/packages/taler-wallet-webextension/src/popup/History.tsx 
b/packages/taler-wallet-webextension/src/popup/History.tsx
index b23b4781..f897299d 100644
--- a/packages/taler-wallet-webextension/src/popup/History.tsx
+++ b/packages/taler-wallet-webextension/src/popup/History.tsx
@@ -23,10 +23,11 @@ import {
 } from "@gnu-taler/taler-util";
 import { Fragment, h, VNode } from "preact";
 import { useEffect, useState } from "preact/hooks";
-import { PopupBox } from "../components/styled";
+import { ButtonPrimary } from "../components/styled/index";
 import { TransactionItem } from "../components/TransactionItem";
 import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
 import * as wxApi from "../wxApi";
+import { AddNewActionView } from "./AddNewActionView";
 
 export function HistoryPage(): VNode {
   const [transactions, setTransactions] = useState<
@@ -45,6 +46,12 @@ export function HistoryPage(): VNode {
     fetchData();
   }, []);
 
+  const [addingAction, setAddingAction] = useState(false);
+
+  if (addingAction) {
+    return <AddNewActionView onCancel={() => setAddingAction(false)} />;
+  }
+
   if (!transactions) {
     return <div>Loading ...</div>;
   }
@@ -53,6 +60,7 @@ export function HistoryPage(): VNode {
     <HistoryView
       balances={balanceWithoutError}
       list={[...transactions.transactions].reverse()}
+      onAddNewAction={() => setAddingAction(true)}
     />
   );
 }
@@ -65,31 +73,42 @@ function amountToString(c: AmountString): string {
 export function HistoryView({
   list,
   balances,
+  onAddNewAction,
 }: {
   list: Transaction[];
   balances: Balance[];
+  onAddNewAction: () => void;
 }): VNode {
   const multiCurrency = balances.length > 1;
   return (
     <Fragment>
-      {balances.length > 0 && (
-        <header>
-          {multiCurrency ? (
-            <div class="title">
-              Balance:{" "}
-              <ul style={{ margin: 0 }}>
-                {balances.map((b, i) => (
-                  <li key={i}>{b.available}</li>
-                ))}
-              </ul>
-            </div>
-          ) : (
-            <div class="title">
-              Balance: <span>{amountToString(balances[0].available)}</span>
-            </div>
-          )}
-        </header>
-      )}
+      <header>
+        {balances.length > 0 ? (
+          <Fragment>
+            {multiCurrency ? (
+              <div class="title">
+                Balance:{" "}
+                <ul style={{ margin: 0 }}>
+                  {balances.map((b, i) => (
+                    <li key={i}>{b.available}</li>
+                  ))}
+                </ul>
+              </div>
+            ) : (
+              <div class="title">
+                Balance: <span>{amountToString(balances[0].available)}</span>
+              </div>
+            )}
+          </Fragment>
+        ) : (
+          <div />
+        )}
+        <div>
+          <ButtonPrimary onClick={onAddNewAction}>
+            <b>+</b>
+          </ButtonPrimary>
+        </div>
+      </header>
       {list.length === 0 ? (
         <section data-expanded data-centered>
           <p>
diff --git a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx 
b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx
index b2220e37..40e9111f 100644
--- a/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx
+++ b/packages/taler-wallet-webextension/src/popup/TalerActionFound.tsx
@@ -22,6 +22,7 @@
 import { classifyTalerUri, TalerUriType } from "@gnu-taler/taler-util";
 import { Fragment, h } from "preact";
 import { ButtonPrimary, ButtonSuccess } from "../components/styled/index";
+import { actionForTalerUri } from "../utils/index";
 
 export interface Props {
   url: string;
@@ -108,50 +109,3 @@ export function TalerActionFound({ url, onDismiss }: 
Props) {
     </Fragment>
   );
 }
-
-function actionForTalerUri(
-  uriType: TalerUriType,
-  talerUri: string,
-): string | undefined {
-  switch (uriType) {
-    case TalerUriType.TalerWithdraw:
-      return makeExtensionUrlWithParams("static/wallet.html#/withdraw", {
-        talerWithdrawUri: talerUri,
-      });
-    case TalerUriType.TalerPay:
-      return makeExtensionUrlWithParams("static/wallet.html#/pay", {
-        talerPayUri: talerUri,
-      });
-    case TalerUriType.TalerTip:
-      return makeExtensionUrlWithParams("static/wallet.html#/tip", {
-        talerTipUri: talerUri,
-      });
-    case TalerUriType.TalerRefund:
-      return makeExtensionUrlWithParams("static/wallet.html#/refund", {
-        talerRefundUri: talerUri,
-      });
-    case TalerUriType.TalerNotifyReserve:
-      // FIXME: implement
-      break;
-    default:
-      console.warn(
-        "Response with HTTP 402 has Taler header, but header value is not a 
taler:// URI.",
-      );
-      break;
-  }
-  return undefined;
-}
-
-function makeExtensionUrlWithParams(
-  url: string,
-  params?: { [name: string]: string | undefined },
-): string {
-  const innerUrl = new URL(chrome.extension.getURL("/" + url));
-  if (params) {
-    const hParams = Object.keys(params)
-      .map((k) => `${k}=${params[k]}`)
-      .join("&");
-    innerUrl.hash = innerUrl.hash + "?" + hParams;
-  }
-  return innerUrl.href;
-}
diff --git a/packages/taler-wallet-webextension/src/utils/index.ts 
b/packages/taler-wallet-webextension/src/utils/index.ts
index 15081f92..8eb89d58 100644
--- a/packages/taler-wallet-webextension/src/utils/index.ts
+++ b/packages/taler-wallet-webextension/src/utils/index.ts
@@ -14,7 +14,7 @@
  GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
  */
 
-import { AmountJson, Amounts, GetExchangeTosResult } from 
"@gnu-taler/taler-util";
+import { AmountJson, Amounts, GetExchangeTosResult, TalerUriType } from 
"@gnu-taler/taler-util";
 
 
 function getJsonIfOk(r: Response): Promise<any> {
@@ -164,3 +164,52 @@ export function amountToString(text: AmountJson): string {
   return `${amount} ${aj.currency}`;
 }
 
+export function actionForTalerUri(
+  uriType: TalerUriType,
+  talerUri: string,
+): string | undefined {
+  switch (uriType) {
+    case TalerUriType.TalerWithdraw:
+      return makeExtensionUrlWithParams("static/wallet.html#/withdraw", {
+        talerWithdrawUri: talerUri,
+      });
+    case TalerUriType.TalerPay:
+      return makeExtensionUrlWithParams("static/wallet.html#/pay", {
+        talerPayUri: talerUri,
+      });
+    case TalerUriType.TalerTip:
+      return makeExtensionUrlWithParams("static/wallet.html#/tip", {
+        talerTipUri: talerUri,
+      });
+    case TalerUriType.TalerRefund:
+      return makeExtensionUrlWithParams("static/wallet.html#/refund", {
+        talerRefundUri: talerUri,
+      });
+    case TalerUriType.TalerNotifyReserve:
+      // FIXME: implement
+      break;
+    default:
+      console.warn(
+        "Response with HTTP 402 has Taler header, but header value is not a 
taler:// URI.",
+      );
+      break;
+  }
+  return undefined;
+}
+
+function makeExtensionUrlWithParams(
+  url: string,
+  params?: { [name: string]: string | undefined },
+): string {
+  // eslint-disable-next-line no-undef
+  const innerUrl = new URL(chrome.extension.getURL("/" + url));
+  if (params) {
+    const hParams = Object.keys(params)
+      .map((k) => `${k}=${params[k]}`)
+      .join("&");
+    innerUrl.hash = innerUrl.hash + "?" + hParams;
+  }
+  return innerUrl.href;
+}
+
+
diff --git a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx 
b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx
index 0f471ac3..ce4b0fb7 100644
--- a/packages/taler-wallet-webextension/src/wallet/History.stories.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/History.stories.tsx
@@ -127,6 +127,11 @@ export const Empty = createExample(TestedComponent, {
   ],
 });
 
+export const EmptyWithNoBalance = createExample(TestedComponent, {
+  list: [],
+  balances: [],
+});
+
 export const One = createExample(TestedComponent, {
   list: [exampleData.withdraw],
   balances: [
diff --git a/packages/taler-wallet-webextension/src/wallet/History.tsx 
b/packages/taler-wallet-webextension/src/wallet/History.tsx
index bc8ef734..58db0360 100644
--- a/packages/taler-wallet-webextension/src/wallet/History.tsx
+++ b/packages/taler-wallet-webextension/src/wallet/History.tsx
@@ -21,10 +21,12 @@ import {
   Transaction,
 } from "@gnu-taler/taler-util";
 import { Fragment, h, VNode } from "preact";
-import { DateSeparator } from "../components/styled";
+import { useState } from "preact/hooks";
+import { ButtonPrimary, DateSeparator } from "../components/styled";
 import { Time } from "../components/Time";
 import { TransactionItem } from "../components/TransactionItem";
 import { useAsyncAsHook } from "../hooks/useAsyncAsHook";
+import { AddNewActionView } from "../popup/AddNewActionView";
 import * as wxApi from "../wxApi";
 
 export function HistoryPage(): VNode {
@@ -37,6 +39,12 @@ export function HistoryPage(): VNode {
     NotificationType.WithdrawGroupFinished,
   ]);
 
+  const [addingAction, setAddingAction] = useState(false);
+
+  if (addingAction) {
+    return <AddNewActionView onCancel={() => setAddingAction(false)} />;
+  }
+
   if (!transactionQuery) {
     return <div>Loading ...</div>;
   }
@@ -48,6 +56,7 @@ export function HistoryPage(): VNode {
     <HistoryView
       balances={balanceWithoutError}
       list={[...transactionQuery.response.transactions].reverse()}
+      onAddNewAction={() => setAddingAction(true)}
     />
   );
 }
@@ -65,9 +74,11 @@ function normalizeToDay(x: number): number {
 export function HistoryView({
   list,
   balances,
+  onAddNewAction,
 }: {
   list: Transaction[];
   balances: Balance[];
+  onAddNewAction: () => void;
 }): VNode {
   const byDate = list.reduce((rv, x) => {
     const theDate =
@@ -83,25 +94,34 @@ export function HistoryView({
 
   return (
     <Fragment>
-      {balances.length > 0 && (
-        <header>
-          {balances.length === 1 && (
-            <div class="title">
-              Balance: <span>{amountToString(balances[0].available)}</span>
-            </div>
-          )}
-          {balances.length > 1 && (
-            <div class="title">
-              Balance:{" "}
-              <ul style={{ margin: 0 }}>
-                {balances.map((b, i) => (
-                  <li key={i}>{b.available}</li>
-                ))}
-              </ul>
-            </div>
-          )}
-        </header>
-      )}
+      <header>
+        {balances.length > 0 ? (
+          <Fragment>
+            {balances.length === 1 && (
+              <div class="title">
+                Balance: <span>{amountToString(balances[0].available)}</span>
+              </div>
+            )}
+            {balances.length > 1 && (
+              <div class="title">
+                Balance:{" "}
+                <ul style={{ margin: 0 }}>
+                  {balances.map((b, i) => (
+                    <li key={i}>{b.available}</li>
+                  ))}
+                </ul>
+              </div>
+            )}
+          </Fragment>
+        ) : (
+          <div />
+        )}
+        <div>
+          <ButtonPrimary onClick={onAddNewAction}>
+            <b>+</b>
+          </ButtonPrimary>
+        </div>
+      </header>
       <section>
         {Object.keys(byDate).map((d, i) => {
           return (

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]