aboutsummaryrefslogtreecommitdiff
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/demobank-ui/src/hooks/backend.ts55
-rw-r--r--packages/demobank-ui/src/hooks/index.ts12
-rw-r--r--packages/demobank-ui/src/hooks/settings.ts38
3 files changed, 72 insertions, 33 deletions
diff --git a/packages/demobank-ui/src/hooks/backend.ts b/packages/demobank-ui/src/hooks/backend.ts
index 83df53a1a..f7c255ead 100644
--- a/packages/demobank-ui/src/hooks/backend.ts
+++ b/packages/demobank-ui/src/hooks/backend.ts
@@ -14,11 +14,20 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { canonicalizeBaseUrl } from "@gnu-taler/taler-util";
+import {
+ Codec,
+ buildCodecForObject,
+ buildCodecForUnion,
+ canonicalizeBaseUrl,
+ codecForBoolean,
+ codecForConstString,
+ codecForString,
+} from "@gnu-taler/taler-util";
import {
ErrorType,
HttpError,
RequestError,
+ buildStorageKey,
useLocalStorage,
} from "@gnu-taler/web-util/browser";
import {
@@ -51,6 +60,26 @@ interface LoggedOut {
status: "loggedOut";
}
+export const codecForBackendStateLoggedIn = (): Codec<LoggedIn> =>
+ buildCodecForObject<LoggedIn>()
+ .property("status", codecForConstString("loggedIn"))
+ .property("username", codecForString())
+ .property("password", codecForString())
+ .property("isUserAdministrator", codecForBoolean())
+ .build("BackendState.LoggedIn");
+
+export const codecForBackendStateLoggedOut = (): Codec<LoggedOut> =>
+ buildCodecForObject<LoggedOut>()
+ .property("status", codecForConstString("loggedOut"))
+ .build("BackendState.LoggedOut");
+
+export const codecForBackendState = (): Codec<BackendState> =>
+ buildCodecForUnion<BackendState>()
+ .discriminateOn("status")
+ .alternative("loggedIn", codecForBackendStateLoggedIn())
+ .alternative("loggedOut", codecForBackendStateLoggedOut())
+ .build("BackendState");
+
export function getInitialBackendBaseURL(): string {
const overrideUrl =
typeof localStorage !== "undefined"
@@ -79,29 +108,27 @@ export interface BackendStateHandler {
logOut(): void;
logIn(info: BackendCredentials): void;
}
+
+const BACKEND_STATE_KEY = buildStorageKey(
+ "backend-state",
+ codecForBackendState(),
+);
+
/**
* Return getters and setters for
* login credentials and backend's
* base URL.
*/
export function useBackendState(): BackendStateHandler {
- const { value, update } = useLocalStorage(
- "backend-state",
- JSON.stringify(defaultState),
+ const { value: state, update } = useLocalStorage(
+ BACKEND_STATE_KEY,
+ defaultState,
);
- let parsed;
- try {
- parsed = JSON.parse(value!);
- } catch {
- parsed = undefined;
- }
- const state: BackendState = !parsed?.status ? defaultState : parsed;
-
return {
state,
logOut() {
- update(JSON.stringify({ ...defaultState }));
+ update(defaultState);
},
logIn(info) {
//admin is defined by the username
@@ -110,7 +137,7 @@ export function useBackendState(): BackendStateHandler {
...info,
isUserAdministrator: info.username === "admin",
};
- update(JSON.stringify(nextState));
+ update(nextState);
},
};
}
diff --git a/packages/demobank-ui/src/hooks/index.ts b/packages/demobank-ui/src/hooks/index.ts
index 44b0598e6..e9c68812c 100644
--- a/packages/demobank-ui/src/hooks/index.ts
+++ b/packages/demobank-ui/src/hooks/index.ts
@@ -20,7 +20,8 @@
*/
import { StateUpdater } from "preact/hooks";
-import { useLocalStorage } from "@gnu-taler/web-util/browser";
+import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
+import { codecForBoolean } from "@gnu-taler/taler-util";
export type ValueOrFunction<T> = T | ((p: T) => T);
const calculateRootPath = () => {
@@ -31,11 +32,14 @@ const calculateRootPath = () => {
return rootPath;
};
+const BACKEND_URL_KEY = buildStorageKey("backend-url");
+const TRIED_LOGIN_KEY = buildStorageKey("tried-login", codecForBoolean());
+
export function useBackendURL(
url?: string,
): [string, boolean, StateUpdater<string>, () => void] {
const { value, update: setter } = useLocalStorage(
- "backend-url",
+ BACKEND_URL_KEY,
url || calculateRootPath(),
);
@@ -43,10 +47,10 @@ export function useBackendURL(
value: triedToLog,
update: setTriedToLog,
reset: resetBackend,
- } = useLocalStorage("tried-login");
+ } = useLocalStorage(TRIED_LOGIN_KEY);
const checkedSetter = (v: ValueOrFunction<string>) => {
- setTriedToLog("yes");
+ setTriedToLog(true);
const computedValue =
v instanceof Function ? v(value) : v.replace(/\/$/, "");
return setter(computedValue);
diff --git a/packages/demobank-ui/src/hooks/settings.ts b/packages/demobank-ui/src/hooks/settings.ts
index 325b583f9..46b31bf2a 100644
--- a/packages/demobank-ui/src/hooks/settings.ts
+++ b/packages/demobank-ui/src/hooks/settings.ts
@@ -14,36 +14,44 @@
GNU Taler; see the file COPYING. If not, see <http://www.gnu.org/licenses/>
*/
-import { useLocalStorage } from "@gnu-taler/web-util/browser";
+import {
+ Codec,
+ buildCodecForObject,
+ codecForString,
+ codecOptional,
+} from "@gnu-taler/taler-util";
+import { buildStorageKey, useLocalStorage } from "@gnu-taler/web-util/browser";
interface Settings {
currentWithdrawalOperationId: string | undefined;
}
+export const codecForSettings = (): Codec<Settings> =>
+ buildCodecForObject<Settings>()
+ .property("currentWithdrawalOperationId", codecOptional(codecForString()))
+ .build("Settings");
+
const defaultSettings: Settings = {
currentWithdrawalOperationId: undefined,
};
-function parse_json_or_undefined<T>(str: string | undefined): T | undefined {
- if (str === undefined) return undefined;
- try {
- return JSON.parse(str);
- } catch {
- return undefined;
- }
-}
+const DEMOBANK_SETTINGS_KEY = buildStorageKey(
+ "demobank-settings",
+ codecForSettings(),
+);
export function useSettings(): [
Readonly<Settings>,
<T extends keyof Settings>(key: T, value: Settings[T]) => void,
] {
- const { value, update } = useLocalStorage("demobank-settings");
+ const { value, update } = useLocalStorage(
+ DEMOBANK_SETTINGS_KEY,
+ defaultSettings,
+ );
- const parsed: Settings = parse_json_or_undefined(value) ?? defaultSettings;
function updateField<T extends keyof Settings>(k: T, v: Settings[T]) {
- const newValue = { ...parsed, [k]: v };
- const json = JSON.stringify(newValue);
- update(json);
+ const newValue = { ...value, [k]: v };
+ update(newValue);
}
- return [parsed, updateField];
+ return [value, updateField];
}