gnunet-svn
[Top][All Lists]
Advanced

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

[GNUnet-SVN] [taler-wallet-webex] branch master updated: implement flick


From: gnunet
Subject: [GNUnet-SVN] [taler-wallet-webex] branch master updated: implement flicker-free refunds
Date: Mon, 22 Jan 2018 01:12:23 +0100

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

dold pushed a commit to branch master
in repository wallet-webex.

The following commit(s) were added to refs/heads/master by this push:
     new ae177549 implement flicker-free refunds
ae177549 is described below

commit ae177549a5818e2698253ef17a11b1effbd66fdb
Author: Florian Dold <address@hidden>
AuthorDate: Mon Jan 22 01:12:08 2018 +0100

    implement flicker-free refunds
---
 src/wallet.ts              |  8 ++++++--
 src/webex/messages.ts      |  4 ++++
 src/webex/pages/refund.tsx | 33 +++++++++++++++++++++++++++------
 src/webex/wxApi.ts         |  7 +++++++
 src/webex/wxBackend.ts     | 22 +++++++++++++++++++---
 5 files changed, 63 insertions(+), 11 deletions(-)

diff --git a/src/wallet.ts b/src/wallet.ts
index 9498fe82..01db8c61 100644
--- a/src/wallet.ts
+++ b/src/wallet.ts
@@ -2532,6 +2532,10 @@ export class Wallet {
     }
   }
 
+  /**
+   * Accept a refund, return the contract hash for the contract
+   * that was involved in the refund.
+   */
   async acceptRefund(refundUrl: string): Promise<string> {
     console.log("processing refund");
     let resp;
@@ -2598,7 +2602,8 @@ export class Wallet {
     return refundPermissions[0].h_contract_terms;
   }
 
-  async submitRefunds(contractTermsHash: string): Promise<void> {
+
+  private async submitRefunds(contractTermsHash: string): Promise<void> {
     const purchase = await this.q().get(Stores.purchases, contractTermsHash);
     if (!purchase) {
       console.error("not submitting refunds, contract terms not found:", 
contractTermsHash);
@@ -2644,7 +2649,6 @@ export class Wallet {
         return c;
       };
 
-
       await this.q()
                 .mutate(Stores.purchases, contractTermsHash, transformPurchase)
                 .mutate(Stores.coins, perm.coin_pub, transformCoin)
diff --git a/src/webex/messages.ts b/src/webex/messages.ts
index e1bd6f12..2219cdf1 100644
--- a/src/webex/messages.ts
+++ b/src/webex/messages.ts
@@ -195,6 +195,10 @@ export interface MessageMap {
     request: { contractTermsHash: string, sessionId: string | undefined };
     response: void;
   };
+  "accept-refund": {
+    request: { refundUrl: string }
+    response: string;
+  };
 }
 
 /**
diff --git a/src/webex/pages/refund.tsx b/src/webex/pages/refund.tsx
index 3e82f366..8164eb66 100644
--- a/src/webex/pages/refund.tsx
+++ b/src/webex/pages/refund.tsx
@@ -35,10 +35,12 @@ import { AmountDisplay } from "../renderHtml";
 import * as wxApi from "../wxApi";
 
 interface RefundStatusViewProps {
-  contractTermsHash: string;
+  contractTermsHash?: string;
+  refundUrl?: string;
 }
 
 interface RefundStatusViewState {
+  contractTermsHash?: string;
   purchase?: dbTypes.PurchaseRecord;
   refundFees?: AmountJson;
   gotResult: boolean;
@@ -102,13 +104,22 @@ class RefundStatusView extends 
React.Component<RefundStatusViewProps, RefundStat
   }
 
   render(): JSX.Element {
+    if (!this.props.contractTermsHash && !this.props.refundUrl) {
+      return (
+        <div id="main">
+          <span>Error: Neither contract terms hash nor refund url given.</span>
+        </div>
+      );
+    }
     const purchase = this.state.purchase;
     if (!purchase) {
+      let message;
       if (this.state.gotResult) {
-        return <span>No purchase with contract terms hash 
{this.props.contractTermsHash} found</span>;
+        message = <span>No purchase with contract terms hash 
{this.props.contractTermsHash} found</span>;
       } else {
-        return <span>...</span>;
+        message = <span>...</span>;
       }
+      return <div id="main">{message}</div>;
     }
     const merchantName = purchase.contractTerms.merchant.name || "(unknown)";
     const summary = purchase.contractTerms.summary || 
purchase.contractTerms.order_id;
@@ -128,7 +139,16 @@ class RefundStatusView extends 
React.Component<RefundStatusViewProps, RefundStat
   }
 
   async update() {
-    const purchase = await wxApi.getPurchase(this.props.contractTermsHash);
+    let contractTermsHash = this.state.contractTermsHash;
+    if (!contractTermsHash) {
+      const refundUrl = this.props.refundUrl;
+      if (!refundUrl) {
+        console.error("neither contractTermsHash nor refundUrl is given");
+        return;
+      }
+      contractTermsHash = await wxApi.acceptRefund(refundUrl);
+    }
+    const purchase = await wxApi.getPurchase(contractTermsHash);
     console.log("got purchase", purchase);
     const refundsDone = Object.keys(purchase.refundsDone).map((x) => 
purchase.refundsDone[x]);
     const refundFees = await wxApi.getFullRefundFees( {refundPermissions: 
refundsDone });
@@ -147,8 +167,9 @@ async function main() {
     return;
   }
 
-  const contractTermsHash = query.contractTermsHash || "(none)";
-  ReactDOM.render(<RefundStatusView contractTermsHash={contractTermsHash} />, 
container);
+  const contractTermsHash = query.contractTermsHash;
+  const refundUrl = query.refundUrl;
+  ReactDOM.render(<RefundStatusView contractTermsHash={contractTermsHash} 
refundUrl={refundUrl} />, container);
 }
 
 document.addEventListener("DOMContentLoaded", () => main());
diff --git a/src/webex/wxApi.ts b/src/webex/wxApi.ts
index 566f4526..8a7bf825 100644
--- a/src/webex/wxApi.ts
+++ b/src/webex/wxApi.ts
@@ -363,3 +363,10 @@ export function talerPay(msg: any): Promise<void> {
 export function downloadProposal(url: string): Promise<number> {
   return callBackend("download-proposal", { url });
 }
+
+/**
+ * Download a refund and accept it.
+ */
+export function acceptRefund(refundUrl: string): Promise<string> {
+  return callBackend("accept-refund", { refundUrl });
+}
diff --git a/src/webex/wxBackend.ts b/src/webex/wxBackend.ts
index 26b8ff2c..98b543d2 100644
--- a/src/webex/wxBackend.ts
+++ b/src/webex/wxBackend.ts
@@ -292,6 +292,8 @@ function handleMessage(sender: MessageSender,
     }
     case "get-full-refund-fees":
       return needsWallet().getFullRefundFees(detail.refundPermissions);
+    case "accept-refund":
+      return needsWallet().acceptRefund(detail.refundUrl);
     case "get-tip-status": {
       const tipToken = TipToken.checked(detail.tipToken);
       return needsWallet().getTipStatus(tipToken);
@@ -430,8 +432,8 @@ async function talerPay(fields: any, url: string, tabId: 
number): Promise<string
   }
   if (fields.refund_url) {
     console.log("processing refund");
-    const hc = await w.acceptRefund(fields.refund_url);
-    return 
chrome.extension.getURL(`/src/webex/pages/refund.html?contractTermsHash=${hc}`);
+    const uri = new 
URI(chrome.extension.getURL("/src/webex/pages/refund.html"));
+    return uri.query({ refundUrl: fields.refund_url }).href();
   }
   if (fields.tip) {
     const uri = new URI(chrome.extension.getURL("/src/webex/pages/tip.html"));
@@ -507,10 +509,24 @@ function handleHttpPayment(headerList: 
chrome.webRequest.HttpHeader[], url: stri
     return { redirectUrl: uri.href() };
   }
 
+  // Synchronous fast path for refund
+  if (fields.refund_url) {
+    console.log("processing refund");
+    const uri = new 
URI(chrome.extension.getURL("/src/webex/pages/refund.html"));
+    uri.query({ refundUrl: fields.refund_url });
+    return { redirectUrl: uri.href };
+  }
+
   // We need to do some asynchronous operation, we can't directly redirect
   talerPay(fields, url, tabId).then((nextUrl) => {
     if (nextUrl) {
-      chrome.tabs.update(tabId, { url: nextUrl });
+      // We use chrome.tabs.executeScript instead of chrome.tabs.update
+      // because the latter is buggy when it does not execute in the same
+      // (micro-?)task as the header callback.
+      chrome.tabs.executeScript({
+        code: `document.location.href = 
decodeURIComponent("${encodeURI(nextUrl)}");`,
+        runAt: "document_start",
+      });
     }
   });
 

-- 
To stop receiving notification emails like this one, please contact
address@hidden



reply via email to

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