aboutsummaryrefslogtreecommitdiff
path: root/popup
diff options
context:
space:
mode:
authorFlorian Dold <florian.dold@gmail.com>2016-11-13 23:30:18 +0100
committerFlorian Dold <florian.dold@gmail.com>2016-11-13 23:31:17 +0100
commitf3fb8be7db6de87dae40d41bd5597a735c800ca1 (patch)
tree1a061db04de8f5bb5a6b697fa56a9948f67fac2f /popup
parent200d83c3886149ebb3f018530302079e12a81f6b (diff)
downloadwallet-core-f3fb8be7db6de87dae40d41bd5597a735c800ca1.tar.xz
restructuring
Diffstat (limited to 'popup')
-rw-r--r--popup/popup.css84
-rw-r--r--popup/popup.html26
-rw-r--r--popup/popup.tsx508
3 files changed, 0 insertions, 618 deletions
diff --git a/popup/popup.css b/popup/popup.css
deleted file mode 100644
index 675412c11..000000000
--- a/popup/popup.css
+++ /dev/null
@@ -1,84 +0,0 @@
-
-/**
- * @author Gabor X. Toth
- * @author Marcello Stanisci
- * @author Florian Dold
- */
-
-body {
- min-height: 20em;
- width: 30em;
- margin: 0;
- padding: 0;
- max-height: 800px;
- overflow: hidden;
-}
-
-.nav {
- background-color: #ddd;
- padding: 0.5em 0;
-}
-
-.nav a {
- color: black;
- padding: 0.5em;
- text-decoration: none;
-}
-
-.nav a.active {
- background-color: white;
- font-weight: bold;
-}
-
-
-.container {
- overflow-y: scroll;
- max-height: 400px;
-}
-
-.abbrev {
- text-decoration-style: dotted;
-}
-
-#content {
- padding: 1em;
-}
-
-
-#wallet-table .amount {
- text-align: right;
-}
-
-.hidden {
- display: none;
-}
-
-#transactions-table th,
-#transactions-table td {
- padding: 0.2em 0.5em;
-}
-
-#reserve-create table {
- width: 100%;
-}
-
-#reserve-create table td.label {
- width: 5em;
-}
-
-#reserve-create table .input input[type="text"] {
- width: 100%;
-}
-
-.historyItem {
- border: 1px solid black;
- border-radius: 10px;
- padding-left: 0.5em;
- margin: 0.5em;
-}
-
-.historyDate {
- font-size: 90%;
- margin: 0.3em;
- color: slategray;
-}
diff --git a/popup/popup.html b/popup/popup.html
deleted file mode 100644
index 9059c0da1..000000000
--- a/popup/popup.html
+++ /dev/null
@@ -1,26 +0,0 @@
-<!DOCTYPE html>
-<html>
-
-<head>
- <meta charset="utf-8">
-
- <link rel="stylesheet" type="text/css" href="../style/lang.css">
- <link rel="stylesheet" type="text/css" href="popup.css">
-
- <script src="../lib/vendor/react.js"></script>
- <script src="../lib/vendor/react-dom.js"></script>
- <script src="../lib/vendor/URI.js"></script>
-
- <script src="../lib/vendor/jed.js"></script>
- <script src="../lib/i18n.js"></script>
- <script src="../i18n/strings.js"></script>
-
- <script src="../lib/vendor/system-csp-production.src.js"></script>
- <script src="../lib/module-trampoline.js"></script>
-</head>
-
-<body>
-<div id="content" style="margin:0;padding:0"></div>
-</body>
-
-</html>
diff --git a/popup/popup.tsx b/popup/popup.tsx
deleted file mode 100644
index fa21d76e3..000000000
--- a/popup/popup.tsx
+++ /dev/null
@@ -1,508 +0,0 @@
-/*
- 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/>
- */
-
-
-/**
- * Popup shown to the user when they click
- * the Taler browser action button.
- *
- * @author Florian Dold
- */
-
-
-"use strict";
-
-import {substituteFulfillmentUrl} from "../lib/wallet/helpers";
-import BrowserClickedEvent = chrome.browserAction.BrowserClickedEvent;
-import {HistoryRecord, HistoryLevel} from "../lib/wallet/wallet";
-import {
- AmountJson, WalletBalance, Amounts,
- WalletBalanceEntry
-} from "../lib/wallet/types";
-import {abbrev, prettyAmount} from "../lib/wallet/renderHtml";
-
-declare var i18n: any;
-
-function onUpdateNotification(f: () => void): () => void {
- let port = chrome.runtime.connect({name: "notifications"});
- let listener = (msg: any, port: any) => {
- f();
- };
- port.onMessage.addListener(listener);
- return () => {
- port.onMessage.removeListener(listener);
- }
-}
-
-
-class Router extends React.Component<any,any> {
- static setRoute(s: string): void {
- window.location.hash = s;
- }
-
- static getRoute(): string {
- // Omit the '#' at the beginning
- return window.location.hash.substring(1);
- }
-
- static onRoute(f: any): () => void {
- Router.routeHandlers.push(f);
- return () => {
- let i = Router.routeHandlers.indexOf(f);
- this.routeHandlers = this.routeHandlers.splice(i, 1);
- }
- }
-
- static routeHandlers: any[] = [];
-
- componentWillMount() {
- console.log("router mounted");
- window.onhashchange = () => {
- this.setState({});
- for (let f of Router.routeHandlers) {
- f();
- }
- }
- }
-
- componentWillUnmount() {
- console.log("router unmounted");
- }
-
-
- render(): JSX.Element {
- let route = window.location.hash.substring(1);
- console.log("rendering route", route);
- let defaultChild: React.ReactChild|null = null;
- let foundChild: React.ReactChild|null = null;
- React.Children.forEach(this.props.children, (child) => {
- let childProps: any = (child as any).props;
- if (!childProps) {
- return;
- }
- if (childProps["default"]) {
- defaultChild = child;
- }
- if (childProps["route"] == route) {
- foundChild = child;
- }
- })
- let child: React.ReactChild | null = foundChild || defaultChild;
- if (!child) {
- throw Error("unknown route");
- }
- Router.setRoute((child as any).props["route"]);
- return <div>{child}</div>;
- }
-}
-
-export function main() {
- console.log("popup main");
-
- let el = (
- <div>
- <WalletNavBar />
- <div style={{margin: "1em"}}>
- <Router>
- <WalletBalanceView route="/balance" default/>
- <WalletHistory route="/history"/>
- <WalletDebug route="/debug"/>
- </Router>
- </div>
- </div>
- );
-
- ReactDOM.render(el, document.getElementById("content")!);
-}
-
-interface TabProps {
- target: string;
- children?: React.ReactNode;
-}
-
-function Tab(props: TabProps) {
- let cssClass = "";
- if (props.target == Router.getRoute()) {
- cssClass = "active";
- }
- let onClick = (e: React.MouseEvent) => {
- Router.setRoute(props.target);
- e.preventDefault();
- };
- return (
- <a onClick={onClick} href={props.target} className={cssClass}>
- {props.children}
- </a>
- );
-}
-
-
-class WalletNavBar extends React.Component<any,any> {
- cancelSubscription: any;
-
- componentWillMount() {
- this.cancelSubscription = Router.onRoute(() => {
- this.setState({});
- });
- }
-
- componentWillUnmount() {
- if (this.cancelSubscription) {
- this.cancelSubscription();
- }
- }
-
- render() {
- console.log("rendering nav bar");
- return (
- <div className="nav" id="header">
- <Tab target="/balance">
- Balance
- </Tab>
- <Tab target="/history">
- History
- </Tab>
- <Tab target="/debug">
- Debug
- </Tab>
- </div>);
- }
-}
-
-
-function ExtensionLink(props: any) {
- let onClick = (e: React.MouseEvent) => {
- chrome.tabs.create({
- "url": chrome.extension.getURL(props.target)
- });
- e.preventDefault();
- };
- return (
- <a onClick={onClick} href={props.target}>
- {props.children}
- </a>)
-}
-
-class WalletBalanceView extends React.Component<any, any> {
- balance: WalletBalance;
- gotError = false;
- canceler: (() => void) | undefined = undefined;
- 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() {
- chrome.runtime.sendMessage({type: "balances"}, (resp) => {
- if (this.unmount) {
- return;
- }
- if (resp.error) {
- this.gotError = true;
- console.error("could not retrieve balances", resp);
- this.setState({});
- return;
- }
- this.gotError = false;
- console.log("got wallet", resp);
- this.balance = resp;
- this.setState({});
- });
- }
-
- renderEmpty(): JSX.Element {
- let helpLink = (
- <ExtensionLink target="pages/help/empty-wallet.html">
- help
- </ExtensionLink>
- );
- return <div>You have no balance to show. Need some
- {" "}{helpLink}{" "}
- getting started?</div>;
- }
-
- formatPending(entry: WalletBalanceEntry): JSX.Element {
- let incoming: JSX.Element | undefined;
- let payment: JSX.Element | undefined;
-
- console.log("available: ", entry.pendingIncoming ? prettyAmount(entry.available) : null);
- console.log("incoming: ", entry.pendingIncoming ? prettyAmount(entry.pendingIncoming) : null);
-
- if (Amounts.isNonZero(entry.pendingIncoming)) {
- incoming = (
- <span>
- <span style={{color: "darkgreen"}}>
- {"+"}
- {prettyAmount(entry.pendingIncoming)}
- </span>
- {" "}
- incoming
- </span>);
- }
-
- if (Amounts.isNonZero(entry.pendingPayment)) {
- payment = (
- <span>
- <span style={{color: "darkblue"}}>
- {prettyAmount(entry.pendingPayment)}
- </span>
- {" "}
- being spent
- </span>);
- }
-
- let l = [incoming, payment].filter((x) => x !== undefined);
- if (l.length == 0) {
- return <span />;
- }
-
- if (l.length == 1) {
- return <span>({l})</span>
- }
- return <span>({l[0]}, {l[1]})</span>;
-
- }
-
- render(): JSX.Element {
- let wallet = this.balance;
- if (this.gotError) {
- return i18n`Error: could not retrieve balance information.`;
- }
- if (!wallet) {
- return <span></span>;
- }
- console.log(wallet);
- let listing = Object.keys(wallet).map((key) => {
- let entry: WalletBalanceEntry = wallet[key];
- return (
- <p>
- {prettyAmount(entry.available)}
- {" "}
- {this.formatPending(entry)}
- </p>
- );
- });
- if (listing.length > 0) {
- return <div>{listing}</div>;
- }
-
- return this.renderEmpty();
- }
-}
-
-
-function formatHistoryItem(historyItem: HistoryRecord) {
- const d = historyItem.detail;
- const t = historyItem.timestamp;
- console.log("hist item", historyItem);
- switch (historyItem.type) {
- case "create-reserve":
- return (
- <p>
- {i18n.parts`Bank requested reserve (${abbrev(d.reservePub)}) for ${prettyAmount(
- d.requestedAmount)}.`}
- </p>
- );
- case "confirm-reserve": {
- // FIXME: eventually remove compat fix
- let exchange = d.exchangeBaseUrl ? URI(d.exchangeBaseUrl).host() : "??";
- let amount = prettyAmount(d.requestedAmount);
- let pub = abbrev(d.reservePub);
- return (
- <p>
- {i18n.parts`Started to withdraw ${amount} from ${exchange} (${pub}).`}
- </p>
- );
- }
- case "offer-contract": {
- let link = chrome.extension.getURL("view-contract.html");
- let linkElem = <a href={link}>{abbrev(d.contractHash)}</a>;
- let merchantElem = <em>{abbrev(d.merchantName, 15)}</em>;
- return (
- <p>
- {i18n.parts`Merchant ${merchantElem} offered contract ${linkElem}.`}
- </p>
- );
- }
- case "depleted-reserve": {
- let exchange = d.exchangeBaseUrl ? URI(d.exchangeBaseUrl).host() : "??";
- let amount = prettyAmount(d.requestedAmount);
- let pub = abbrev(d.reservePub);
- return (<p>
- {i18n.parts`Withdrew ${amount} from ${exchange} (${pub}).`}
- </p>);
- }
- case "pay": {
- let url = substituteFulfillmentUrl(d.fulfillmentUrl,
- {H_contract: d.contractHash});
- let merchantElem = <em>{abbrev(d.merchantName, 15)}</em>;
- let fulfillmentLinkElem = <a href={url} onClick={openTab(url)}>view product</a>;
- return (
- <p>
- {i18n.parts`Paid ${prettyAmount(d.amount)} to merchant ${merchantElem}. (${fulfillmentLinkElem})`}
- </p>);
- }
- default:
- return (<p>i18n`Unknown event (${historyItem.type})`</p>);
- }
-}
-
-
-class WalletHistory extends React.Component<any, any> {
- myHistory: any[];
- gotError = false;
- 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(): JSX.Element {
- console.log("rendering history");
- let history: HistoryRecord[] = this.myHistory;
- if (this.gotError) {
- return i18n`Error: could not retrieve event history`;
- }
-
- if (!history) {
- // We're not ready yet
- return <span />;
- }
-
- let subjectMemo: {[s: string]: boolean} = {};
- let listing: any[] = [];
- for (let record of history.reverse()) {
- if (record.subjectId && subjectMemo[record.subjectId]) {
- continue;
- }
- if (record.level != undefined && record.level < HistoryLevel.User) {
- continue;
- }
- subjectMemo[record.subjectId as string] = true;
-
- let item = (
- <div className="historyItem">
- <div className="historyDate">
- {(new Date(record.timestamp)).toString()}
- </div>
- {formatHistoryItem(record)}
- </div>
- );
-
- listing.push(item);
- }
-
- if (listing.length > 0) {
- return <div className="container">{listing}</div>;
- }
- return <p>{i18n`Your wallet has no events recorded.`}</p>
- }
-
-}
-
-
-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?")) {
- chrome.runtime.sendMessage({type: "reset"});
- window.close();
- }
-}
-
-
-function WalletDebug(props: any) {
- return (<div>
- <p>Debug tools:</p>
- <button onClick={openExtensionPage("popup/popup.html")}>
- wallet tab
- </button>
- <button onClick={openExtensionPage("pages/show-db.html")}>
- show db
- </button>
- <button onClick={openExtensionPage("pages/tree.html")}>
- show tree
- </button>
- <br />
- <button onClick={confirmReset}>
- reset
- </button>
- <button onClick={reload}>
- reload chrome extension
- </button>
- </div>);
-}
-
-
-function openExtensionPage(page: string) {
- return function() {
- chrome.tabs.create({
- "url": chrome.extension.getURL(page)
- });
- }
-}
-
-
-function openTab(page: string) {
- return function() {
- chrome.tabs.create({
- "url": page
- });
- }
-}