diff options
author | Sebastian <sebasjm@gmail.com> | 2024-03-01 09:35:03 -0300 |
---|---|---|
committer | Sebastian <sebasjm@gmail.com> | 2024-03-01 09:35:03 -0300 |
commit | d09c50bdb1f5eadc7aa64f38aedd07eb5beea039 (patch) | |
tree | e121971f6f4621d8e37d4c66684e4674235240cd | |
parent | c83d9465eb8ea775a5dafa11d4a27396e532211d (diff) |
move the wallet listener to background
4 files changed, 88 insertions, 53 deletions
diff --git a/packages/taler-wallet-webextension/src/components/WalletActivity.tsx b/packages/taler-wallet-webextension/src/components/WalletActivity.tsx index 4a3aaf79f..a370e859d 100644 --- a/packages/taler-wallet-webextension/src/components/WalletActivity.tsx +++ b/packages/taler-wallet-webextension/src/components/WalletActivity.tsx @@ -35,6 +35,7 @@ import { useSettings } from "../hooks/useSettings.js"; import { Button } from "../mui/Button.js"; import { Modal } from "./Modal.js"; import { Time } from "./Time.js"; +import { WalletEvent } from "../wxApi.js"; interface Props extends JSX.HTMLAttributes { } @@ -613,63 +614,67 @@ function getNotificationFor(id: string, event: WalletNotification, start: Absolu } } +let lastTimeout: ReturnType<typeof setTimeout>; export function ObservavilityEventsTable({ }: {}): VNode { const { i18n } = useTranslationContext() - const listenAllEvents = Array.from<NotificationType>({ length: 1 }); - listenAllEvents.includes = () => true const api = useBackendContext(); - const [lastEvent, setLastEvent] = useState<Date>(new Date()) - const [lastShow, setLastShow] = useState<Date>(new Date()) - const [notifications, setNotifications] = useState<{ notif: WalletNotification, when: AbsoluteTime }[]>([]) + const [notifications, setNotifications] = useState<Notif[]>([]) + useEffect(() => { - return api.listener.onUpdateNotification(listenAllEvents, (not) => { - console.log(not) - const time = new Date(); - setLastEvent(time) - notifications.unshift({ - notif: not, - when: AbsoluteTime.now() - }) - setNotifications(Array.from(notifications)) - }); + //initial call + api.background.call("getNotifications", undefined).then(notif => { + const list: Notif[] = [] + for (const pepe of notif) { + const event = getNotificationFor(String(list.length), pepe.notification, pepe.when, list) + // pepe. + if (event) { + list.push(event) + } + } + setNotifications(list); + }) + + function periodicRefresh() { + lastTimeout = setTimeout(async () => { + + const notif = await api.background.call("getNotifications", undefined); + + const list: Notif[] = [] + for (const pepe of notif) { + const event = getNotificationFor(String(list.length), pepe.notification, pepe.when, list) + // pepe. + if (event) { + list.push(event) + } + } + + setNotifications(list); + periodicRefresh(); + }, 1000) + + //clear on unload + return () => { clearTimeout(lastTimeout) } + } + return periodicRefresh() }); const [showDetails, setShowDetails] = useState<VNode>() - const [notif, setnotif] = useState<Notif[]>([]) return <div> <div style={{ display: "flex", justifyContent: "space-between" }}> - {lastShow === lastEvent ? - <div>last event {lastEvent.toString()}</div> - : <div>there are more events, update to see them</div>} - <div> - {lastShow !== lastEvent ? - <div style={{ padding: 4, margin: 2, border: "solid 1px black" }} onClick={() => { - const list = [...notif] - for (const pepe of notifications) { - const event = getNotificationFor(String(list.length), pepe.notif, pepe.when, list) - if (event) { - list.push(event) - } - } - setnotif(list) - setLastShow(lastEvent) - }}> - update - </div> - : <div />} - <div style={{ padding: 4, margin: 2, border: "solid 1px black" }} onClick={() => { - setNotifications([]) - }}> - clear - </div> + <div style={{ padding: 4, margin: 2, border: "solid 1px black" }} onClick={() => { + setNotifications([]) + }}> + clear </div> + + </div> {showDetails && <Modal title="event details" onClose={{ onClick: (async () => { setShowDetails(undefined) }) as any }} > {showDetails} </Modal>} - {notif.map((not) => { + {notifications.map((not) => { return ( <details key={not.id}> <summary> @@ -721,14 +726,15 @@ function ErroDetailModal({ error, onClose }: { error: TalerErrorDetail, onClose: export function ActiveTasksTable({ }: {}): VNode { const { i18n } = useTranslationContext() - const listenAllEvents = Array.from<NotificationType>({ length: 1 }); - listenAllEvents.includes = () => true const api = useBackendContext(); const state = useAsyncAsHook(() => api.wallet.call(WalletApiOperation.GetActiveTasks, {}), ); const [showError, setShowError] = useState<TalerErrorDetail>() const tasks = state && !state.hasError ? state.response.tasks : []; + + // const listenAllEvents = Array.from<NotificationType>({ length: 1 }); + // listenAllEvents.includes = () => true // useEffect(() => { // return api.listener.onUpdateNotification(listenAllEvents, (notif) => { // state?.retry() diff --git a/packages/taler-wallet-webextension/src/wallet/Settings.tsx b/packages/taler-wallet-webextension/src/wallet/Settings.tsx index 64a96d643..b704b585e 100644 --- a/packages/taler-wallet-webextension/src/wallet/Settings.tsx +++ b/packages/taler-wallet-webextension/src/wallet/Settings.tsx @@ -25,7 +25,7 @@ import { WalletCoreVersion, } from "@gnu-taler/taler-util"; import { WalletApiOperation } from "@gnu-taler/taler-wallet-core"; -import { useTranslationContext } from "@gnu-taler/web-util/browser"; +import { useApiContext, useTranslationContext } from "@gnu-taler/web-util/browser"; import { Fragment, VNode, h } from "preact"; import { Pages } from "../NavigationBar.js"; import { Checkbox } from "../components/Checkbox.js"; @@ -231,6 +231,7 @@ type Options = { }; function AdvanceSettings(): VNode { const [settings, updateSettings] = useSettings(); + const api = useBackendContext(); const { i18n } = useTranslationContext(); const o: Options = { backup: { @@ -287,6 +288,7 @@ function AdvanceSettings(): VNode { enabled={settings[settingsName]} onToggle={async () => { updateSettings(settingsName, !settings[settingsName]); + await api.background.call("reinitWallet", undefined); }} /> ); diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts index a1c09ef8d..c53b15ef0 100644 --- a/packages/taler-wallet-webextension/src/wxApi.ts +++ b/packages/taler-wallet-webextension/src/wxApi.ts @@ -70,6 +70,14 @@ export interface BackgroundOperations { request: void; response: void; }; + reinitWallet: { + request: void; + response: void; + }; + getNotifications: { + request: void; + response: WalletEvent[]; + }; setLoggingLevel: { request: { tag?: string; @@ -79,6 +87,8 @@ export interface BackgroundOperations { }; } +export type WalletEvent = { notification: WalletNotification, when: AbsoluteTime } + export interface BackgroundApiClient { call<Op extends keyof BackgroundOperations>( operation: Op, @@ -182,7 +192,6 @@ function onUpdateNotification( const onNewMessage = (message: MessageFromBackend): void => { const shouldNotify = message.type === "wallet" && messageTypes.includes(message.notification.type); if (shouldNotify) { - message.notification doCallback(message.notification); } }; diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts index 0801d2ab0..2f48a6611 100644 --- a/packages/taler-wallet-webextension/src/wxBackend.ts +++ b/packages/taler-wallet-webextension/src/wxBackend.ts @@ -24,6 +24,7 @@ * Imports. */ import { + AbsoluteTime, LogLevel, Logger, OpenedPromise, @@ -33,7 +34,7 @@ import { makeErrorDetail, openPromise, setGlobalLogLevelFromString, - setLogLevelFromString, + setLogLevelFromString } from "@gnu-taler/taler-util"; import { HttpRequestLibrary } from "@gnu-taler/taler-util/http"; import { @@ -53,7 +54,7 @@ import { import { MessageFromFrontend, MessageResponse } from "./platform/api.js"; import { platform } from "./platform/background.js"; import { ExtensionOperations } from "./taler-wallet-interaction-loader.js"; -import { BackgroundOperations } from "./wxApi.js"; +import { BackgroundOperations, WalletEvent } from "./wxApi.js"; /** * Currently active wallet instance. Might be unloaded and @@ -91,6 +92,12 @@ async function resetDb(): Promise<void> { await reinitWallet(); } +//FIXME: maybe circular buffer +const notifications: WalletEvent[] = [] +async function getNotifications(): Promise<WalletEvent[]> { + return notifications +} + async function runGarbageCollector(): Promise<void> { const dbBeforeGc = currentDatabase; if (!dbBeforeGc) { @@ -129,6 +136,8 @@ async function isDomainTrusted(): Promise<boolean> { const backendHandlers: BackendHandlerType = { resetDb, runGarbageCollector, + getNotifications, + reinitWallet, setLoggingLevel, }; @@ -284,12 +293,14 @@ async function reinitWallet(): Promise<void> { ); try { await wallet.handleCoreApiRequest("initWallet", "native-init", { - testing: { - emitObservabilityEvents: true, - }, - features: { - allowHttp: settings.walletAllowHttp, - }, + config: { + testing: { + emitObservabilityEvents: settings.showWalletActivity, + }, + features: { + allowHttp: settings.walletAllowHttp, + }, + } }); } catch (e) { logger.error("could not initialize wallet", e); @@ -297,6 +308,13 @@ async function reinitWallet(): Promise<void> { return; } wallet.addNotificationListener((message) => { + if (settings.showWalletActivity) { + notifications.push({ + notification: message, + when: AbsoluteTime.now() + }) + } + platform.sendMessageToAllChannels({ type: "wallet", notification: message, |