diff options
Diffstat (limited to 'extension/pages/confirm-create-reserve.tsx')
-rw-r--r-- | extension/pages/confirm-create-reserve.tsx | 177 |
1 files changed, 148 insertions, 29 deletions
diff --git a/extension/pages/confirm-create-reserve.tsx b/extension/pages/confirm-create-reserve.tsx index 6a130eeff..8cb46559b 100644 --- a/extension/pages/confirm-create-reserve.tsx +++ b/extension/pages/confirm-create-reserve.tsx @@ -14,40 +14,107 @@ TALER; see the file COPYING. If not, If not, see <http://www.gnu.org/licenses/> */ -import {amountToPretty} from "../lib/web-common"; -import {AmountJson, CreateReserveResponse} from "../lib/wallet/wallet"; +import {amountToPretty, canonicalizeBaseUrl} from "../lib/wallet/helpers"; +import {AmountJson, CreateReserveResponse} from "../lib/wallet/types"; + "use strict"; +declare var m: any; -export function main() { - function updateAmount() { - let showAmount = document.getElementById("show-amount"); - console.log("Query is " + JSON.stringify(query)); - let amount = AmountJson.checked(JSON.parse(query.amount)); - showAmount.textContent = amountToPretty(amount); + +/** + * Execute something after a delay, with the possibility + * to reset the delay. + */ +class DelayTimer { + ms: number; + f; + timerId: number = null; + + constructor(ms: number, f) { + this.f = f; + this.ms = ms; + } + + bump() { + if (this.timerId !== null) { + window.clearTimeout(this.timerId); + } + const handler = () => { + this.f(); + }; + this.timerId = window.setTimeout(handler, this.ms); } +} - let url = URI(document.location.href); - let query: any = URI.parseQuery(url.query()); - updateAmount(); +class Controller { + url = null; + errorString = null; + isValidMint = false; + private timer: DelayTimer; + private request: XMLHttpRequest; - document.getElementById("confirm").addEventListener("click", (e) => { - const d = { - mint: (document.getElementById('mint-url') as HTMLInputElement).value, - amount: JSON.parse(query.amount) + constructor() { + this.update(); + this.timer = new DelayTimer(800, () => this.update()); + } + + update() { + const doUpdate = () => { + if (!this.url) { + this.errorString = i18n`Please enter a URL`; + return; + } + this.errorString = null; + let parsedUrl = URI(this.url); + if (parsedUrl.is("relative")) { + this.errorString = i18n`The URL you've entered is not valid (must be absolute)`; + return; + } + + const keysUrl = URI("/keys").absoluteTo(canonicalizeBaseUrl(this.url)); + + console.log(`requesting keys from '${keysUrl}'`); + + this.request = new XMLHttpRequest(); + this.request.onreadystatechange = () => { + if (this.request.readyState == XMLHttpRequest.DONE) { + switch (this.request.status) { + case 200: + this.isValidMint = true; + break; + case 0: + this.errorString = `unknown request error`; + break; + default: + this.errorString = `request failed with status ${this.request.status}`; + break; + } + m.redraw(); + } + }; + this.request.open("get", keysUrl.href()); + this.request.send(); }; - if (!d.mint) { - // FIXME: indicate error instead! - throw Error("mint missing"); - } + doUpdate(); + m.redraw(); + console.log("got update"); + } - if (!d.amount) { - // FIXME: indicate error instead! - throw Error("amount missing"); + reset() { + this.isValidMint = false; + this.errorString = null; + if (this.request) { + this.request.abort(); + this.request = null; } + m.redraw(); + } + confirmReserve(mint: string, amount: AmountJson, callback_url: string) { + const d = {mint, amount}; const cb = (rawResp) => { if (!rawResp) { throw Error("empty response"); @@ -57,20 +124,72 @@ export function main() { let q = { mint: resp.mint, reserve_pub: resp.reservePub, - amount: query.amount, + amount_value: amount.value, + amount_fraction: amount.fraction, + amount_currency: amount.currency, }; - let url = URI(query.callback_url).addQuery(q); + let url = URI(callback_url).addQuery(q); if (!url.is("absolute")) { throw Error("callback url is not absolute"); } + console.log("going to", url.href()); document.location.href = url.href(); } else { - document.body.innerHTML = - `Oops, something went wrong. It looks like the bank could not - transfer funds to the mint. Please go back to your bank's website - to check what happened.`; + this.reset(); + this.errorString = ( + `Oops, something went wrong.` + + `The wallet responded with error status (${rawResp.error}).`); } }; chrome.runtime.sendMessage({type: 'create-reserve', detail: d}, cb); - }); + } + + onUrlChanged(url: string) { + this.reset(); + this.url = url; + this.timer.bump(); + } +} + + +export function main() { + const url = URI(document.location.href); + const query: any = URI.parseQuery(url.query()); + const amount = AmountJson.checked(JSON.parse(query.amount)); + const callback_url = query.callback_url; + + var MintSelection = { + controller: () => new Controller(), + view(ctrl: Controller) { + let controls = []; + let mx = (...args) => controls.push(m(...args)); + + mx("p", + i18n`The bank wants to create a reserve over ${amountToPretty( + amount)}.`); + mx("input.url", + { + type: "text", + spellcheck: false, + oninput: m.withAttr("value", ctrl.onUrlChanged.bind(ctrl)), + }); + + if (ctrl.isValidMint) { + mx("button", { + onclick: () => ctrl.confirmReserve(ctrl.url, + amount, + callback_url) + }, + "Confirm mint selection"); + } + + if (ctrl.errorString) { + mx("p", ctrl.errorString); + } + + return m("div", controls); + } + }; + + m.mount(document.getElementById("mint-selection"), MintSelection); }
\ No newline at end of file |