diff options
Diffstat (limited to 'pages')
-rw-r--r-- | pages/confirm-contract.html | 64 | ||||
-rw-r--r-- | pages/confirm-contract.tsx | 30 | ||||
-rw-r--r-- | pages/confirm-create-reserve.html | 64 | ||||
-rw-r--r-- | pages/confirm-create-reserve.tsx | 130 |
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) ]) ]; } |