gnunet-svn
[Top][All Lists]
Advanced

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

[taler-wallet-core] 01/02: find taler action in clipboard and withdraw w


From: gnunet
Subject: [taler-wallet-core] 01/02: find taler action in clipboard and withdraw with mobile
Date: Sun, 11 Sep 2022 04:23:11 +0200

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

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

commit dda90b51f6fc6fca48a68bc53088e1ed3f018a21
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Fri Sep 9 12:22:26 2022 -0300

    find taler action in clipboard and withdraw with mobile
---
 .../src/context/iocContext.ts                      |  7 +-
 .../src/cta/InvoiceCreate/views.tsx                |  4 +-
 .../src/cta/Withdraw/index.ts                      |  1 +
 .../src/cta/Withdraw/state.ts                      |  1 +
 .../src/cta/Withdraw/views.tsx                     | 94 +++++++++++++++-------
 .../src/hooks/useTalerActionURL.ts                 | 29 +++++--
 .../taler-wallet-webextension/src/platform/api.ts  | 17 +++-
 .../src/platform/chrome.ts                         |  6 ++
 .../taler-wallet-webextension/src/platform/dev.ts  |  1 +
 .../src/popup/Application.tsx                      | 10 ++-
 10 files changed, 127 insertions(+), 43 deletions(-)

diff --git a/packages/taler-wallet-webextension/src/context/iocContext.ts 
b/packages/taler-wallet-webextension/src/context/iocContext.ts
index b1a9aa12..c7fee0bc 100644
--- a/packages/taler-wallet-webextension/src/context/iocContext.ts
+++ b/packages/taler-wallet-webextension/src/context/iocContext.ts
@@ -25,9 +25,11 @@ import { platform } from "../platform/api.js";
 
 interface Type {
   findTalerUriInActiveTab: () => Promise<string | undefined>;
+  findTalerUriInClipboard: () => Promise<string | undefined>;
 }
 const Context = createContext<Type>({
   findTalerUriInActiveTab: async () => undefined,
+  findTalerUriInClipboard: async () => undefined,
 });
 
 /**
@@ -56,7 +58,10 @@ export const IoCProviderForRuntime = ({
   children: any;
 }): VNode => {
   return h(Context.Provider, {
-    value: { findTalerUriInActiveTab: platform.findTalerUriInActiveTab },
+    value: {
+      findTalerUriInActiveTab: platform.findTalerUriInActiveTab,
+      findTalerUriInClipboard: platform.findTalerUriInClipboard,
+    },
     children,
   });
 };
diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx 
b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx
index d3d2c68e..18e59328 100644
--- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx
@@ -122,13 +122,13 @@ export function ReadyView({
               }}
             >
               <i18n.Translate>Exchange</i18n.Translate>
-              <Link>
+              {/* <Link>
                 <SvgIcon
                   title="Edit"
                   dangerouslySetInnerHTML={{ __html: editIcon }}
                   color="black"
                 />
-              </Link>
+              </Link> */}
             </div>
           }
           text={<ExchangeDetails exchange={exchangeUrl} />}
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts 
b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
index 7425dbd2..7bd66726 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts
@@ -85,6 +85,7 @@ export namespace State {
 
     ageRestriction?: SelectFieldHandler;
 
+    talerWithdrawUri?: string;
     cancel: () => Promise<void>;
   };
 }
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts 
b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
index 015c9aac..0d2e150e 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts
@@ -410,6 +410,7 @@ export function useComponentStateFromURI(
     toBeReceived,
     withdrawalFee,
     chosenAmount,
+    talerWithdrawUri,
     ageRestriction,
     doWithdrawal: {
       onClick:
diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx 
b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
index 850bd6e8..44058634 100644
--- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
+++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx
@@ -23,6 +23,7 @@ import { SelectList } from "../../components/SelectList.js";
 import {
   Input,
   Link,
+  LinkSuccess,
   SubTitle,
   SuccessBox,
   SvgIcon,
@@ -35,6 +36,8 @@ import { TermsOfServiceSection } from 
"../TermsOfServiceSection.js";
 import { State } from "./index.js";
 import editIcon from "../../svg/edit_24px.svg";
 import { Amount } from "../../components/Amount.js";
+import { QR } from "../../components/QR.js";
+import { useState } from "preact/hooks";
 
 export function LoadingUriView({ error }: State.LoadingUriError): VNode {
   const { i18n } = useTranslationContext();
@@ -126,13 +129,13 @@ export function SuccessView(state: State.Success): VNode {
               }}
             >
               <i18n.Translate>Exchange</i18n.Translate>
-              <Link>
+              {/* <Link>
                 <SvgIcon
                   title="Edit"
                   dangerouslySetInnerHTML={{ __html: editIcon }}
                   color="black"
                 />
-              </Link>
+              </Link> */}
             </div>
           }
           text={<ExchangeDetails exchange={state.exchangeUrl} />}
@@ -164,31 +167,36 @@ export function SuccessView(state: State.Success): VNode {
       </section>
       {state.tosProps && <TermsOfServiceSection {...state.tosProps} />}
       {state.tosProps ? (
-        <section>
-          {(state.tosProps.terms.status === "accepted" ||
-            (state.mustAcceptFirst && state.tosProps.reviewed)) && (
-            <Button
-              variant="contained"
-              color="success"
-              disabled={!state.doWithdrawal.onClick}
-              onClick={state.doWithdrawal.onClick}
-            >
-              <i18n.Translate>
-                Withdraw &nbsp; <Amount value={state.toBeReceived} />
-              </i18n.Translate>
-            </Button>
-          )}
-          {state.tosProps.terms.status === "notfound" && (
-            <Button
-              variant="contained"
-              color="warning"
-              disabled={!state.doWithdrawal.onClick}
-              onClick={state.doWithdrawal.onClick}
-            >
-              <i18n.Translate>Withdraw anyway</i18n.Translate>
-            </Button>
-          )}
-        </section>
+        <Fragment>
+          <section>
+            {(state.tosProps.terms.status === "accepted" ||
+              (state.mustAcceptFirst && state.tosProps.reviewed)) && (
+              <Button
+                variant="contained"
+                color="success"
+                disabled={!state.doWithdrawal.onClick}
+                onClick={state.doWithdrawal.onClick}
+              >
+                <i18n.Translate>
+                  Withdraw &nbsp; <Amount value={state.toBeReceived} />
+                </i18n.Translate>
+              </Button>
+            )}
+            {state.tosProps.terms.status === "notfound" && (
+              <Button
+                variant="contained"
+                color="warning"
+                disabled={!state.doWithdrawal.onClick}
+                onClick={state.doWithdrawal.onClick}
+              >
+                <i18n.Translate>Withdraw anyway</i18n.Translate>
+              </Button>
+            )}
+          </section>
+          {state.talerWithdrawUri ? (
+            <WithdrawWithMobile talerWithdrawUri={state.talerWithdrawUri} />
+          ) : undefined}
+        </Fragment>
       ) : (
         <section>
           <i18n.Translate>Loading terms of service...</i18n.Translate>
@@ -202,3 +210,35 @@ export function SuccessView(state: State.Success): VNode {
     </WalletAction>
   );
 }
+
+function WithdrawWithMobile({
+  talerWithdrawUri,
+}: {
+  talerWithdrawUri: string;
+}): VNode {
+  const { i18n } = useTranslationContext();
+  const [showQR, setShowQR] = useState<boolean>(false);
+
+  return (
+    <section>
+      <LinkSuccess upperCased onClick={() => setShowQR((qr) => !qr)}>
+        {!showQR ? (
+          <i18n.Translate>Withdraw to a mobile phone</i18n.Translate>
+        ) : (
+          <i18n.Translate>Hide QR</i18n.Translate>
+        )}
+      </LinkSuccess>
+      {showQR && (
+        <div>
+          <QR text={talerWithdrawUri} />
+          <i18n.Translate>
+            Scan the QR code or &nbsp;
+            <a href={talerWithdrawUri}>
+              <i18n.Translate>click here</i18n.Translate>
+            </a>
+          </i18n.Translate>
+        </div>
+      )}
+    </section>
+  );
+}
diff --git a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts 
b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts
index 449cb698..74d7cbbd 100644
--- a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts
+++ b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts
@@ -17,20 +17,39 @@
 import { useEffect, useState } from "preact/hooks";
 import { useIocContext } from "../context/iocContext.js";
 
+export interface UriLocation {
+  uri: string;
+  location: "clipboard" | "activeTab"
+}
+
 export function useTalerActionURL(): [
-  string | undefined,
+  UriLocation | undefined,
   (s: boolean) => void,
 ] {
-  const [talerActionUrl, setTalerActionUrl] = useState<string | undefined>(
+  const [talerActionUrl, setTalerActionUrl] = useState<UriLocation | 
undefined>(
     undefined,
   );
   const [dismissed, setDismissed] = useState(false);
-  const { findTalerUriInActiveTab } = useIocContext();
+  const { findTalerUriInActiveTab, findTalerUriInClipboard } = useIocContext();
 
   useEffect(() => {
     async function check(): Promise<void> {
-      const talerUri = await findTalerUriInActiveTab();
-      setTalerActionUrl(talerUri);
+      const clipUri = await findTalerUriInClipboard();
+      if (clipUri) {
+        setTalerActionUrl({
+          location: "clipboard",
+          uri: clipUri
+        });
+        return;
+      }
+      const tabUri = await findTalerUriInActiveTab();
+      if (tabUri) {
+        setTalerActionUrl({
+          location: "activeTab",
+          uri: tabUri
+        });
+        return;
+      }
     }
     check();
   });
diff --git a/packages/taler-wallet-webextension/src/platform/api.ts 
b/packages/taler-wallet-webextension/src/platform/api.ts
index 37f52192..23fd80ed 100644
--- a/packages/taler-wallet-webextension/src/platform/api.ts
+++ b/packages/taler-wallet-webextension/src/platform/api.ts
@@ -163,13 +163,22 @@ export interface PlatformAPI {
   findTalerUriInActiveTab(): Promise<string | undefined>;
 
   /**
-   * Used from the frontend to send commands to the wallet
+   * Popup API
    *
-   * @param operation
-   * @param payload
+   * Read the current tab html and try to find any Taler URI or QR code 
present.
    *
-   * @return response from the backend
+   * @return Taler URI if found
    */
+  findTalerUriInClipboard(): Promise<string | undefined>;
+
+  /**
+  * Used from the frontend to send commands to the wallet
+  *
+  * @param operation
+  * @param payload
+  *
+  * @return response from the backend
+  */
   sendMessageToWalletBackground(
     operation: string,
     payload: any,
diff --git a/packages/taler-wallet-webextension/src/platform/chrome.ts 
b/packages/taler-wallet-webextension/src/platform/chrome.ts
index 4ce995bd..7311354c 100644
--- a/packages/taler-wallet-webextension/src/platform/chrome.ts
+++ b/packages/taler-wallet-webextension/src/platform/chrome.ts
@@ -30,6 +30,7 @@ import {
 const api: PlatformAPI = {
   isFirefox,
   findTalerUriInActiveTab,
+  findTalerUriInClipboard,
   getPermissionsApi,
   getWalletWebExVersion,
   listenToWalletBackground,
@@ -689,6 +690,11 @@ async function findTalerUriInTab(tabId: number): 
Promise<string | undefined> {
   }
 }
 
+async function findTalerUriInClipboard(): Promise<string | undefined> {
+  const textInClipboard = await window.navigator.clipboard.readText();
+  return textInClipboard.startsWith("taler://") || 
textInClipboard.startsWith("taler+http://";) ? textInClipboard : undefined
+}
+
 async function findTalerUriInActiveTab(): Promise<string | undefined> {
   const tab = await getCurrentTab();
   if (!tab || tab.id === undefined) return;
diff --git a/packages/taler-wallet-webextension/src/platform/dev.ts 
b/packages/taler-wallet-webextension/src/platform/dev.ts
index e5db0c8e..bb7e181c 100644
--- a/packages/taler-wallet-webextension/src/platform/dev.ts
+++ b/packages/taler-wallet-webextension/src/platform/dev.ts
@@ -23,6 +23,7 @@ const api: PlatformAPI = {
   isFirefox: () => false,
   keepAlive: (cb: VoidFunction) => cb(),
   findTalerUriInActiveTab: async () => undefined,
+  findTalerUriInClipboard: async () => undefined,
   containsTalerHeaderListener: () => {
     return true;
   },
diff --git a/packages/taler-wallet-webextension/src/popup/Application.tsx 
b/packages/taler-wallet-webextension/src/popup/Application.tsx
index 2bf09d07..457f26cf 100644
--- a/packages/taler-wallet-webextension/src/popup/Application.tsx
+++ b/packages/taler-wallet-webextension/src/popup/Application.tsx
@@ -42,13 +42,15 @@ import { BalancePage } from "./BalancePage.js";
 import { TalerActionFound } from "./TalerActionFound.js";
 
 function CheckTalerActionComponent(): VNode {
-  const [talerActionUrl] = useTalerActionURL();
+  const [action] = useTalerActionURL();
+
+  const actionUri = action?.uri;
 
   useEffect(() => {
-    if (talerActionUrl) {
-      route(Pages.cta({ action: encodeURIComponent(talerActionUrl) }));
+    if (actionUri) {
+      route(Pages.cta({ action: encodeURIComponent(actionUri) }));
     }
-  }, [talerActionUrl]);
+  }, [actionUri]);
 
   return <Fragment />;
 }

-- 
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]