webpackJsonp([8],{

/***/ 161:
/***/ (function(module, exports, __webpack_require__) {

"use strict";

/*
 This file is part of TALER
 (C) 2016 GNUnet e.V.

 TALER is free software; you can redistribute it and/or modify it under the
 terms of the GNU General Public License as published by the Free Software
 Foundation; either version 3, or (at your option) any later version.

 TALER is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 TALER; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
Object.defineProperty(exports, "__esModule", { value: true });
/**
 * Popup shown to the user when they click
 * the Taler browser action button.
 *
 * @author Florian Dold
 */
/**
 * Imports.
 */
const i18n = __webpack_require__(7);
const Amounts = __webpack_require__(4);
const renderHtml_1 = __webpack_require__(5);
const wxApi = __webpack_require__(2);
const React = __webpack_require__(1);
const ReactDOM = __webpack_require__(3);
const URI = __webpack_require__(6);
function onUpdateNotification(f) {
    const port = chrome.runtime.connect({ name: "notifications" });
    const listener = () => {
        f();
    };
    port.onMessage.addListener(listener);
    return () => {
        port.onMessage.removeListener(listener);
    };
}
class Router extends React.Component {
    static setRoute(s) {
        window.location.hash = s;
    }
    static getRoute() {
        // Omit the '#' at the beginning
        return window.location.hash.substring(1);
    }
    static onRoute(f) {
        Router.routeHandlers.push(f);
        return () => {
            const i = Router.routeHandlers.indexOf(f);
            this.routeHandlers = this.routeHandlers.splice(i, 1);
        };
    }
    componentWillMount() {
        console.log("router mounted");
        window.onhashchange = () => {
            this.setState({});
            for (const f of Router.routeHandlers) {
                f();
            }
        };
    }
    componentWillUnmount() {
        console.log("router unmounted");
    }
    render() {
        const route = window.location.hash.substring(1);
        console.log("rendering route", route);
        let defaultChild = null;
        let foundChild = null;
        React.Children.forEach(this.props.children, (child) => {
            const childProps = child.props;
            if (!childProps) {
                return;
            }
            if (childProps.default) {
                defaultChild = child;
            }
            if (childProps.route === route) {
                foundChild = child;
            }
        });
        const c = foundChild || defaultChild;
        if (!c) {
            throw Error("unknown route");
        }
        Router.setRoute(c.props.route);
        return React.createElement("div", null, c);
    }
}
Router.routeHandlers = [];
function Tab(props) {
    let cssClass = "";
    if (props.target === Router.getRoute()) {
        cssClass = "active";
    }
    const onClick = (e) => {
        Router.setRoute(props.target);
        e.preventDefault();
    };
    return (React.createElement("a", { onClick: onClick, href: props.target, className: cssClass }, props.children));
}
class WalletNavBar extends React.Component {
    componentWillMount() {
        this.cancelSubscription = Router.onRoute(() => {
            this.setState({});
        });
    }
    componentWillUnmount() {
        if (this.cancelSubscription) {
            this.cancelSubscription();
        }
    }
    render() {
        console.log("rendering nav bar");
        return (React.createElement("div", { className: "nav", id: "header" },
            React.createElement(Tab, { target: "/balance" }, i18n.str `Balance`),
            React.createElement(Tab, { target: "/history" }, i18n.str `History`),
            React.createElement(Tab, { target: "/debug" }, i18n.str `Debug`)));
    }
}
function ExtensionLink(props) {
    const onClick = (e) => {
        chrome.tabs.create({
            url: chrome.extension.getURL(props.target),
        });
        e.preventDefault();
    };
    return (React.createElement("a", { onClick: onClick, href: props.target }, props.children));
}
/**
 * Render an amount as a large number with a small currency symbol.
 */
function bigAmount(amount) {
    const v = amount.value + amount.fraction / Amounts.fractionalBase;
    return (React.createElement("span", null,
        React.createElement("span", { style: { fontSize: "300%" } }, v),
        " ",
        React.createElement("span", null, amount.currency)));
}
class WalletBalanceView extends React.Component {
    constructor() {
        super(...arguments);
        this.gotError = false;
        this.canceler = undefined;
        this.unmount = false;
    }
    componentWillMount() {
        this.canceler = onUpdateNotification(() => this.updateBalance());
        this.updateBalance();
    }
    componentWillUnmount() {
        console.log("component WalletBalanceView will unmount");
        if (this.canceler) {
            this.canceler();
        }
        this.unmount = true;
    }
    updateBalance() {
        return __awaiter(this, void 0, void 0, function* () {
            let balance;
            try {
                balance = yield wxApi.getBalance();
            }
            catch (e) {
                if (this.unmount) {
                    return;
                }
                this.gotError = true;
                console.error("could not retrieve balances", e);
                this.setState({});
                return;
            }
            if (this.unmount) {
                return;
            }
            this.gotError = false;
            console.log("got balance", balance);
            this.balance = balance;
            this.setState({});
        });
    }
    renderEmpty() {
        const helpLink = (React.createElement(ExtensionLink, { target: "/src/webex/pages/help/empty-wallet.html" }, i18n.str `help`));
        return (React.createElement("div", null,
            React.createElement(i18n.Translate, { wrap: "p" },
                "You have no balance to show. Need some",
                " ",
                React.createElement("span", null, helpLink),
                " ",
                "getting started?")));
    }
    formatPending(entry) {
        let incoming;
        let payment;
        console.log("available: ", entry.pendingIncoming ? renderHtml_1.renderAmount(entry.available) : null);
        console.log("incoming: ", entry.pendingIncoming ? renderHtml_1.renderAmount(entry.pendingIncoming) : null);
        if (Amounts.isNonZero(entry.pendingIncoming)) {
            incoming = (React.createElement(i18n.Translate, { wrap: "span" },
                React.createElement("span", { style: { color: "darkgreen" } },
                    "+",
                    renderHtml_1.renderAmount(entry.pendingIncoming)),
                " ",
                "incoming"));
        }
        if (Amounts.isNonZero(entry.pendingPayment)) {
            payment = (React.createElement(i18n.Translate, { wrap: "span" },
                React.createElement("span", { style: { color: "red" } },
                    "-",
                    renderHtml_1.renderAmount(entry.pendingPayment)),
                " ",
                "being spent"));
        }
        const l = [incoming, payment].filter((x) => x !== undefined);
        if (l.length === 0) {
            return React.createElement("span", null);
        }
        if (l.length === 1) {
            return React.createElement("span", null,
                "(",
                l,
                ")");
        }
        return React.createElement("span", null,
            "(",
            l[0],
            ", ",
            l[1],
            ")");
    }
    render() {
        const wallet = this.balance;
        if (this.gotError) {
            return i18n.str `Error: could not retrieve balance information.`;
        }
        if (!wallet) {
            return React.createElement("span", null);
        }
        console.log(wallet);
        let paybackAvailable = false;
        const listing = Object.keys(wallet.byCurrency).map((key) => {
            const entry = wallet.byCurrency[key];
            if (entry.paybackAmount.value !== 0 || entry.paybackAmount.fraction !== 0) {
                paybackAvailable = true;
            }
            return (React.createElement("p", null,
                bigAmount(entry.available),
                " ",
                this.formatPending(entry)));
        });
        const makeLink = (page, name) => {
            const url = chrome.extension.getURL(`/src/webex/pages/${page}`);
            return React.createElement("div", null,
                React.createElement("a", { className: "actionLink", href: url, target: "_blank" }, name));
        };
        return (React.createElement("div", null,
            listing.length > 0 ? listing : this.renderEmpty(),
            paybackAvailable && makeLink("payback", i18n.str `Payback`),
            makeLink("return-coins.html#dissolve", i18n.str `Return Electronic Cash to Bank Account`),
            makeLink("auditors.html", i18n.str `Manage Trusted Auditors and Exchanges`)));
    }
}
function formatHistoryItem(historyItem) {
    const d = historyItem.detail;
    console.log("hist item", historyItem);
    switch (historyItem.type) {
        case "create-reserve":
            return (React.createElement(i18n.Translate, { wrap: "p" },
                "Bank requested reserve (",
                React.createElement("span", null, renderHtml_1.abbrev(d.reservePub)),
                ") for",
                " ",
                React.createElement("span", null, renderHtml_1.renderAmount(d.requestedAmount)),
                "."));
        case "confirm-reserve": {
            const exchange = (new URI(d.exchangeBaseUrl)).host();
            const pub = renderHtml_1.abbrev(d.reservePub);
            return (React.createElement(i18n.Translate, { wrap: "p" },
                "Started to withdraw",
                React.createElement("span", null, renderHtml_1.renderAmount(d.requestedAmount)),
                "from ",
                React.createElement("span", null, exchange),
                " (",
                React.createElement("span", null, pub),
                ")."));
        }
        case "offer-contract": {
            return (React.createElement(i18n.Translate, { wrap: "p" },
                "Merchant ",
                React.createElement("em", null, renderHtml_1.abbrev(d.merchantName, 15)),
                " offered contract ",
                React.createElement("span", null, renderHtml_1.abbrev(d.contractTermsHash)),
                "."));
        }
        case "depleted-reserve": {
            const exchange = d.exchangeBaseUrl ? (new URI(d.exchangeBaseUrl)).host() : "??";
            const amount = renderHtml_1.renderAmount(d.requestedAmount);
            const pub = renderHtml_1.abbrev(d.reservePub);
            return (React.createElement(i18n.Translate, { wrap: "p" },
                "Withdrew ",
                React.createElement("span", null, amount),
                " from ",
                React.createElement("span", null, exchange),
                " (",
                React.createElement("span", null, pub),
                ")."));
        }
        case "pay": {
            const url = d.fulfillmentUrl;
            const merchantElem = React.createElement("em", null, renderHtml_1.abbrev(d.merchantName, 15));
            const fulfillmentLinkElem = React.createElement("a", { href: url, onClick: openTab(url) }, "view product");
            return (React.createElement(i18n.Translate, { wrap: "p" },
                "Paid ",
                React.createElement("span", null, renderHtml_1.renderAmount(d.amount)),
                " to merchant ",
                React.createElement("span", null, merchantElem),
                ".",
                React.createElement("span", null, " "),
                "(",
                React.createElement("span", null, fulfillmentLinkElem),
                ")"));
        }
        case "refund": {
            const merchantElem = React.createElement("em", null, renderHtml_1.abbrev(d.merchantName, 15));
            return (React.createElement(i18n.Translate, { wrap: "p" },
                "Merchant ",
                React.createElement("span", null, merchantElem),
                " gave a refund over ",
                React.createElement("span", null, renderHtml_1.renderAmount(d.refundAmount)),
                "."));
        }
        case "tip": {
            const tipPageUrl = new URI(chrome.extension.getURL("/src/webex/pages/tip.html"));
            const params = { tip_id: d.tipId, merchant_domain: d.merchantDomain };
            const url = tipPageUrl.query(params).href();
            const tipLink = React.createElement("a", { href: url, onClick: openTab(url) }, i18n.str `tip`);
            // i18n: Tip
            return (React.createElement(React.Fragment, null,
                React.createElement(i18n.Translate, { wrap: "p" },
                    "Merchant ",
                    React.createElement("span", null, d.merchantDomain),
                    " gave a ",
                    React.createElement("span", null, tipLink),
                    " of ",
                    React.createElement("span", null, renderHtml_1.renderAmount(d.amount)),
                    "."),
                React.createElement("span", null,
                    " ",
                    d.accepted ? null : React.createElement(i18n.Translate, null, "You did not accept the tip yet."))));
        }
        default:
            return (React.createElement("p", null, i18n.str `Unknown event (${historyItem.type})`));
    }
}
class WalletHistory extends React.Component {
    constructor() {
        super(...arguments);
        this.gotError = false;
        this.unmounted = false;
    }
    componentWillMount() {
        this.update();
        onUpdateNotification(() => this.update());
    }
    componentWillUnmount() {
        console.log("history component unmounted");
        this.unmounted = true;
    }
    update() {
        chrome.runtime.sendMessage({ type: "get-history" }, (resp) => {
            if (this.unmounted) {
                return;
            }
            console.log("got history response");
            if (resp.error) {
                this.gotError = true;
                console.error("could not retrieve history", resp);
                this.setState({});
                return;
            }
            this.gotError = false;
            console.log("got history", resp.history);
            this.myHistory = resp.history;
            this.setState({});
        });
    }
    render() {
        console.log("rendering history");
        const history = this.myHistory;
        if (this.gotError) {
            return i18n.str `Error: could not retrieve event history`;
        }
        if (!history) {
            // We're not ready yet
            return React.createElement("span", null);
        }
        const listing = [];
        for (const record of history.reverse()) {
            const item = (React.createElement("div", { className: "historyItem" },
                React.createElement("div", { className: "historyDate" }, (new Date(record.timestamp)).toString()),
                formatHistoryItem(record)));
            listing.push(item);
        }
        if (listing.length > 0) {
            return React.createElement("div", { className: "container" }, listing);
        }
        return React.createElement("p", null, i18n.str `Your wallet has no events recorded.`);
    }
}
function reload() {
    try {
        chrome.runtime.reload();
        window.close();
    }
    catch (e) {
        // Functionality missing in firefox, ignore!
    }
}
function confirmReset() {
    if (confirm("Do you want to IRREVOCABLY DESTROY everything inside your" +
        " wallet and LOSE ALL YOUR COINS?")) {
        wxApi.resetDb();
        window.close();
    }
}
function WalletDebug(props) {
    return (React.createElement("div", null,
        React.createElement("p", null, "Debug tools:"),
        React.createElement("button", { onClick: openExtensionPage("/src/webex/pages/popup.html") }, "wallet tab"),
        React.createElement("button", { onClick: openExtensionPage("/src/webex/pages/show-db.html") }, "show db"),
        React.createElement("button", { onClick: openExtensionPage("/src/webex/pages/tree.html") }, "show tree"),
        React.createElement("button", { onClick: openExtensionPage("/src/webex/pages/logs.html") }, "show logs"),
        React.createElement("br", null),
        React.createElement("button", { onClick: confirmReset }, "reset"),
        React.createElement("button", { onClick: reload }, "reload chrome extension")));
}
function openExtensionPage(page) {
    return () => {
        chrome.tabs.create({
            url: chrome.extension.getURL(page),
        });
    };
}
function openTab(page) {
    return (evt) => {
        evt.preventDefault();
        chrome.tabs.create({
            url: page,
        });
    };
}
const el = (React.createElement("div", null,
    React.createElement(WalletNavBar, null),
    React.createElement("div", { style: { margin: "1em" } },
        React.createElement(Router, null,
            React.createElement(WalletBalanceView, { route: "/balance", default: true }),
            React.createElement(WalletHistory, { route: "/history" }),
            React.createElement(WalletDebug, { route: "/debug" })))));
document.addEventListener("DOMContentLoaded", () => {
    ReactDOM.render(el, document.getElementById("content"));
    // Will be used by the backend to detect when the popup gets closed,
    // so we can clear notifications
    chrome.runtime.connect({ name: "popup" });
});


/***/ })

},[161]);
//# sourceMappingURL=popup-bundle.js.map