aboutsummaryrefslogtreecommitdiff
path: root/pages
diff options
context:
space:
mode:
Diffstat (limited to 'pages')
-rw-r--r--pages/confirm-contract.html64
-rw-r--r--pages/confirm-contract.tsx30
-rw-r--r--pages/confirm-create-reserve.html64
-rw-r--r--pages/confirm-create-reserve.tsx130
4 files changed, 240 insertions, 48 deletions
diff --git a/pages/confirm-contract.html b/pages/confirm-contract.html
index 6abb65c67..ec7eab8c1 100644
--- a/pages/confirm-contract.html
+++ b/pages/confirm-contract.html
@@ -5,7 +5,6 @@
<title>Taler Wallet: Confirm Reserve Creation</title>
<link rel="stylesheet" type="text/css" href="../style/lang.css">
- <link rel="stylesheet" type="text/css" href="../style/wallet.css">
<script src="../lib/vendor/URI.js"></script>
<script src="../lib/vendor/mithril.js"></script>
@@ -15,18 +14,65 @@
<script src="../i18n/strings.js"></script>
<script src="../lib/i18n.js"></script>
<script src="../lib/module-trampoline.js"></script>
-</head>
-<body>
- <header>
- <div id="logo"></div>
- <h1>Payment Confirmation</h1>
- </header>
+ <style>
+ #main {
+ border: solid 1px black;
+ border-radius: 10px;
+ margin: auto;
+ max-width: 50%;
+ padding: 2em;
+ }
+
+ button.accept {
+ background-color: #5757D2;
+ border: 1px solid black;
+ border-radius: 5px;
+ margin: 1em 0;
+ padding: 0.5em;
+ font-weight: bold;
+ color: white;
+ }
+ button.linky {
+ background:none!important;
+ border:none;
+ padding:0!important;
+
+ font-family:arial,sans-serif;
+ color:#069;
+ text-decoration:underline;
+ cursor:pointer;
+ }
+
+ input.url {
+ width: 25em;
+ }
- <aside class="sidebar" id="left">
- </aside>
+ button.accept:disabled {
+ background-color: #dedbe8;
+ border: 1px solid white;
+ border-radius: 5px;
+ margin: 1em 0;
+ padding: 0.5em;
+ font-weight: bold;
+ color: #2C2C2C;
+ }
+
+ .errorbox {
+ border: 1px solid;
+ display: inline-block;
+ margin: 1em;
+ padding: 1em;
+ font-weight: bold;
+ background: #FF8A8A;
+ }
+ </style>
+</head>
+
+<body>
<section id="main">
+ <h1>GNU Taler Wallet</h1>
<article id="contract" class="fade"></article>
</section>
</body>
diff --git a/pages/confirm-contract.tsx b/pages/confirm-contract.tsx
index 0c7419c6c..2e055d4f1 100644
--- a/pages/confirm-contract.tsx
+++ b/pages/confirm-contract.tsx
@@ -72,6 +72,7 @@ export function main() {
console.dir(offer);
let contract = offer.contract;
let error = null;
+ let payDisabled = true;
var Contract = {
view(ctrl) {
@@ -87,8 +88,8 @@ export function main() {
_.map(contract.products,
(p: any) => m("li",
`${p.description}: ${prettyAmount(p.price)}`))),
- m("button.confirm-pay", {onclick: doPayment}, i18n`Confirm Payment`),
- m("p", error ? error : []),
+ m("button.accept", {onclick: doPayment, disabled: payDisabled}, i18n`Confirm Payment`),
+ (error ? m("p.errorbox", error) : []),
m(Details, contract)
];
}
@@ -96,6 +97,31 @@ export function main() {
m.mount(document.getElementById("contract"), Contract);
+ function checkPayment() {
+ chrome.runtime.sendMessage({type: 'check-pay', detail: {offer}}, (resp) => {
+ if (resp.error) {
+ console.log("check-pay error", JSON.stringify(resp));
+ switch (resp.error) {
+ case "coins-insufficient":
+ error = "You do not have enough coins of the requested currency.";
+ break;
+ default:
+ error = `Error: ${resp.error}`;
+ break;
+ }
+ payDisabled = true;
+ } else {
+ payDisabled = false;
+ error = null;
+ }
+ m.redraw();
+ window.setTimeout(checkPayment, 300);
+ });
+ }
+
+ checkPayment();
+
+
function doPayment() {
let d = {offer};
chrome.runtime.sendMessage({type: 'confirm-pay', detail: d}, (resp) => {
diff --git a/pages/confirm-create-reserve.html b/pages/confirm-create-reserve.html
index ab0a7c954..1612340e8 100644
--- a/pages/confirm-create-reserve.html
+++ b/pages/confirm-create-reserve.html
@@ -4,8 +4,6 @@
<head>
<title>Taler Wallet: Select Taler Provider</title>
- <link rel="stylesheet" type="text/css" href="../style/wallet.css">
-
<script src="../lib/vendor/URI.js"></script>
<script src="../lib/vendor/mithril.js"></script>
<script src="../lib/vendor/system-csp-production.src.js"></script>
@@ -13,21 +11,63 @@
<script src="../i18n/strings.js"></script>
<script src="../lib/i18n.js"></script>
<script src="../lib/module-trampoline.js"></script>
-</head>
-<body>
- <header>
- <div id="logo"></div>
- <h1>Select Taler Provider</h1>
- </header>
+ <style>
+ #main {
+ border: solid 1px black;
+ border-radius: 10px;
+ margin: auto;
+ max-width: 50%;
+ padding: 2em;
+ }
+
+ button.accept {
+ background-color: #5757D2;
+ border: 1px solid black;
+ border-radius: 5px;
+ margin: 1em 0;
+ padding: 0.5em;
+ font-weight: bold;
+ color: white;
+ }
+ button.linky {
+ background:none!important;
+ border:none;
+ padding:0!important;
+
+ font-family:arial,sans-serif;
+ color:#069;
+ text-decoration:underline;
+ cursor:pointer;
+ }
+
+ input.url {
+ width: 25em;
+ }
- <aside class="sidebar" id="left">
- </aside>
+ table {
+ border-collapse: collapse;
+ }
+ td {
+ border-left: 1px solid black;
+ border-right: 1px solid black;
+ text-align: center;
+ padding: 0.3em;
+ }
+
+ span.spacer {
+ padding-left: 0.5em;
+ padding-right: 0.5em;
+ }
+
+ </style>
+</head>
+
+<body>
<section id="main">
- <article>
+ <h1>GNU Taler Wallet</h1>
<div class="fade" id="exchange-selection"></div>
- </article>
</section>
</body>
diff --git a/pages/confirm-create-reserve.tsx b/pages/confirm-create-reserve.tsx
index be84fff2b..f490451ca 100644
--- a/pages/confirm-create-reserve.tsx
+++ b/pages/confirm-create-reserve.tsx
@@ -76,31 +76,38 @@ class Controller {
callbackUrl: string;
wtTypes: string[];
detailCollapsed = m.prop<boolean>(true);
+ suggestedExchangeUrl: string;
+ complexViewRequested = false;
+ urlOkay = false;
- constructor(initialExchangeUrl: string,
+ constructor(suggestedExchangeUrl: string,
amount: AmountJson,
callbackUrl: string,
wt_types: string[]) {
console.log("creating main controller");
+ this.suggestedExchangeUrl = suggestedExchangeUrl;
this.amount = amount;
this.callbackUrl = callbackUrl;
this.wtTypes = wt_types;
this.timer = new DelayTimer(800, () => this.update());
- this.url(initialExchangeUrl);
+ this.url(suggestedExchangeUrl);
this.update();
}
private update() {
this.timer.stop();
const doUpdate = () => {
+ this.reserveCreationInfo = null;
if (!this.url()) {
- this.statusString = i18n`Please enter a URL`;
+ this.statusString = i18n`Error: URL is empty`;
+ m.redraw(true);
return;
}
this.statusString = null;
let parsedUrl = URI(this.url());
if (parsedUrl.is("relative")) {
- this.statusString = i18n`The URL you've entered is not valid (must be absolute)`;
+ this.statusString = i18n`Error: URL may not be relative`;
+ m.redraw(true);
return;
}
@@ -114,15 +121,15 @@ class Controller {
this.isValidExchange = true;
this.reserveCreationInfo = r;
console.dir(r);
- this.statusString = "The exchange base URL is valid!";
m.endComputation();
})
.catch((e) => {
console.log("get exchange info rejected");
if (e.hasOwnProperty("httpStatus")) {
- this.statusString = `request failed with status ${this.request.status}`;
- } else {
- this.statusString = `unknown request error`;
+ this.statusString = `Error: request failed with status ${this.request.status}`;
+ } else if (e.hasOwnProperty("errorResponse")) {
+ let resp = e.errorResponse;
+ this.statusString = `Error: ${resp.error} (${resp.hint})`;
}
m.endComputation();
});
@@ -130,7 +137,7 @@ class Controller {
doUpdate();
- console.log("got update");
+ console.log("got update", this.url());
}
reset() {
@@ -187,14 +194,82 @@ class Controller {
}
}
-
-function view(ctrl: Controller) {
+function view(ctrl: Controller): any {
let controls = [];
let mx = (x, ...args) => controls.push(m(x, ...args));
mx("p",
- i18n`The bank wants to create a reserve over ${amountToPretty(
- ctrl.amount)}.`);
+ i18n.parts`You are about to withdraw ${m("strong", amountToPretty(
+ ctrl.amount))} from your bank account into your wallet.`);
+
+ if (ctrl.complexViewRequested || !ctrl.suggestedExchangeUrl) {
+ return controls.concat(viewComplex(ctrl));
+ }
+
+ return controls.concat(viewSimple(ctrl));
+}
+
+function viewSimple(ctrl: Controller) {
+ let controls = [];
+ let mx = (x, ...args) => controls.push(m(x, ...args));
+
+ if (ctrl.statusString) {
+ mx("p", "Error: ", ctrl.statusString);
+ mx("button.linky", {
+ onclick: () => {
+ ctrl.complexViewRequested = true;
+ }
+ }, "advanced options");
+ }
+ else if (ctrl.reserveCreationInfo) {
+ mx("button.accept", {
+ onclick: () => ctrl.confirmReserve(ctrl.reserveCreationInfo,
+ ctrl.url(),
+ ctrl.amount,
+ ctrl.callbackUrl),
+ disabled: !ctrl.isValidExchange
+ },
+ "Accept fees and withdraw");
+ mx("span.spacer");
+ mx("button.linky", {
+ onclick: () => {
+ ctrl.complexViewRequested = true;
+ }
+ }, "advanced options");
+ let totalCost = Amounts.add(ctrl.reserveCreationInfo.overhead,
+ ctrl.reserveCreationInfo.withdrawFee).amount;
+ mx("p", `Withdraw cost: ${amountToPretty(totalCost)}`);
+ } else {
+ mx("p", "Please wait ...");
+ }
+
+
+ return controls;
+}
+
+
+function viewComplex(ctrl: Controller) {
+ let controls = [];
+ let mx = (x, ...args) => controls.push(m(x, ...args));
+
+ mx("button.accept", {
+ onclick: () => ctrl.confirmReserve(ctrl.reserveCreationInfo,
+ ctrl.url(),
+ ctrl.amount,
+ ctrl.callbackUrl),
+ disabled: !ctrl.isValidExchange
+ },
+ "Accept fees and withdraw");
+ mx("span.spacer");
+ mx("button.linky", {
+ onclick: () => {
+ ctrl.complexViewRequested = false;
+ }
+ }, "back to simple view");
+
+ mx("br");
+
+
mx("input",
{
className: "url",
@@ -204,18 +279,11 @@ function view(ctrl: Controller) {
oninput: m.withAttr("value", ctrl.onUrlChanged.bind(ctrl)),
});
- mx("button", {
- onclick: () => ctrl.confirmReserve(ctrl.reserveCreationInfo,
- ctrl.url(),
- ctrl.amount,
- ctrl.callbackUrl),
- disabled: !ctrl.isValidExchange
- },
- "Confirm exchange selection");
+ mx("br");
if (ctrl.statusString) {
mx("p", ctrl.statusString);
- } else {
+ } else if (!ctrl.reserveCreationInfo) {
mx("p", "Checking URL, please wait ...");
}
@@ -246,9 +314,21 @@ function view(ctrl: Controller) {
function renderReserveCreationDetails(rci: ReserveCreationInfo) {
let denoms = rci.selectedDenoms;
+ let countByPub = {};
+ let uniq = [];
+
+ denoms.forEach((x: Denomination) => {
+ let c = countByPub[x.denom_pub] || 0;
+ if (c == 0) {
+ uniq.push(x);
+ }
+ c += 1;
+ countByPub[x.denom_pub] = c;
+ });
+
function row(denom: Denomination) {
return m("tr", [
- m("td", denom.pub_hash.substr(0, 5) + "..."),
+ m("td", countByPub[denom.denom_pub] + "x"),
m("td", amountToPretty(denom.value)),
m("td", amountToPretty(denom.fee_withdraw)),
m("td", amountToPretty(denom.fee_refresh)),
@@ -263,13 +343,13 @@ function renderReserveCreationDetails(rci: ReserveCreationInfo) {
m("p", `Overhead: ${overheadStr}`),
m("table", [
m("tr", [
- m("th", "Key Hash"),
+ m("th", "Count"),
m("th", "Value"),
m("th", "Withdraw Fee"),
m("th", "Refresh Fee"),
m("th", "Deposit Fee"),
]),
- denoms.map(row)
+ uniq.map(row)
])
];
}