diff options
author | Sebastian <sebasjm@gmail.com> | 2022-09-16 16:03:58 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2022-09-16 16:03:58 -0300 |
commit | 59d235e8d29159bc8caccf8bee6a2bca8b0b90dc (patch) | |
tree | 551261c860b1989dc0b1a05ddcfd53d20e561626 | |
parent | 6ddb2de84245ae3914c92b2b2eb7399e7f04500e (diff) |
redirect after success #7357
36 files changed, 289 insertions, 621 deletions
diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/index.ts b/packages/taler-wallet-webextension/src/cta/Deposit/index.ts index 0f6c4743e..d6433b18c 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Deposit/index.ts @@ -21,19 +21,19 @@ import { ButtonHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import * as wxApi from "../../wxApi.js"; import { useComponentState } from "./state.js"; -import { CompletedView, LoadingUriView, ReadyView } from "./views.js"; +import { LoadingUriView, ReadyView } from "./views.js"; export interface Props { talerDepositUri: string | undefined; amountStr: AmountString | undefined; cancel: () => Promise<void>; + onSuccess: (tx: string) => Promise<void>; } export type State = | State.Loading | State.LoadingUriError - | State.Ready - | State.Completed; + | State.Ready; export namespace State { export interface Loading { @@ -62,7 +62,6 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, "loading-uri": LoadingUriView, - completed: CompletedView, ready: ReadyView, }; diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts index 0ae8bff18..b6861cb4b 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Deposit/state.ts @@ -21,12 +21,9 @@ import * as wxApi from "../../wxApi.js"; import { Props, State } from "./index.js"; export function useComponentState( - { talerDepositUri, amountStr, cancel }: Props, + { talerDepositUri, amountStr, cancel, onSuccess }: Props, api: typeof wxApi, ): State { - const [result, setResult] = useState<CreateDepositGroupResponse | undefined>( - undefined, - ); const info = useAsyncAsHook(async () => { if (!talerDepositUri) throw Error("ERROR_NO-URI-FOR-DEPOSIT"); @@ -51,14 +48,7 @@ export function useComponentState( const { deposit, uri, amount } = info.response; async function doDeposit(): Promise<void> { const resp = await api.createDepositGroup(uri, Amounts.stringify(amount)); - setResult(resp); - } - - if (result !== undefined) { - return { - status: "completed", - error: undefined, - }; + onSuccess(resp.transactionId); } return { diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts index 67f9ca8bd..5d5c5cecb 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Deposit/test.ts @@ -35,6 +35,7 @@ describe("Deposit CTA states", () => { cancel: async () => { null; }, + onSuccess: async () => { null; }, }, { prepareRefund: async () => ({}), @@ -75,13 +76,14 @@ describe("Deposit CTA states", () => { cancel: async () => { null; }, + onSuccess: async () => { null; }, }, { prepareDeposit: async () => - ({ - effectiveDepositAmount: Amounts.parseOrThrow("EUR:1"), - totalDepositCost: Amounts.parseOrThrow("EUR:1.2"), - } as PrepareDepositResponse as any), + ({ + effectiveDepositAmount: Amounts.parseOrThrow("EUR:1"), + totalDepositCost: Amounts.parseOrThrow("EUR:1.2"), + } as PrepareDepositResponse as any), createDepositGroup: async () => ({}), } as any, ), diff --git a/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx b/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx index 9045e5bfa..2ec305de5 100644 --- a/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Deposit/views.tsx @@ -40,24 +40,6 @@ export function LoadingUriView({ error }: State.LoadingUriError): VNode { /> ); } -export function CompletedView(state: State.Completed): VNode { - const { i18n } = useTranslationContext(); - - return ( - <WalletAction> - <LogoHeader /> - - <SubTitle> - <i18n.Translate>Digital cash deposit</i18n.Translate> - </SubTitle> - <section> - <p> - <i18n.Translate>deposit completed</i18n.Translate> - </p> - </section> - </WalletAction> - ); -} export function ReadyView(state: State.Ready): VNode { const { i18n } = useTranslationContext(); diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts index fe0b0f5f7..f7d6fbe63 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/index.ts @@ -17,7 +17,7 @@ import { Loading } from "../../components/Loading.js"; import { HookError } from "../../hooks/useAsyncAsHook.js"; import { compose, StateViewMap } from "../../utils/index.js"; -import { LoadingUriView, ReadyView, CreatedView } from "./views.js"; +import { LoadingUriView, ReadyView } from "./views.js"; import * as wxApi from "../../wxApi.js"; import { useComponentState } from "./state.js"; import { AmountJson, TalerErrorDetail } from "@gnu-taler/taler-util"; @@ -26,12 +26,12 @@ import { ButtonHandler, TextFieldHandler } from "../../mui/handlers.js"; export interface Props { amount: string; onClose: () => Promise<void>; + onSuccess: (tx: string) => Promise<void>; } export type State = | State.Loading | State.LoadingUriError - | State.Created | State.Ready; export namespace State { @@ -49,11 +49,6 @@ export namespace State { error: undefined; cancel: ButtonHandler; } - export interface Created extends BaseInfo { - status: "created"; - talerUri: string; - copyToClipboard: ButtonHandler; - } export interface Ready extends BaseInfo { status: "ready"; create: ButtonHandler; @@ -70,7 +65,6 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, "loading-uri": LoadingUriView, - created: CreatedView, ready: ReadyView, }; diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts index 8f57582d6..a338387de 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/state.ts @@ -22,13 +22,12 @@ import * as wxApi from "../../wxApi.js"; import { Props, State } from "./index.js"; export function useComponentState( - { amount: amountStr, onClose }: Props, + { amount: amountStr, onClose, onSuccess }: Props, api: typeof wxApi, ): State { const amount = Amounts.parseOrThrow(amountStr); const [subject, setSubject] = useState(""); - const [talerUri, setTalerUri] = useState(""); const hook = useAsyncAsHook(api.listExchanges); const [exchangeIdx, setExchangeIdx] = useState("0"); @@ -49,22 +48,6 @@ export function useComponentState( }; } - if (talerUri) { - return { - status: "created", - talerUri, - error: undefined, - cancel: { - onClick: onClose, - }, - copyToClipboard: { - onClick: async () => { - navigator.clipboard.writeText(talerUri); - }, - }, - }; - } - const exchanges = hook.response.exchanges.filter( (e) => e.currency === amount.currency, ); @@ -74,7 +57,7 @@ export function useComponentState( ); const selected = exchanges[Number(exchangeIdx)]; - async function accept(): Promise<string> { + async function accept(): Promise<void> { try { const resp = await api.initiatePeerPullPayment({ amount: Amounts.stringify(amount), @@ -83,7 +66,8 @@ export function useComponentState( summary: subject, }, }); - return resp.talerUri; + + onSuccess(resp.transactionId); } catch (e) { if (e instanceof TalerError) { setOperationError(e.errorDetail); @@ -103,10 +87,7 @@ export function useComponentState( invalid: !subject || Amounts.isZero(amount), exchangeUrl: selected.exchangeBaseUrl, create: { - onClick: async () => { - const uri = await accept(); - setTalerUri(uri); - }, + onClick: accept }, cancel: { onClick: onClose, diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx index 0adc29e78..b5a0a52e2 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/stories.tsx @@ -20,19 +20,12 @@ */ import { createExample } from "../../test-utils.js"; -import { ReadyView, CreatedView } from "./views.js"; +import { ReadyView } from "./views.js"; export default { title: "wallet/invoice create", }; -export const ShowQr = createExample(CreatedView, { - talerUri: - "taler://pay-pull/exchange.taler.ar/HS585JK0QCXHJ8Z8QWZA3EBAY5WY7XNC1RR2MHJXSH2Z4WP0YPJ0", - cancel: {}, - copyToClipboard: {}, -}); - export const Ready = createExample(ReadyView, { chosenAmount: { currency: "ARS", diff --git a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx index c5ed9a4cf..693c07713 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/InvoiceCreate/views.tsx @@ -45,38 +45,6 @@ export function LoadingUriView({ error }: State.LoadingUriError): VNode { ); } -export function CreatedView({ - talerUri, - copyToClipboard, - cancel, -}: State.Created): VNode { - const { i18n } = useTranslationContext(); - return ( - <WalletAction> - <LogoHeader /> - <SubTitle> - <i18n.Translate>Digital cash invoice</i18n.Translate> - </SubTitle> - <section> - <p> - <i18n.Translate>Show this QR to pay the invoice</i18n.Translate> - </p> - <QR text={talerUri} /> - </section> - <section> - or - <Button onClick={copyToClipboard.onClick}> - <i18n.Translate>Copy the invoice URI</i18n.Translate> - </Button> - </section> - <section> - <Link upperCased onClick={cancel.onClick}> - <i18n.Translate>Close</i18n.Translate> - </Link> - </section> - </WalletAction> - ); -} export function ReadyView({ invalid, diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts index 731064661..7c6f13286 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/index.ts @@ -32,6 +32,7 @@ export interface Props { talerPayPullUri: string; onClose: () => Promise<void>; goToWalletManualWithdraw: (amount?: string) => Promise<void>; + onSuccess: (tx: string) => Promise<void>; } export type State = diff --git a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts index e69bb4627..c88e80602 100644 --- a/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts +++ b/packages/taler-wallet-webextension/src/cta/InvoicePay/state.ts @@ -30,7 +30,7 @@ import * as wxApi from "../../wxApi.js"; import { Props, State } from "./index.js"; export function useComponentState( - { talerPayPullUri, onClose, goToWalletManualWithdraw }: Props, + { talerPayPullUri, onClose, goToWalletManualWithdraw, onSuccess }: Props, api: typeof wxApi, ): State { const hook = useAsyncAsHook(async () => { @@ -149,7 +149,7 @@ export function useComponentState( const resp = await api.acceptPeerPullPayment({ peerPullPaymentIncomingId, }); - await onClose(); + onSuccess(resp.transactionId); } catch (e) { if (e instanceof TalerError) { setOperationError(e.errorDetail); diff --git a/packages/taler-wallet-webextension/src/cta/Payment/index.ts b/packages/taler-wallet-webextension/src/cta/Payment/index.ts index b20f91b0c..1dd84fd7e 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/index.ts @@ -35,6 +35,7 @@ export interface Props { talerPayUri?: string; goToWalletManualWithdraw: (amount?: string) => Promise<void>; cancel: () => Promise<void>; + onSuccess: (tx: string) => Promise<void>; } export type State = @@ -43,7 +44,6 @@ export type State = | State.Ready | State.NoEnoughBalance | State.NoBalanceForCurrency - | State.Completed | State.Confirmed; export namespace State { @@ -86,13 +86,6 @@ export namespace State { balance: AmountJson; } - export interface Completed extends BaseInfo { - status: "completed"; - payStatus: PreparePayResult; - payResult: ConfirmPayResult; - paymentError?: TalerError; - balance: AmountJson; - } } const viewMapping: StateViewMap<State> = { @@ -101,7 +94,6 @@ const viewMapping: StateViewMap<State> = { "no-balance-for-currency": BaseView, "no-enough-balance": BaseView, confirmed: BaseView, - completed: BaseView, ready: BaseView, }; diff --git a/packages/taler-wallet-webextension/src/cta/Payment/state.ts b/packages/taler-wallet-webextension/src/cta/Payment/state.ts index 488263bb8..e8690be39 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/state.ts @@ -31,12 +31,9 @@ import * as wxApi from "../../wxApi.js"; import { Props, State } from "./index.js"; export function useComponentState( - { talerPayUri, cancel, goToWalletManualWithdraw }: Props, + { talerPayUri, cancel, goToWalletManualWithdraw, onSuccess }: Props, api: typeof wxApi, ): State { - const [payResult, setPayResult] = useState<ConfirmPayResult | undefined>( - undefined, - ); const [payErrMsg, setPayErrMsg] = useState<TalerError | undefined>(undefined); const hook = useAsyncAsHook(async () => { @@ -104,17 +101,6 @@ export function useComponentState( const foundAmount = Amounts.parseOrThrow(foundBalance.available); - if (payResult) { - return { - status: "completed", - balance: foundAmount, - payStatus, - paymentError: payErrMsg, - payResult, - ...baseResult, - }; - } - if (payStatus.status === PreparePayResultType.InsufficientBalance) { return { status: "no-enough-balance", @@ -157,7 +143,7 @@ export function useComponentState( console.log(`should d to ${fu}`); } } - setPayResult(res); + onSuccess(res.transactionId); } catch (e) { if (e instanceof TalerError) { setPayErrMsg(e); diff --git a/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx b/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx index 559e5c5d4..6946f6906 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/Payment/stories.tsx @@ -334,80 +334,4 @@ export const AlreadyConfirmedByOther = createExample(BaseView, { }, }); -export const AlreadyPaidWithoutFulfillment = createExample(BaseView, { - status: "completed", - error: undefined, - amount: Amounts.parseOrThrow("USD:10"), - balance: { - currency: "USD", - fraction: 40000000, - value: 11, - }, - - uri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", - payResult: { - type: ConfirmPayResultType.Done, - contractTerms: {} as any, - transactionId: "", - }, - payStatus: { - status: PreparePayResultType.AlreadyConfirmed, - amountEffective: "USD:10", - amountRaw: "USD:10", - contractTerms: { - merchant: { - name: "the merchant", - logo: merchantIcon, - website: "https://www.themerchant.taler", - email: "contact@merchant.taler", - }, - summary: "some beers", - amount: "USD:10", - } as Partial<ContractTerms> as any, - contractTermsHash: "123456", - proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0", - paid: true, - }, -}); - -export const AlreadyPaidWithFulfillment = createExample(BaseView, { - status: "completed", - error: undefined, - amount: Amounts.parseOrThrow("USD:10"), - balance: { - currency: "USD", - fraction: 40000000, - value: 11, - }, - uri: "taler://pay/merchant-backend.taler/2021.242-01G2X4275RBWG/?c=66BE594PDZR24744J6EQK52XM0", - payResult: { - type: ConfirmPayResultType.Done, - contractTerms: { - fulfillment_message: "thanks for buying!", - fulfillment_url: "https://demo.taler.net", - } as Partial<ContractTerms> as any, - transactionId: "", - }, - payStatus: { - status: PreparePayResultType.AlreadyConfirmed, - amountEffective: "USD:10", - amountRaw: "USD:10", - contractTerms: { - merchant: { - name: "the merchant", - logo: merchantIcon, - website: "https://www.themerchant.taler", - email: "contact@merchant.taler", - }, - fulfillment_url: "https://demo.taler.net", - fulfillment_message: - "congratulations! you are looking at the fulfillment message! ", - summary: "some beers", - amount: "USD:10", - } as Partial<ContractTerms> as any, - contractTermsHash: "123456", - proposalId: "96YY92RQZGF3V7TJSPN4SF9549QX7BRF88Q5PYFCSBNQ0YK4RPK0", - paid: true, - }, -}); diff --git a/packages/taler-wallet-webextension/src/cta/Payment/test.ts b/packages/taler-wallet-webextension/src/cta/Payment/test.ts index 235b22c22..91d2d825d 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Payment/test.ts @@ -75,6 +75,7 @@ describe("Payment CTA states", () => { talerPayUri: undefined, cancel: nullFunction, goToWalletManualWithdraw: nullFunction, + onSuccess: async () => { null; }, }, { onUpdateNotification: nullFunction, @@ -110,18 +111,19 @@ describe("Payment CTA states", () => { talerPayUri: "taller://pay", cancel: nullFunction, goToWalletManualWithdraw: nullFunction, + onSuccess: async () => { null; }, }, { onUpdateNotification: nullFunction, preparePay: async () => - ({ - amountRaw: "USD:10", - status: PreparePayResultType.InsufficientBalance, - } as Partial<PreparePayResult>), + ({ + amountRaw: "USD:10", + status: PreparePayResultType.InsufficientBalance, + } as Partial<PreparePayResult>), getBalance: async () => - ({ - balances: [], - } as Partial<BalancesResponse>), + ({ + balances: [], + } as Partial<BalancesResponse>), } as Partial<typeof wxApi> as any, ), ); @@ -152,22 +154,23 @@ describe("Payment CTA states", () => { talerPayUri: "taller://pay", cancel: nullFunction, goToWalletManualWithdraw: nullFunction, + onSuccess: async () => { null; }, }, { onUpdateNotification: nullFunction, preparePay: async () => - ({ - amountRaw: "USD:10", - status: PreparePayResultType.InsufficientBalance, - } as Partial<PreparePayResult>), + ({ + amountRaw: "USD:10", + status: PreparePayResultType.InsufficientBalance, + } as Partial<PreparePayResult>), getBalance: async () => - ({ - balances: [ - { - available: "USD:5", - }, - ], - } as Partial<BalancesResponse>), + ({ + balances: [ + { + available: "USD:5", + }, + ], + } as Partial<BalancesResponse>), } as Partial<typeof wxApi> as any, ), ); @@ -198,23 +201,24 @@ describe("Payment CTA states", () => { talerPayUri: "taller://pay", cancel: nullFunction, goToWalletManualWithdraw: nullFunction, + onSuccess: async () => { null; }, }, { onUpdateNotification: nullFunction, preparePay: async () => - ({ - amountRaw: "USD:10", - amountEffective: "USD:10", - status: PreparePayResultType.PaymentPossible, - } as Partial<PreparePayResult>), + ({ + amountRaw: "USD:10", + amountEffective: "USD:10", + status: PreparePayResultType.PaymentPossible, + } as Partial<PreparePayResult>), getBalance: async () => - ({ - balances: [ - { - available: "USD:15", - }, - ], - } as Partial<BalancesResponse>), + ({ + balances: [ + { + available: "USD:15", + }, + ], + } as Partial<BalancesResponse>), } as Partial<typeof wxApi> as any, ), ); @@ -247,23 +251,24 @@ describe("Payment CTA states", () => { talerPayUri: "taller://pay", cancel: nullFunction, goToWalletManualWithdraw: nullFunction, + onSuccess: async () => { null; }, }, { onUpdateNotification: nullFunction, preparePay: async () => - ({ - amountRaw: "USD:9", - amountEffective: "USD:10", - status: PreparePayResultType.PaymentPossible, - } as Partial<PreparePayResult>), + ({ + amountRaw: "USD:9", + amountEffective: "USD:10", + status: PreparePayResultType.PaymentPossible, + } as Partial<PreparePayResult>), getBalance: async () => - ({ - balances: [ - { - available: "USD:15", - }, - ], - } as Partial<BalancesResponse>), + ({ + balances: [ + { + available: "USD:15", + }, + ], + } as Partial<BalancesResponse>), } as Partial<typeof wxApi> as any, ), ); @@ -296,28 +301,29 @@ describe("Payment CTA states", () => { talerPayUri: "taller://pay", cancel: nullFunction, goToWalletManualWithdraw: nullFunction, + onSuccess: async () => { null; }, }, { onUpdateNotification: nullFunction, preparePay: async () => - ({ - amountRaw: "USD:9", - amountEffective: "USD:10", - status: PreparePayResultType.PaymentPossible, - } as Partial<PreparePayResult>), + ({ + amountRaw: "USD:9", + amountEffective: "USD:10", + status: PreparePayResultType.PaymentPossible, + } as Partial<PreparePayResult>), getBalance: async () => - ({ - balances: [ - { - available: "USD:15", - }, - ], - } as Partial<BalancesResponse>), + ({ + balances: [ + { + available: "USD:15", + }, + ], + } as Partial<BalancesResponse>), confirmPay: async () => - ({ - type: ConfirmPayResultType.Done, - contractTerms: {}, - } as Partial<ConfirmPayResult>), + ({ + type: ConfirmPayResultType.Done, + contractTerms: {}, + } as Partial<ConfirmPayResult>), } as Partial<typeof wxApi> as any, ), ); @@ -340,18 +346,18 @@ describe("Payment CTA states", () => { r.payHandler.onClick(); } - await waitNextUpdate(); + // await waitNextUpdate(); - { - const r = getLastResultOrThrow(); - if (r.status !== "completed") expect.fail(); - expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15")); - expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9")); - // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); - // if (r.payResult.type !== ConfirmPayResultType.Done) expect.fail(); - // expect(r.payResult.contractTerms).not.undefined; - // expect(r.payHandler.onClick).undefined; - } + // { + // const r = getLastResultOrThrow(); + // if (r.status !== "completed") expect.fail(); + // expect(r.balance).deep.equal(Amounts.parseOrThrow("USD:15")); + // expect(r.amount).deep.equal(Amounts.parseOrThrow("USD:9")); + // // expect(r.totalFees).deep.equal(Amounts.parseOrThrow("USD:1")); + // // if (r.payResult.type !== ConfirmPayResultType.Done) expect.fail(); + // // expect(r.payResult.contractTerms).not.undefined; + // // expect(r.payHandler.onClick).undefined; + // } await assertNoPendingUpdate(); }); @@ -364,28 +370,29 @@ describe("Payment CTA states", () => { talerPayUri: "taller://pay", cancel: nullFunction, goToWalletManualWithdraw: nullFunction, + onSuccess: async () => { null; }, }, { onUpdateNotification: nullFunction, preparePay: async () => - ({ - amountRaw: "USD:9", - amountEffective: "USD:10", - status: PreparePayResultType.PaymentPossible, - } as Partial<PreparePayResult>), + ({ + amountRaw: "USD:9", + amountEffective: "USD:10", + status: PreparePayResultType.PaymentPossible, + } as Partial<PreparePayResult>), getBalance: async () => - ({ - balances: [ - { - available: "USD:15", - }, - ], - } as Partial<BalancesResponse>), + ({ + balances: [ + { + available: "USD:15", + }, + ], + } as Partial<BalancesResponse>), confirmPay: async () => - ({ - type: ConfirmPayResultType.Pending, - lastError: { code: 1 }, - } as Partial<ConfirmPayResult>), + ({ + type: ConfirmPayResultType.Pending, + lastError: { code: 1 }, + } as Partial<ConfirmPayResult>), } as Partial<typeof wxApi> as any, ), ); @@ -447,23 +454,24 @@ describe("Payment CTA states", () => { talerPayUri: "taller://pay", cancel: nullFunction, goToWalletManualWithdraw: nullFunction, + onSuccess: async () => { null; }, }, { onUpdateNotification: subscriptions.saveSubscription, preparePay: async () => - ({ - amountRaw: "USD:9", - amountEffective: "USD:10", - status: PreparePayResultType.PaymentPossible, - } as Partial<PreparePayResult>), + ({ + amountRaw: "USD:9", + amountEffective: "USD:10", + status: PreparePayResultType.PaymentPossible, + } as Partial<PreparePayResult>), getBalance: async () => - ({ - balances: [ - { - available: Amounts.stringify(availableBalance), - }, - ], - } as Partial<BalancesResponse>), + ({ + balances: [ + { + available: Amounts.stringify(availableBalance), + }, + ], + } as Partial<BalancesResponse>), } as Partial<typeof wxApi> as any, ), ); diff --git a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx index 0383960ed..a2e52269c 100644 --- a/packages/taler-wallet-webextension/src/cta/Payment/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Payment/views.tsx @@ -63,7 +63,6 @@ export function LoadingUriView({ error }: State.LoadingUriError): VNode { type SupportedStates = | State.Ready | State.Confirmed - | State.Completed | State.NoBalanceForCurrency | State.NoEnoughBalance; @@ -167,7 +166,6 @@ export function BaseView(state: SupportedStates): VNode { /> )} </section> - {state.status !== "completed" ? ( <ButtonsSection amount={state.amount} balance={state.balance} @@ -176,7 +174,6 @@ export function BaseView(state: SupportedStates): VNode { payHandler={state.status === "ready" ? state.payHandler : undefined} goToWalletManualWithdraw={state.goToWalletManualWithdraw} /> - ) : undefined} <section> <Link upperCased onClick={state.cancel}> <i18n.Translate>Cancel</i18n.Translate> @@ -285,35 +282,6 @@ function ShowImportantMessage({ state }: { state: SupportedStates }): VNode { ); } - if (state.status == "completed") { - const { payResult, paymentError } = state; - if (paymentError) { - return <ErrorTalerOperation error={paymentError.errorDetail} />; - } - if (payResult.type === ConfirmPayResultType.Done) { - return ( - <SuccessBox> - <h3> - <i18n.Translate>Payment complete</i18n.Translate> - </h3> - <p> - {!payResult.contractTerms.fulfillment_message ? ( - payResult.contractTerms.fulfillment_url ? ( - <i18n.Translate> - You are going to be redirected to $ - {payResult.contractTerms.fulfillment_url} - </i18n.Translate> - ) : ( - <i18n.Translate>You can close this page.</i18n.Translate> - ) - ) : ( - payResult.contractTerms.fulfillment_message - )} - </p> - </SuccessBox> - ); - } - } return <Fragment />; } diff --git a/packages/taler-wallet-webextension/src/cta/Refund/index.ts b/packages/taler-wallet-webextension/src/cta/Refund/index.ts index f513ee3b7..be9e3499b 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Refund/index.ts @@ -22,7 +22,6 @@ import { compose, StateViewMap } from "../../utils/index.js"; import * as wxApi from "../../wxApi.js"; import { useComponentState } from "./state.js"; import { - CompletedView, IgnoredView, InProgressView, LoadingUriView, @@ -32,6 +31,7 @@ import { export interface Props { talerRefundUri?: string; cancel: () => Promise<void>; + onSuccess: (tx: string) => Promise<void>; } export type State = @@ -39,8 +39,7 @@ export type State = | State.LoadingUriError | State.Ready | State.Ignored - | State.InProgress - | State.Completed; + | State.InProgress; export namespace State { export interface Loading { @@ -79,17 +78,12 @@ export namespace State { status: "in-progress"; error: undefined; } - export interface Completed extends BaseInfo { - status: "completed"; - error: undefined; - } } const viewMapping: StateViewMap<State> = { loading: Loading, "loading-uri": LoadingUriView, "in-progress": InProgressView, - completed: CompletedView, ignored: IgnoredView, ready: ReadyView, }; diff --git a/packages/taler-wallet-webextension/src/cta/Refund/state.ts b/packages/taler-wallet-webextension/src/cta/Refund/state.ts index 8d36b61ea..16dbbf70d 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Refund/state.ts @@ -21,7 +21,7 @@ import * as wxApi from "../../wxApi.js"; import { Props, State } from "./index.js"; export function useComponentState( - { talerRefundUri, cancel }: Props, + { talerRefundUri, cancel, onSuccess }: Props, api: typeof wxApi, ): State { const [ignored, setIgnored] = useState(false); @@ -51,8 +51,9 @@ export function useComponentState( const { refund, uri } = info.response; const doAccept = async (): Promise<void> => { - await api.applyRefund(uri); - info.retry(); + const res = await api.applyRefund(uri); + + onSuccess(res.transactionId); }; const doIgnore = async (): Promise<void> => { @@ -75,13 +76,6 @@ export function useComponentState( }; } - if (Amounts.isZero(baseInfo.awaitingAmount)) { - return { - status: "completed", - ...baseInfo, - }; - } - if (refund.pending) { return { status: "in-progress", diff --git a/packages/taler-wallet-webextension/src/cta/Refund/stories.tsx b/packages/taler-wallet-webextension/src/cta/Refund/stories.tsx index d3a2302d9..d74120dff 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/Refund/stories.tsx @@ -23,7 +23,6 @@ import { Amounts } from "@gnu-taler/taler-util"; import beer from "../../../static-dev/beer.png"; import { createExample } from "../../test-utils.js"; import { - CompletedView, IgnoredView, InProgressView, ReadyView, @@ -32,15 +31,6 @@ export default { title: "cta/refund", }; -export const Complete = createExample(CompletedView, { - status: "completed", - amount: Amounts.parseOrThrow("USD:1"), - granted: Amounts.parseOrThrow("USD:1"), - error: undefined, - merchantName: "the merchant", - products: undefined, -}); - export const InProgress = createExample(InProgressView, { status: "in-progress", error: undefined, diff --git a/packages/taler-wallet-webextension/src/cta/Refund/test.ts b/packages/taler-wallet-webextension/src/cta/Refund/test.ts index 04d3e0d5f..09470b7f6 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Refund/test.ts @@ -40,6 +40,7 @@ describe("Refund CTA states", () => { cancel: async () => { null; }, + onSuccess: async () => { null; }, }, { prepareRefund: async () => ({}), @@ -79,25 +80,26 @@ describe("Refund CTA states", () => { cancel: async () => { null; }, + onSuccess: async () => { null; }, }, { prepareRefund: async () => - ({ - effectivePaid: "EUR:2", - awaiting: "EUR:2", - gone: "EUR:0", - granted: "EUR:0", - pending: false, - proposalId: "1", - info: { - contractTermsHash: "123", - merchant: { - name: "the merchant name", - }, - orderId: "orderId1", - summary: "the summary", + ({ + effectivePaid: "EUR:2", + awaiting: "EUR:2", + gone: "EUR:0", + granted: "EUR:0", + pending: false, + proposalId: "1", + info: { + contractTermsHash: "123", + merchant: { + name: "the merchant name", }, - } as PrepareRefundResult as any), + orderId: "orderId1", + summary: "the summary", + }, + } as PrepareRefundResult as any), applyRefund: async () => ({}), onUpdateNotification: async () => ({}), } as any, @@ -136,25 +138,26 @@ describe("Refund CTA states", () => { cancel: async () => { null; }, + onSuccess: async () => { null; }, }, { prepareRefund: async () => - ({ - effectivePaid: "EUR:2", - awaiting: "EUR:2", - gone: "EUR:0", - granted: "EUR:0", - pending: false, - proposalId: "1", - info: { - contractTermsHash: "123", - merchant: { - name: "the merchant name", - }, - orderId: "orderId1", - summary: "the summary", + ({ + effectivePaid: "EUR:2", + awaiting: "EUR:2", + gone: "EUR:0", + granted: "EUR:0", + pending: false, + proposalId: "1", + info: { + contractTermsHash: "123", + merchant: { + name: "the merchant name", }, - } as PrepareRefundResult as any), + orderId: "orderId1", + summary: "the summary", + }, + } as PrepareRefundResult as any), applyRefund: async () => ({}), onUpdateNotification: async () => ({}), } as any, @@ -220,25 +223,27 @@ describe("Refund CTA states", () => { cancel: async () => { null; }, + onSuccess: async () => { null; }, + }, { prepareRefund: async () => - ({ - awaiting: Amounts.stringify(awaiting), - effectivePaid: "EUR:2", - gone: "EUR:0", - granted: Amounts.stringify(granted), - pending, - proposalId: "1", - info: { - contractTermsHash: "123", - merchant: { - name: "the merchant name", - }, - orderId: "orderId1", - summary: "the summary", + ({ + awaiting: Amounts.stringify(awaiting), + effectivePaid: "EUR:2", + gone: "EUR:0", + granted: Amounts.stringify(granted), + pending, + proposalId: "1", + info: { + contractTermsHash: "123", + merchant: { + name: "the merchant name", }, - } as PrepareRefundResult as any), + orderId: "orderId1", + summary: "the summary", + }, + } as PrepareRefundResult as any), applyRefund: async () => ({}), onUpdateNotification: subscriptions.saveSubscription, } as any, @@ -286,7 +291,7 @@ describe("Refund CTA states", () => { { const state = getLastResultOrThrow(); - if (state.status !== "completed") expect.fail("3"); + if (state.status !== "ready") expect.fail("3"); if (state.error) expect.fail(); expect(state.merchantName).eq("the merchant name"); expect(state.products).undefined; diff --git a/packages/taler-wallet-webextension/src/cta/Refund/views.tsx b/packages/taler-wallet-webextension/src/cta/Refund/views.tsx index d8c67334c..4b5ff70dd 100644 --- a/packages/taler-wallet-webextension/src/cta/Refund/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Refund/views.tsx @@ -92,32 +92,6 @@ export function InProgressView(state: State.InProgress): VNode { </WalletAction> ); } -export function CompletedView(state: State.Completed): VNode { - const { i18n } = useTranslationContext(); - - return ( - <WalletAction> - <LogoHeader /> - - <SubTitle> - <i18n.Translate>Digital cash refund</i18n.Translate> - </SubTitle> - <section> - <p> - <i18n.Translate>this refund is already accepted.</i18n.Translate> - </p> - </section> - <section> - <Part - big - title={<i18n.Translate>Total to refunded</i18n.Translate>} - text={<Amount value={state.granted} />} - kind="negative" - /> - </section> - </WalletAction> - ); -} export function ReadyView(state: State.Ready): VNode { const { i18n } = useTranslationContext(); return ( diff --git a/packages/taler-wallet-webextension/src/cta/Tip/index.ts b/packages/taler-wallet-webextension/src/cta/Tip/index.ts index 4bdad0808..157cf7d4e 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Tip/index.ts @@ -32,6 +32,7 @@ import { export interface Props { talerTipUri?: string; onCancel: () => Promise<void>; + onSuccess: (tx: string) => Promise<void>; } export type State = diff --git a/packages/taler-wallet-webextension/src/cta/Tip/state.ts b/packages/taler-wallet-webextension/src/cta/Tip/state.ts index 333337e78..a3adafe53 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Tip/state.ts @@ -21,7 +21,7 @@ import * as wxApi from "../../wxApi.js"; import { Props, State } from "./index.js"; export function useComponentState( - { talerTipUri, onCancel }: Props, + { talerTipUri, onCancel, onSuccess }: Props, api: typeof wxApi, ): State { const [tipIgnored, setTipIgnored] = useState(false); @@ -48,8 +48,11 @@ export function useComponentState( const { tip } = tipInfo.response; const doAccept = async (): Promise<void> => { - await api.acceptTip({ walletTipId: tip.walletTipId }); + const res = await api.acceptTip({ walletTipId: tip.walletTipId }); + + //FIX: this may not be seen since we are moving to the success also tipInfo.retry(); + onSuccess(res.transactionId) }; const baseInfo = { diff --git a/packages/taler-wallet-webextension/src/cta/Tip/test.ts b/packages/taler-wallet-webextension/src/cta/Tip/test.ts index 4895fcc7f..eeb39c8aa 100644 --- a/packages/taler-wallet-webextension/src/cta/Tip/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Tip/test.ts @@ -34,6 +34,7 @@ describe("Tip CTA states", () => { onCancel: async () => { null; }, + onSuccess: async () => { null; }, }, { prepareTip: async () => ({}), @@ -74,16 +75,17 @@ describe("Tip CTA states", () => { onCancel: async () => { null; }, + onSuccess: async () => { null; }, }, { prepareTip: async () => - ({ - accepted: tipAccepted, - exchangeBaseUrl: "exchange url", - merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", - } as PrepareTipResult as any), + ({ + accepted: tipAccepted, + exchangeBaseUrl: "exchange url", + merchantBaseUrl: "merchant url", + tipAmountEffective: "EUR:1", + walletTipId: "tip_id", + } as PrepareTipResult as any), acceptTip: async () => { tipAccepted = true; }, @@ -134,15 +136,16 @@ describe("Tip CTA states", () => { onCancel: async () => { null; }, + onSuccess: async () => { null; }, }, { prepareTip: async () => - ({ - exchangeBaseUrl: "exchange url", - merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", - } as PrepareTipResult as any), + ({ + exchangeBaseUrl: "exchange url", + merchantBaseUrl: "merchant url", + tipAmountEffective: "EUR:1", + walletTipId: "tip_id", + } as PrepareTipResult as any), acceptTip: async () => ({}), } as any, ), @@ -188,16 +191,17 @@ describe("Tip CTA states", () => { onCancel: async () => { null; }, + onSuccess: async () => { null; }, }, { prepareTip: async () => - ({ - accepted: true, - exchangeBaseUrl: "exchange url", - merchantBaseUrl: "merchant url", - tipAmountEffective: "EUR:1", - walletTipId: "tip_id", - } as PrepareTipResult as any), + ({ + accepted: true, + exchangeBaseUrl: "exchange url", + merchantBaseUrl: "merchant url", + tipAmountEffective: "EUR:1", + walletTipId: "tip_id", + } as PrepareTipResult as any), acceptTip: async () => ({}), } as any, ), diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts index 1794b837b..5097380f6 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/index.ts @@ -21,17 +21,17 @@ import { ButtonHandler, TextFieldHandler } from "../../mui/handlers.js"; import { compose, StateViewMap } from "../../utils/index.js"; import * as wxApi from "../../wxApi.js"; import { useComponentState } from "./state.js"; -import { LoadingUriView, ReadyView, CreatedView } from "./views.js"; +import { LoadingUriView, ReadyView } from "./views.js"; export interface Props { amount: string; onClose: () => Promise<void>; + onSuccess: (tx: string) => Promise<void>; } export type State = | State.Loading | State.LoadingUriError - | State.Created | State.Ready; export namespace State { @@ -49,11 +49,6 @@ export namespace State { error: undefined; cancel: ButtonHandler; } - export interface Created extends BaseInfo { - status: "created"; - talerUri: string; - copyToClipboard: ButtonHandler; - } export interface Ready extends BaseInfo { status: "ready"; invalid: boolean; @@ -69,7 +64,6 @@ export namespace State { const viewMapping: StateViewMap<State> = { loading: Loading, "loading-uri": LoadingUriView, - created: CreatedView, ready: ReadyView, }; diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts index e6397f2e9..03dfc8b18 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/state.ts @@ -21,34 +21,18 @@ import * as wxApi from "../../wxApi.js"; import { Props, State } from "./index.js"; export function useComponentState( - { amount: amountStr, onClose }: Props, + { amount: amountStr, onClose, onSuccess }: Props, api: typeof wxApi, ): State { const amount = Amounts.parseOrThrow(amountStr); const [subject, setSubject] = useState(""); - const [talerUri, setTalerUri] = useState(""); const [operationError, setOperationError] = useState< TalerErrorDetail | undefined >(undefined); - if (talerUri) { - return { - status: "created", - talerUri, - error: undefined, - cancel: { - onClick: onClose, - }, - copyToClipboard: { - onClick: async () => { - navigator.clipboard.writeText(talerUri); - }, - }, - }; - } - async function accept(): Promise<string> { + async function accept(): Promise<void> { try { const resp = await api.initiatePeerPushPayment({ amount: Amounts.stringify(amount), @@ -56,7 +40,7 @@ export function useComponentState( summary: subject, }, }); - return resp.talerUri; + onSuccess(resp.transactionId); } catch (e) { if (e instanceof TalerError) { setOperationError(e.errorDetail); @@ -77,10 +61,7 @@ export function useComponentState( onInput: async (e) => setSubject(e), }, create: { - onClick: async () => { - const uri = await accept(); - setTalerUri(uri); - }, + onClick: accept }, chosenAmount: amount, toBeReceived: amount, diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx b/packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx index c6ce301a9..2746cc153 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/stories.tsx @@ -20,19 +20,12 @@ */ import { createExample } from "../../test-utils.js"; -import { ReadyView, CreatedView } from "./views.js"; +import { ReadyView } from "./views.js"; export default { title: "wallet/transfer create", }; -export const ShowQr = createExample(CreatedView, { - talerUri: - "taler://pay-push/exchange.taler.ar/HS585JK0QCXHJ8Z8QWZA3EBAY5WY7XNC1RR2MHJXSH2Z4WP0YPJ0", - cancel: {}, - copyToClipboard: {}, -}); - export const Ready = createExample(ReadyView, { chosenAmount: { currency: "ARS", diff --git a/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx b/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx index 433980621..297ae4837 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/TransferCreate/views.tsx @@ -38,34 +38,6 @@ export function LoadingUriView({ error }: State.LoadingUriError): VNode { ); } -export function CreatedView({ - talerUri, - copyToClipboard, - cancel, -}: State.Created): VNode { - const { i18n } = useTranslationContext(); - return ( - <WalletAction> - <LogoHeader /> - <SubTitle> - <i18n.Translate>Digital cash transfer</i18n.Translate> - </SubTitle> - <section> - <p>Show this QR to receive the transfer</p> - <QR text={talerUri} /> - </section> - <section> - or - <Button onClick={copyToClipboard.onClick}>Copy the transfer URI</Button> - </section> - <section> - <Link upperCased onClick={cancel.onClick}> - <i18n.Translate>Close</i18n.Translate> - </Link> - </section> - </WalletAction> - ); -} export function ReadyView({ subject, diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts index 914296062..0ffdb1b95 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/index.ts @@ -30,6 +30,7 @@ import { LoadingUriView, ReadyView } from "./views.js"; export interface Props { talerPayPushUri: string; onClose: () => Promise<void>; + onSuccess: (tx: string) => Promise<void>; } export type State = State.Loading | State.LoadingUriError | State.Ready; diff --git a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts index d4c863608..c6cc13b6c 100644 --- a/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts +++ b/packages/taler-wallet-webextension/src/cta/TransferPickup/state.ts @@ -27,7 +27,7 @@ import * as wxApi from "../../wxApi.js"; import { Props, State } from "./index.js"; export function useComponentState( - { talerPayPushUri, onClose }: Props, + { talerPayPushUri, onClose, onSuccess }: Props, api: typeof wxApi, ): State { const hook = useAsyncAsHook(async () => { @@ -68,7 +68,7 @@ export function useComponentState( const resp = await api.acceptPeerPushPayment({ peerPushPaymentIncomingId, }); - await onClose(); + onSuccess(resp.transactionId) } catch (e) { if (e instanceof TalerError) { setOperationError(e.errorDetail); diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts index d777489ab..2d9aaf828 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/index.ts @@ -26,7 +26,6 @@ import { useComponentStateFromURI, } from "./state.js"; import { - CompletedView, LoadingExchangeView, LoadingInfoView, LoadingUriView, @@ -36,11 +35,13 @@ import { export interface PropsFromURI { talerWithdrawUri: string | undefined; cancel: () => Promise<void>; + onSuccess: (txid: string) => Promise<void>; } export interface PropsFromParams { amount: string; cancel: () => Promise<void>; + onSuccess: (txid: string) => Promise<void>; } export type State = @@ -48,8 +49,7 @@ export type State = | State.LoadingUriError | State.LoadingExchangeError | State.LoadingInfoError - | State.Success - | State.Completed; + | State.Success; export namespace State { export interface Loading { @@ -69,11 +69,6 @@ export namespace State { error: HookError; } - export type Completed = { - status: "completed"; - error: undefined; - }; - export type Success = { status: "success"; error: undefined; @@ -100,7 +95,6 @@ const viewMapping: StateViewMap<State> = { "loading-uri": LoadingUriView, "loading-exchange": LoadingExchangeView, "loading-info": LoadingInfoView, - completed: CompletedView, success: SuccessView, }; diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts index 0b174d34c..fca69a669 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/state.ts @@ -23,7 +23,7 @@ import * as wxApi from "../../wxApi.js"; import { PropsFromURI, PropsFromParams, State } from "./index.js"; export function useComponentStateFromParams( - { amount, cancel }: PropsFromParams, + { amount, cancel, onSuccess }: PropsFromParams, api: typeof wxApi, ): State { const [ageRestricted, setAgeRestricted] = useState(0); @@ -40,8 +40,8 @@ export function useComponentStateFromParams( // get the first exchange with the currency as the default one const exchange = exchangeHookDep ? exchangeHookDep.exchanges.find( - (e) => e.currency === chosenAmount.currency, - ) + (e) => e.currency === chosenAmount.currency, + ) : undefined; /** * For the exchange selected, bring the status of the terms of service @@ -90,7 +90,6 @@ export function useComponentStateFromParams( undefined, ); const [doingWithdraw, setDoingWithdraw] = useState<boolean>(false); - const [withdrawCompleted, setWithdrawCompleted] = useState<boolean>(false); if (!exchangeHook) return { status: "loading", error: undefined }; if (exchangeHook.hasError) { @@ -122,7 +121,7 @@ export function useComponentStateFromParams( Amounts.stringify(amount), ); - setWithdrawCompleted(true); + onSuccess(response.transactionId); } catch (e) { if (e instanceof TalerError) { setWithdrawError(e); @@ -143,9 +142,6 @@ export function useComponentStateFromParams( if (!amountHook.response) { return { status: "loading", error: undefined }; } - if (withdrawCompleted) { - return { status: "completed", error: undefined }; - } const withdrawalFee = Amounts.sub( amountHook.response.amount.raw, @@ -156,8 +152,8 @@ export function useComponentStateFromParams( const { state: termsState } = (!terms ? undefined : terms.hasError - ? undefined - : terms.response) || { state: undefined }; + ? undefined + : terms.response) || { state: undefined }; async function onAccept(accepted: boolean): Promise<void> { if (!termsState || !exchange) return; @@ -194,10 +190,10 @@ export function useComponentStateFromParams( //TODO: calculate based on exchange info const ageRestriction = ageRestrictionEnabled ? { - list: ageRestrictionOptions, - value: String(ageRestricted), - onChange: async (v: string) => setAgeRestricted(parseInt(v, 10)), - } + list: ageRestrictionOptions, + value: String(ageRestricted), + onChange: async (v: string) => setAgeRestricted(parseInt(v, 10)), + } : undefined; return { @@ -218,19 +214,19 @@ export function useComponentStateFromParams( tosProps: !termsState ? undefined : { - onAccept, - onReview: setReviewing, - reviewed: reviewed, - reviewing: reviewing, - terms: termsState, - }, + onAccept, + onReview: setReviewing, + reviewed: reviewed, + reviewing: reviewing, + terms: termsState, + }, mustAcceptFirst, cancel, }; } export function useComponentStateFromURI( - { talerWithdrawUri, cancel }: PropsFromURI, + { talerWithdrawUri, cancel, onSuccess }: PropsFromURI, api: typeof wxApi, ): State { const [ageRestricted, setAgeRestricted] = useState(0); @@ -303,7 +299,6 @@ export function useComponentStateFromURI( undefined, ); const [doingWithdraw, setDoingWithdraw] = useState<boolean>(false); - const [withdrawCompleted, setWithdrawCompleted] = useState<boolean>(false); if (!uriInfoHook) return { status: "loading", error: undefined }; if (uriInfoHook.hasError) { @@ -343,8 +338,10 @@ export function useComponentStateFromURI( ); if (res.confirmTransferUrl) { document.location.href = res.confirmTransferUrl; + } else { + onSuccess(res.transactionId) } - setWithdrawCompleted(true); + } catch (e) { if (e instanceof TalerError) { setWithdrawError(e); @@ -365,9 +362,6 @@ export function useComponentStateFromURI( if (!amountHook.response) { return { status: "loading", error: undefined }; } - if (withdrawCompleted) { - return { status: "completed", error: undefined }; - } const withdrawalFee = Amounts.sub( amountHook.response.amount.raw, @@ -378,8 +372,8 @@ export function useComponentStateFromURI( const { state: termsState } = (!terms ? undefined : terms.hasError - ? undefined - : terms.response) || { state: undefined }; + ? undefined + : terms.response) || { state: undefined }; async function onAccept(accepted: boolean): Promise<void> { if (!termsState || !thisExchange) return; @@ -416,10 +410,10 @@ export function useComponentStateFromURI( //TODO: calculate based on exchange info const ageRestriction = ageRestrictionEnabled ? { - list: ageRestrictionOptions, - value: String(ageRestricted), - onChange: async (v: string) => setAgeRestricted(parseInt(v, 10)), - } + list: ageRestrictionOptions, + value: String(ageRestricted), + onChange: async (v: string) => setAgeRestricted(parseInt(v, 10)), + } : undefined; return { @@ -441,12 +435,12 @@ export function useComponentStateFromURI( tosProps: !termsState ? undefined : { - onAccept, - onReview: setReviewing, - reviewed: reviewed, - reviewing: reviewing, - terms: termsState, - }, + onAccept, + onReview: setReviewing, + reviewed: reviewed, + reviewing: reviewing, + terms: termsState, + }, mustAcceptFirst, cancel, }; diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/stories.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw/stories.tsx index 9c4faaf4a..2be4437cc 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/stories.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/stories.tsx @@ -21,7 +21,7 @@ import { createExample } from "../../test-utils.js"; import { TermsState } from "../../utils/index.js"; -import { CompletedView, SuccessView } from "./views.js"; +import { SuccessView } from "./views.js"; export default { title: "cta/withdraw", @@ -179,11 +179,6 @@ export const EditExchangeModified = createExample(SuccessView, { tosProps: normalTosState, }); -export const CompletedWithoutBankURL = createExample(CompletedView, { - status: "completed", - error: undefined, -}); - export const WithAgeRestriction = createExample(SuccessView, { error: undefined, status: "success", diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts index 3a49f2a71..a0c24a6bb 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/test.ts @@ -68,6 +68,7 @@ describe("Withdraw CTA states", () => { cancel: async () => { null; }, + onSuccess: async () => { null }, }, { listExchanges: async () => ({ exchanges }), @@ -108,6 +109,7 @@ describe("Withdraw CTA states", () => { cancel: async () => { null; }, + onSuccess: async () => { null }, }, { listExchanges: async () => ({ exchanges }), @@ -150,6 +152,7 @@ describe("Withdraw CTA states", () => { cancel: async () => { null; }, + onSuccess: async () => { null }, }, { listExchanges: async () => ({ exchanges }), @@ -160,10 +163,10 @@ describe("Withdraw CTA states", () => { }), getExchangeWithdrawalInfo: async (): Promise<ExchangeWithdrawDetails> => - ({ - withdrawalAmountRaw: "ARS:2", - withdrawalAmountEffective: "ARS:2", - } as any), + ({ + withdrawalAmountRaw: "ARS:2", + withdrawalAmountEffective: "ARS:2", + } as any), getExchangeTos: async (): Promise<GetExchangeTosResult> => ({ contentType: "text", content: "just accept", @@ -224,6 +227,7 @@ describe("Withdraw CTA states", () => { cancel: async () => { null; }, + onSuccess: async () => { null }, }, { listExchanges: async () => ({ exchanges }), @@ -234,10 +238,10 @@ describe("Withdraw CTA states", () => { }), getExchangeWithdrawalInfo: async (): Promise<ExchangeWithdrawDetails> => - ({ - withdrawalAmountRaw: "ARS:2", - withdrawalAmountEffective: "ARS:2", - } as any), + ({ + withdrawalAmountRaw: "ARS:2", + withdrawalAmountEffective: "ARS:2", + } as any), getExchangeTos: async (): Promise<GetExchangeTosResult> => ({ contentType: "text", content: "just accept", diff --git a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx index 440586343..60157d289 100644 --- a/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx +++ b/packages/taler-wallet-webextension/src/cta/Withdraw/views.tsx @@ -76,29 +76,6 @@ export function LoadingInfoView({ error }: State.LoadingInfoError): VNode { ); } -export function CompletedView(state: State.Completed): VNode { - const { i18n } = useTranslationContext(); - return ( - <WalletAction> - <LogoHeader /> - <SubTitle> - <i18n.Translate>Digital cash withdrawal</i18n.Translate> - </SubTitle> - <SuccessBox> - <h3> - <i18n.Translate>Withdrawal in process...</i18n.Translate> - </h3> - <p> - <i18n.Translate> - You can close the page now. Check your bank if the transaction need - a confirmation step to be completed - </i18n.Translate> - </p> - </SuccessBox> - </WalletAction> - ); -} - export function SuccessView(state: State.Success): VNode { const { i18n } = useTranslationContext(); return ( diff --git a/packages/taler-wallet-webextension/src/wallet/Application.tsx b/packages/taler-wallet-webextension/src/wallet/Application.tsx index c7e69964b..d2cbf440f 100644 --- a/packages/taler-wallet-webextension/src/wallet/Application.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Application.tsx @@ -249,41 +249,49 @@ export function Application(): VNode { redirectTo(Pages.ctaWithdrawManual({ amount })) } cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid:string) => redirectTo(Pages.balanceTransaction({ tid }))} /> <Route path={Pages.ctaRefund} component={RefundPage} cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid:string) => redirectTo(Pages.balanceTransaction({ tid }))} /> <Route path={Pages.ctaTips} component={TipPage} onCancel={() => redirectTo(Pages.balance)} + onSuccess={(tid:string) => redirectTo(Pages.balanceTransaction({ tid }))} /> <Route path={Pages.ctaWithdraw} component={WithdrawPageFromURI} cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid:string) => redirectTo(Pages.balanceTransaction({ tid }))} /> <Route path={Pages.ctaWithdrawManual.pattern} component={WithdrawPageFromParams} cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid:string) => redirectTo(Pages.balanceTransaction({ tid }))} /> <Route path={Pages.ctaDeposit} component={DepositPageCTA} cancel={() => redirectTo(Pages.balance)} + onSuccess={(tid:string) => redirectTo(Pages.balanceTransaction({ tid }))} /> <Route path={Pages.ctaInvoiceCreate.pattern} component={InvoiceCreatePage} onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid:string) => redirectTo(Pages.balanceTransaction({ tid }))} /> <Route path={Pages.ctaTransferCreate.pattern} component={TransferCreatePage} onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid:string) => redirectTo(Pages.balanceTransaction({ tid }))} /> <Route path={Pages.ctaInvoicePay} @@ -292,11 +300,13 @@ export function Application(): VNode { redirectTo(Pages.ctaWithdrawManual({ amount })) } onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid:string) => redirectTo(Pages.balanceTransaction({ tid }))} /> <Route path={Pages.ctaTransferPickup} component={TransferPickupPage} onClose={() => redirectTo(Pages.balance)} + onSuccess={(tid:string) => redirectTo(Pages.balanceTransaction({ tid }))} /> {/** diff --git a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx index 21cee8789..8318677e3 100644 --- a/packages/taler-wallet-webextension/src/wallet/Transaction.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Transaction.tsx @@ -634,7 +634,7 @@ export function TransactionView({ text={transaction.exchangeBaseUrl} kind="neutral" /> - {transaction.pending && ( + {transaction.pending && ( /** pending is not-pay */ <Part title={<i18n.Translate>URI</i18n.Translate>} text={<ShowQrWithCopy text={transaction.talerUri} />} @@ -720,13 +720,13 @@ export function TransactionView({ text={transaction.exchangeBaseUrl} kind="neutral" /> - {transaction.pending && ( + {/* {transaction.pending && ( //pending is not-received + )} */} <Part title={<i18n.Translate>URI</i18n.Translate>} text={<ShowQrWithCopy text={transaction.talerUri} />} kind="neutral" - /> - )} + /> <Part title={<i18n.Translate>Details</i18n.Translate>} text={ |