diff --git a/packages/taler-wallet-webextension/src/NavigationBar.tsx b/packages/taler-wallet-webextension/src/NavigationBar.tsx index 4f105aa10..b0a7a1016 100644 --- a/packages/taler-wallet-webextension/src/NavigationBar.tsx +++ b/packages/taler-wallet-webextension/src/NavigationBar.tsx @@ -138,9 +138,14 @@ export function PopupNavBar({ path = "" }: { path?: string }): VNode { > Balance - - Backup - + + + Backup + +
Balance - - Backup - - + + Backup + + Dev diff --git a/packages/taler-wallet-webextension/src/context/devContext.ts b/packages/taler-wallet-webextension/src/context/devContext.ts index b710716b5..c494b9403 100644 --- a/packages/taler-wallet-webextension/src/context/devContext.ts +++ b/packages/taler-wallet-webextension/src/context/devContext.ts @@ -21,16 +21,17 @@ import { createContext, h, VNode } from "preact"; import { useContext } from "preact/hooks"; -import { useLocalStorage } from "../hooks/useLocalStorage.js"; +import { useWalletDevMode } from "../hooks/useWalletDevMode.js"; +import { ToggleHandler } from "../mui/handlers.js"; interface Type { devMode: boolean; - toggleDevMode: () => Promise; + devModeToggle: ToggleHandler; } const Context = createContext({ devMode: false, - toggleDevMode: async () => { - return; + devModeToggle: { + button: {}, }, }); @@ -40,28 +41,28 @@ export const DevContextProviderForTesting = ({ value, children, }: { - value: boolean; + value?: boolean; children: any; }): VNode => { return h(Context.Provider, { value: { - devMode: value, - toggleDevMode: async () => { - return; - }, + devMode: !!value, + devModeToggle: { + value, button: {} + } }, children, }); }; export const DevContextProvider = ({ children }: { children: any }): VNode => { - const [value, setter] = useLocalStorage("devMode"); - const devMode = value === "true"; - const toggleDevMode = async (): Promise => - setter((v) => (!v ? "true" : undefined)); + const devModeToggle = useWalletDevMode(); + const value: Type = { devMode: !!devModeToggle.value, devModeToggle } + //support for function as children, useful for getting the value right away children = children.length === 1 && typeof children === "function" - ? children({ devMode }) + ? children(value) : children; - return h(Context.Provider, { value: { devMode, toggleDevMode }, children }); + + return h(Context.Provider, { value, children }); }; diff --git a/packages/taler-wallet-webextension/src/hooks/useWalletDevMode.ts b/packages/taler-wallet-webextension/src/hooks/useWalletDevMode.ts new file mode 100644 index 000000000..8021db686 --- /dev/null +++ b/packages/taler-wallet-webextension/src/hooks/useWalletDevMode.ts @@ -0,0 +1,55 @@ +/* + This file is part of GNU Taler + (C) 2022 Taler Systems S.A. + + GNU 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. + + GNU 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 + GNU Taler; see the file COPYING. If not, see + */ + +import { useState, useEffect } from "preact/hooks"; +import { wxClient } from "../wxApi.js"; +import { ToggleHandler } from "../mui/handlers.js"; +import { TalerError, WalletApiOperation } from "@gnu-taler/taler-wallet-core"; + +export function useWalletDevMode(): ToggleHandler { + const [enabled, setEnabled] = useState(undefined); + const [error, setError] = useState(); + const toggle = async (): Promise => { + return handleOpen(enabled, setEnabled).catch((e) => { + setError(TalerError.fromException(e)); + }); + }; + + useEffect(() => { + async function getValue(): Promise { + const res = await wxClient.call(WalletApiOperation.GetVersion, {}); + setEnabled(res.devMode); + } + getValue(); + }, []); + return { + value: enabled, + button: { + onClick: enabled === undefined ? undefined : toggle, + error, + }, + }; +} + +async function handleOpen( + currentValue: undefined | boolean, + onChange: (value: boolean) => void, +): Promise { + const nextValue = !currentValue + await wxClient.call(WalletApiOperation.SetDevMode, { devModeEnabled: nextValue }); + onChange(nextValue); + return; +} diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx index d0707952f..4082ca29b 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.stories.tsx @@ -37,6 +37,7 @@ const version = { bank: "0:0:0", hash: "d439c3e1bc743f2aa47de4457953dba6ecb0e20f", version: "0.9.0-dev.1", + devMode: false, }, webexVersion: { version: "0.9.0.13", @@ -46,6 +47,7 @@ const version = { export const AllOff = createExample(TestedComponent, { deviceName: "this-is-the-device-name", + devModeToggle: { value: false, button: {} }, autoOpenToggle: { value: false, button: {} }, clipboardToggle: { value: false, button: {} }, setDeviceName: () => Promise.resolve(), @@ -54,6 +56,7 @@ export const AllOff = createExample(TestedComponent, { export const OneChecked = createExample(TestedComponent, { deviceName: "this-is-the-device-name", + devModeToggle: { value: false, button: {} }, autoOpenToggle: { value: false, button: {} }, clipboardToggle: { value: false, button: {} }, setDeviceName: () => Promise.resolve(), @@ -62,6 +65,7 @@ export const OneChecked = createExample(TestedComponent, { export const WithOneExchange = createExample(TestedComponent, { deviceName: "this-is-the-device-name", + devModeToggle: { value: false, button: {} }, autoOpenToggle: { value: false, button: {} }, clipboardToggle: { value: false, button: {} }, setDeviceName: () => Promise.resolve(), @@ -83,6 +87,7 @@ export const WithOneExchange = createExample(TestedComponent, { export const WithExchangeInDifferentState = createExample(TestedComponent, { deviceName: "this-is-the-device-name", + devModeToggle: { value: false, button: {} }, autoOpenToggle: { value: false, button: {} }, clipboardToggle: { value: false, button: {} }, setDeviceName: () => Promise.resolve(), diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx index 2ff9f15f5..8f6807d46 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx @@ -19,6 +19,7 @@ import { ExchangeTosStatus, WalletCoreVersion, } from "@gnu-taler/taler-util"; +import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; import { Fragment, h, VNode } from "preact"; import { Checkbox } from "../components/Checkbox.js"; import { ErrorTalerOperation } from "../components/ErrorTalerOperation.js"; @@ -36,26 +37,26 @@ import { import { useDevContext } from "../context/devContext.js"; import { useTranslationContext } from "../context/translation.js"; import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js"; -import { useBackupDeviceName } from "../hooks/useBackupDeviceName.js"; import { useAutoOpenPermissions } from "../hooks/useAutoOpenPermissions.js"; +import { useBackupDeviceName } from "../hooks/useBackupDeviceName.js"; +import { useClipboardPermissions } from "../hooks/useClipboardPermissions.js"; import { ToggleHandler } from "../mui/handlers.js"; import { Pages } from "../NavigationBar.js"; -import * as wxApi from "../wxApi.js"; import { platform } from "../platform/api.js"; -import { useClipboardPermissions } from "../hooks/useClipboardPermissions.js"; +import { wxClient } from "../wxApi.js"; const GIT_HASH = typeof __GIT_HASH__ !== "undefined" ? __GIT_HASH__ : undefined; export function SettingsPage(): VNode { const autoOpenToggle = useAutoOpenPermissions(); const clipboardToggle = useClipboardPermissions(); - const { devMode, toggleDevMode } = useDevContext(); + const { devModeToggle } = useDevContext(); const { name, update } = useBackupDeviceName(); const webex = platform.getWalletWebExVersion(); const exchangesHook = useAsyncAsHook(async () => { - const list = await wxApi.listExchanges(); - const version = await wxApi.getVersion(); + const list = await wxClient.call(WalletApiOperation.ListExchanges, {}); + const version = await wxClient.call(WalletApiOperation.GetVersion, {}); return { exchanges: list.exchanges, version }; }); const { exchanges, version } = @@ -70,8 +71,7 @@ export function SettingsPage(): VNode { setDeviceName={update} autoOpenToggle={autoOpenToggle} clipboardToggle={clipboardToggle} - developerMode={devMode} - toggleDeveloperMode={toggleDevMode} + devModeToggle={devModeToggle} webexVersion={{ version: webex.version, hash: GIT_HASH, @@ -86,8 +86,7 @@ export interface ViewProps { setDeviceName: (s: string) => Promise; autoOpenToggle: ToggleHandler; clipboardToggle: ToggleHandler; - developerMode: boolean; - toggleDeveloperMode: () => Promise; + devModeToggle: ToggleHandler; knownExchanges: Array; coreVersion: WalletCoreVersion | undefined; webexVersion: { @@ -100,10 +99,9 @@ export function SettingsView({ knownExchanges, autoOpenToggle, clipboardToggle, - developerMode, + devModeToggle, coreVersion, webexVersion, - toggleDeveloperMode, }: ViewProps): VNode { const { i18n, lang, supportedLang, changeLanguage } = useTranslationContext(); @@ -248,8 +246,8 @@ export function SettingsView({ More options and information useful for debugging } - enabled={developerMode} - onToggle={toggleDeveloperMode} + enabled={devModeToggle.value!} + onToggle={devModeToggle.button.onClick!} /> diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts index 6f930b788..7528457c3 100644 --- a/packages/taler-wallet-webextension/src/wxBackend.ts +++ b/packages/taler-wallet-webextension/src/wxBackend.ts @@ -151,6 +151,7 @@ async function dispatch( r = wrapResponse({ newValue: res }); break; } + //FIXME: implement type checked api like WalletCoreApi case "toggleHeaderListener": { const newVal = req.payload.value; logger.trace("new extended permissions value", newVal);