use new local storage api
This commit is contained in:
parent
d4dd82eda1
commit
be9d3dad83
@ -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);
|
||||
},
|
||||
};
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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];
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user