From dda90b51f6fc6fca48a68bc53088e1ed3f018a21 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Fri, 9 Sep 2022 12:22:26 -0300 Subject: 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(-) (limited to 'packages/taler-wallet-webextension') diff --git a/packages/taler-wallet-webextension/src/context/iocContext.ts b/packages/taler-wallet-webextension/src/context/iocContext.ts index b1a9aa128..c7fee0bc0 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; + findTalerUriInClipboard: () => Promise; } const Context = createContext({ 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 d3d2c68e4..18e593283 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({ }} > Exchange - + {/* - + */} } text={} diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts index 7425dbd29..7bd667268 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; }; } diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index 015c9aaca..0d2e150e7 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 850bd6e8f..440586343 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 { }} > Exchange - + {/* - + */} } text={} @@ -164,31 +167,36 @@ export function SuccessView(state: State.Success): VNode { {state.tosProps && } {state.tosProps ? ( -
- {(state.tosProps.terms.status === "accepted" || - (state.mustAcceptFirst && state.tosProps.reviewed)) && ( - - )} - {state.tosProps.terms.status === "notfound" && ( - - )} -
+ +
+ {(state.tosProps.terms.status === "accepted" || + (state.mustAcceptFirst && state.tosProps.reviewed)) && ( + + )} + {state.tosProps.terms.status === "notfound" && ( + + )} +
+ {state.talerWithdrawUri ? ( + + ) : undefined} +
) : (
Loading terms of service... @@ -202,3 +210,35 @@ export function SuccessView(state: State.Success): VNode { ); } + +function WithdrawWithMobile({ + talerWithdrawUri, +}: { + talerWithdrawUri: string; +}): VNode { + const { i18n } = useTranslationContext(); + const [showQR, setShowQR] = useState(false); + + return ( +
+ setShowQR((qr) => !qr)}> + {!showQR ? ( + Withdraw to a mobile phone + ) : ( + Hide QR + )} + + {showQR && ( +
+ + + Scan the QR code or   + + click here + + +
+ )} +
+ ); +} diff --git a/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts b/packages/taler-wallet-webextension/src/hooks/useTalerActionURL.ts index 449cb698f..74d7cbbd9 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( + const [talerActionUrl, setTalerActionUrl] = useState( undefined, ); const [dismissed, setDismissed] = useState(false); - const { findTalerUriInActiveTab } = useIocContext(); + const { findTalerUriInActiveTab, findTalerUriInClipboard } = useIocContext(); useEffect(() => { async function check(): Promise { - 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 37f52192f..23fd80ed7 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; /** - * 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; + + /** + * 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 4ce995bd7..7311354c9 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 { } } +async function findTalerUriInClipboard(): Promise { + const textInClipboard = await window.navigator.clipboard.readText(); + return textInClipboard.startsWith("taler://") || textInClipboard.startsWith("taler+http://") ? textInClipboard : undefined +} + async function findTalerUriInActiveTab(): Promise { 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 e5db0c8ec..bb7e181c4 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 2bf09d07e..457f26cfd 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 ; } -- cgit v1.2.3