gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] 04/19: no-fix: move out useBackend hook


From: gnunet
Subject: [taler-wallet-core] 04/19: no-fix: move out useBackend hook
Date: Wed, 07 Dec 2022 20:08:32 +0100

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

commit 54c8d0db31851e9dd0667da77b119994dee38770
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Wed Dec 7 09:29:36 2022 -0300

    no-fix: move out useBackend hook
---
 packages/demobank-ui/src/declaration.d.ts     |   9 --
 packages/demobank-ui/src/hooks/backend.ts     |  34 ++++++
 packages/demobank-ui/src/pages/home/index.tsx | 156 +++++---------------------
 packages/demobank-ui/src/utils.ts             |  49 ++++++++
 packages/demobank-ui/tsconfig.json            |  18 +--
 5 files changed, 123 insertions(+), 143 deletions(-)

diff --git a/packages/demobank-ui/src/declaration.d.ts 
b/packages/demobank-ui/src/declaration.d.ts
index 084686bd2..70272cc54 100644
--- a/packages/demobank-ui/src/declaration.d.ts
+++ b/packages/demobank-ui/src/declaration.d.ts
@@ -23,15 +23,6 @@ declare module "jed" {
  * Type definitions for states and API calls. *
  *********************************************/
 
-/**
- * Has the information to reach and
- * authenticate at the bank's backend.
- */
-interface BackendStateType {
-  url?: string;
-  username?: string;
-  password?: string;
-}
 
 /**
  * Request body of POST /transactions.
diff --git a/packages/demobank-ui/src/hooks/backend.ts 
b/packages/demobank-ui/src/hooks/backend.ts
new file mode 100644
index 000000000..fa4211f13
--- /dev/null
+++ b/packages/demobank-ui/src/hooks/backend.ts
@@ -0,0 +1,34 @@
+import { hooks } from "@gnu-taler/web-util/lib/index.browser";
+import { StateUpdater } from "preact/hooks";
+
+
+/**
+ * Has the information to reach and
+ * authenticate at the bank's backend.
+ */
+export interface BackendStateType {
+  url?: string;
+  username?: string;
+  password?: string;
+}
+
+/**
+ * Return getters and setters for
+ * login credentials and backend's
+ * base URL.
+ */
+type BackendStateTypeOpt = BackendStateType | undefined;
+export function useBackendState(
+  state?: BackendStateType,
+): [BackendStateTypeOpt, StateUpdater<BackendStateTypeOpt>] {
+  const ret = hooks.useLocalStorage("backend-state", JSON.stringify(state));
+  const retObj: BackendStateTypeOpt = ret[0] ? JSON.parse(ret[0]) : ret[0];
+  const retSetter: StateUpdater<BackendStateTypeOpt> = function (val) {
+    const newVal =
+      val instanceof Function
+        ? JSON.stringify(val(retObj))
+        : JSON.stringify(val);
+    ret[1](newVal);
+  };
+  return [retObj, retSetter];
+}
diff --git a/packages/demobank-ui/src/pages/home/index.tsx 
b/packages/demobank-ui/src/pages/home/index.tsx
index a64c4abe3..49fe9e929 100644
--- a/packages/demobank-ui/src/pages/home/index.tsx
+++ b/packages/demobank-ui/src/pages/home/index.tsx
@@ -15,26 +15,26 @@
  */
 
 /* eslint-disable @typescript-eslint/no-explicit-any */
-import { createContext, Fragment, h, VNode } from "preact";
+import { h, Fragment, VNode } from "preact";
 import useSWR, { SWRConfig, useSWRConfig } from "swr";
 
-import {
-  StateUpdater,
-  useContext,
-  useEffect,
-  useRef,
-  useState,
-} from "preact/hooks";
-import talerLogo from "../../assets/logo-white.svg";
-import { LangSelectorLikePy as LangSelector } from 
"../../components/menu/LangSelector.js";
-import { useTranslationContext } from "../../context/translation.js";
 import { Amounts, HttpStatusCode, parsePaytoUri } from "@gnu-taler/taler-util";
+import { hooks } from "@gnu-taler/web-util/lib/index.browser";
 import { createHashHistory } from "history";
 import Router, { Route, route } from "preact-router";
-import { QrCodeSection } from "./QrCodeSection.js";
-import { hooks } from "@gnu-taler/web-util/lib/index.browser";
-import { bankUiSettings } from "../../settings.js";
+import { StateUpdater, useEffect, useRef, useState } from "preact/hooks";
+import talerLogo from "../../assets/logo-white.svg";
+import { LangSelectorLikePy as LangSelector } from 
"../../components/menu/LangSelector.js";
 import { PageStateType, usePageContext } from "../../context/pageState.js";
+import { useTranslationContext } from "../../context/translation.js";
+import { BackendStateType, useBackendState } from "../../hooks/backend.js";
+import { bankUiSettings } from "../../settings.js";
+import { QrCodeSection } from "./QrCodeSection.js";
+import {
+  getBankBackendBaseUrl,
+  getIbanFromPayto,
+  validateAmount,
+} from "../../utils.js";
 
 /**
  * FIXME:
@@ -53,22 +53,6 @@ import { PageStateType, usePageContext } from 
"../../context/pageState.js";
  * - Many strings need to be i18n-wrapped.
  */
 
-/***********
- * Globals *
- **********/
-
-/************
- * Contexts *
- ***********/
-
-/**
- * Bank account specific information.
- */
-// interface AccountStateType {
-//   balance: string;
-//   /* FIXME: Need history here.  */
-// }
-
 /************
  * Helpers. *
  ***********/
@@ -91,57 +75,11 @@ function goPublicAccounts(pageStateSetter: 
StateUpdater<PageStateType>) {
     }));
 }
 
-/**
- * Validate (the number part of) an amount.  If needed,
- * replace comma with a dot.  Returns 'false' whenever
- * the input is invalid, the valid amount otherwise.
- */
-function validateAmount(maybeAmount: string): any {
-  const amountRegex = "^[0-9]+(.[0-9]+)?$";
-  if (!maybeAmount) {
-    console.log(`Entered amount (${maybeAmount}) mismatched <input> pattern.`);
-    return;
-  }
-  if (typeof maybeAmount !== "undefined" || maybeAmount !== "") {
-    console.log(`Maybe valid amount: ${maybeAmount}`);
-    // tolerating comma instead of point.
-    const re = RegExp(amountRegex);
-    if (!re.test(maybeAmount)) {
-      console.log(`Not using invalid amount '${maybeAmount}'.`);
-      return false;
-    }
-  }
-  return maybeAmount;
-}
-
-/**
- * Extract IBAN from a Payto URI.
- */
-function getIbanFromPayto(url: string): string {
-  const pathSplit = new URL(url).pathname.split("/");
-  let lastIndex = pathSplit.length - 1;
-  // Happens if the path ends with "/".
-  if (pathSplit[lastIndex] === "") lastIndex--;
-  const iban = pathSplit[lastIndex];
-  return iban;
-}
-
-/**
- * Extract value and currency from a $currency:x.y amount.
- */
-// function parseAmount(val: string): Amount {
-//   Amounts.parse(val)
-//   const format = /^[A-Z]+:[0-9]+(\.[0-9]+)?$/;
-//   if (!format.test(val)) throw Error(`Backend gave invalid amount: 
${val}.`);
-//   const amountSplit = val.split(":");
-//   return { value: amountSplit[1], currency: amountSplit[0] };
-// }
-
 /**
  * Get username from the backend state, and throw
  * exception if not found.
  */
-function getUsername(backendState: BackendStateTypeOpt): string {
+function getUsername(backendState: BackendStateType | undefined): string {
   if (typeof backendState === "undefined")
     throw Error("Username can't be found in a undefined backend state.");
 
@@ -158,7 +96,7 @@ function getUsername(backendState: BackendStateTypeOpt): 
string {
  */
 async function postToBackend(
   uri: string,
-  backendState: BackendStateTypeOpt,
+  backendState: BackendStateType | undefined,
   body: string,
 ): Promise<any> {
   if (typeof backendState === "undefined")
@@ -203,20 +141,6 @@ function prepareHeaders(username?: string, password?: 
string): Headers {
   return headers;
 }
 
-const getBankBackendBaseUrl = (): string => {
-  const overrideUrl = localStorage.getItem("bank-base-url");
-  if (overrideUrl) {
-    console.log(
-      `using bank base URL ${overrideUrl} (override via bank-base-url 
localStorage)`,
-    );
-    return overrideUrl;
-  }
-  const maybeRootPath = "https://bank.demo.taler.net/demobanks/default/";;
-  if (!maybeRootPath.endsWith("/")) return `${maybeRootPath}/`;
-  console.log(`using bank base URL (${maybeRootPath})`);
-  return maybeRootPath;
-};
-
 /*******************
  * State managers. *
  ******************/
@@ -315,27 +239,6 @@ function useCredentialsRequestType(
   return [retObj, retSetter];
 }
 
-/**
- * Return getters and setters for
- * login credentials and backend's
- * base URL.
- */
-type BackendStateTypeOpt = BackendStateType | undefined;
-function useBackendState(
-  state?: BackendStateType,
-): [BackendStateTypeOpt, StateUpdater<BackendStateTypeOpt>] {
-  const ret = hooks.useLocalStorage("backend-state", JSON.stringify(state));
-  const retObj: BackendStateTypeOpt = ret[0] ? JSON.parse(ret[0]) : ret[0];
-  const retSetter: StateUpdater<BackendStateTypeOpt> = function (val) {
-    const newVal =
-      val instanceof Function
-        ? JSON.stringify(val(retObj))
-        : JSON.stringify(val);
-    ret[1](newVal);
-  };
-  return [retObj, retSetter];
-}
-
 /**
  * Request preparators.
  *
@@ -356,7 +259,7 @@ function useBackendState(
  * Abort a withdrawal operation via the Access API's /abort.
  */
 async function abortWithdrawalCall(
-  backendState: BackendStateTypeOpt,
+  backendState: BackendStateType | undefined,
   withdrawalId: string | undefined,
   pageStateSetter: StateUpdater<PageStateType>,
 ): Promise<void> {
@@ -455,7 +358,7 @@ async function abortWithdrawalCall(
  * 'page state' and let the related components refresh.
  */
 async function confirmWithdrawalCall(
-  backendState: BackendStateTypeOpt,
+  backendState: BackendStateType | undefined,
   withdrawalId: string | undefined,
   pageStateSetter: StateUpdater<PageStateType>,
 ): Promise<void> {
@@ -554,7 +457,7 @@ async function confirmWithdrawalCall(
  */
 async function createTransactionCall(
   req: TransactionRequestType,
-  backendState: BackendStateTypeOpt,
+  backendState: BackendStateType | undefined,
   pageStateSetter: StateUpdater<PageStateType>,
   /**
    * Optional since the raw payto form doesn't have
@@ -623,9 +526,9 @@ async function createTransactionCall(
  * the user about the operation's outcome.  (2) use POST helper.  */
 async function createWithdrawalCall(
   amount: string,
-  backendState: BackendStateTypeOpt,
+  backendState: BackendStateType | undefined,
   pageStateSetter: StateUpdater<PageStateType>,
-) {
+): Promise<void> {
   if (typeof backendState === "undefined") {
     console.log("Page has a problem: no credentials found in the state.");
     pageStateSetter((prevState) => ({
@@ -699,9 +602,9 @@ async function loginCall(
    * FIXME: figure out if the two following
    * functions can be retrieved from the state.
    */
-  backendStateSetter: StateUpdater<BackendStateTypeOpt>,
+  backendStateSetter: StateUpdater<BackendStateType | undefined>,
   pageStateSetter: StateUpdater<PageStateType>,
-) {
+): Promise<void> {
   /**
    * Optimistically setting the state as 'logged in', and
    * let the Account component request the balance to check
@@ -732,9 +635,9 @@ async function registrationCall(
    * functions can be retrieved somewhat from
    * the state.
    */
-  backendStateSetter: StateUpdater<BackendStateTypeOpt>,
+  backendStateSetter: StateUpdater<BackendStateType | undefined>,
   pageStateSetter: StateUpdater<PageStateType>,
-) {
+): Promise<void> {
   let baseUrl = getBankBackendBaseUrl();
   /**
    * If the base URL doesn't end with slash and the path
@@ -1718,8 +1621,10 @@ function LoginForm(Props: any): VNode {
 /**
  * Collect and submit registration data.
  */
-function RegistrationForm(Props: any): VNode {
+function RegistrationForm(): VNode {
   // eslint-disable-next-line @typescript-eslint/no-unused-vars
+
+  const [backendState, backendStateSetter] = useBackendState();
   const { pageState, pageStateSetter } = usePageContext();
   const [submitData, submitDataSetter] = useCredentialsRequestType();
   const { i18n } = useTranslationContext();
@@ -1823,7 +1728,7 @@ function RegistrationForm(Props: any): VNode {
                   if (!submitData) return;
                   registrationCall(
                     { ...submitData },
-                    Props.backendStateSetter, // will store BE URL, if OK.
+                    backendStateSetter, // will store BE URL, if OK.
                     pageStateSetter,
                   );
                   console.log("Clearing the input data");
@@ -2278,7 +2183,6 @@ function PublicHistoriesPage(): VNode {
 }
 
 function RegistrationPage(): VNode {
-  const [backendState, backendStateSetter] = useBackendState();
   const { i18n } = useTranslationContext();
   if (!bankUiSettings.allowRegistrations) {
     return (
@@ -2289,7 +2193,7 @@ function RegistrationPage(): VNode {
   }
   return (
     <BankFrame>
-      <RegistrationForm backendStateSetter={backendStateSetter} />
+      <RegistrationForm />
     </BankFrame>
   );
 }
diff --git a/packages/demobank-ui/src/utils.ts 
b/packages/demobank-ui/src/utils.ts
new file mode 100644
index 000000000..d812f2ec9
--- /dev/null
+++ b/packages/demobank-ui/src/utils.ts
@@ -0,0 +1,49 @@
+
+/**
+ * Validate (the number part of) an amount.  If needed,
+ * replace comma with a dot.  Returns 'false' whenever
+ * the input is invalid, the valid amount otherwise.
+ */
+export function validateAmount(maybeAmount: string): any {
+  const amountRegex = "^[0-9]+(.[0-9]+)?$";
+  if (!maybeAmount) {
+    console.log(`Entered amount (${maybeAmount}) mismatched <input> pattern.`);
+    return;
+  }
+  if (typeof maybeAmount !== "undefined" || maybeAmount !== "") {
+    console.log(`Maybe valid amount: ${maybeAmount}`);
+    // tolerating comma instead of point.
+    const re = RegExp(amountRegex);
+    if (!re.test(maybeAmount)) {
+      console.log(`Not using invalid amount '${maybeAmount}'.`);
+      return false;
+    }
+  }
+  return maybeAmount;
+}
+
+/**
+ * Extract IBAN from a Payto URI.
+ */
+export function getIbanFromPayto(url: string): string {
+  const pathSplit = new URL(url).pathname.split("/");
+  let lastIndex = pathSplit.length - 1;
+  // Happens if the path ends with "/".
+  if (pathSplit[lastIndex] === "") lastIndex--;
+  const iban = pathSplit[lastIndex];
+  return iban;
+}
+
+export function getBankBackendBaseUrl(): string {
+  const overrideUrl = localStorage.getItem("bank-base-url");
+  if (overrideUrl) {
+    console.log(
+      `using bank base URL ${overrideUrl} (override via bank-base-url 
localStorage)`,
+    );
+    return overrideUrl;
+  }
+  const maybeRootPath = "https://bank.demo.taler.net/demobanks/default/";;
+  if (!maybeRootPath.endsWith("/")) return `${maybeRootPath}/`;
+  console.log(`using bank base URL (${maybeRootPath})`);
+  return maybeRootPath;
+}
diff --git a/packages/demobank-ui/tsconfig.json 
b/packages/demobank-ui/tsconfig.json
index d9d56ad4f..61be44bf1 100644
--- a/packages/demobank-ui/tsconfig.json
+++ b/packages/demobank-ui/tsconfig.json
@@ -3,16 +3,20 @@
     /* Basic Options */
     "target": "ES5",
     "module": "ES6",
-    "lib": ["DOM", "ES2016"],
+    "lib": [
+      "DOM",
+      "ES2016"
+    ],
     "allowJs": true /* Allow javascript files to be compiled. */,
     // "checkJs": true,                       /* Report errors in .js files. */
     "jsx": "react-jsx" /* Specify JSX code generation: 'preserve', 
'react-native', or 'react'. */,
     "jsxImportSource": "preact",
+    "jsxFactory": "h",
+    "jsxFragmentFactory": "Fragment",
     "noEmit": true /* Do not emit outputs. */,
     // "importHelpers": true,                 /* Import emit helpers from 
'tslib'. */
     // "downlevelIteration": true,            /* Provide full support for 
iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. 
*/
     // "isolatedModules": true,               /* Transpile each file as a 
separate module (similar to 'ts.transpileModule'). */
-
     /* Strict Type-Checking Options */
     "strict": true /* Enable all strict type-checking options. */,
     "noImplicitAny": true /* Raise error on expressions and declarations with 
an implied 'any' type. */,
@@ -21,7 +25,6 @@
     // "noUnusedParameters": true,            /* Report errors on unused 
parameters. */
     // "noImplicitReturns": true,             /* Report error when not all 
code paths in function return a value. */
     // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough 
cases in switch statement. */
-
     /* Module Resolution Options */
     "moduleResolution": "Node" /* Specify module resolution strategy: 'node' 
(Node.js) or 'classic' (TypeScript pre-1.6). */,
     "esModuleInterop": true /* */,
@@ -32,19 +35,18 @@
     // "types": [],                           /* Type declaration files to be 
included in compilation. */
     "allowSyntheticDefaultImports": true /* Allow default imports from modules 
with no default export. This does not affect code emit, just typechecking. */,
     // "preserveSymlinks": true,              /* Do not resolve the real path 
of symlinks. */
-
     /* Source Map Options */
     // "sourceRoot": "./",                    /* Specify the location where 
debugger should locate TypeScript files instead of source locations. */
     // "mapRoot": "./",                       /* Specify the location where 
debugger should locate map files instead of generated locations. */
     // "inlineSourceMap": true,               /* Emit a single file with 
source maps instead of having a separate file. */
     // "inlineSources": true,                 /* Emit the source alongside the 
sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' 
to be set. */
-
     /* Experimental Options */
     // "experimentalDecorators": true,        /* Enables experimental support 
for ES7 decorators. */
     // "emitDecoratorMetadata": true,         /* Enables experimental support 
for emitting type metadata for decorators. */
-
     /* Advanced Options */
     "skipLibCheck": true /* Skip type checking of declaration files. */
   },
-  "include": ["src/**/*"]
-}
+  "include": [
+    "src/**/*"
+  ]
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]