aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSebastian <sebasjm@gmail.com>2024-05-07 15:36:57 -0300
committerSebastian <sebasjm@gmail.com>2024-05-07 15:36:57 -0300
commit3e471d5f1c0ae5a647859d22d40ef162d841f70e (patch)
tree40966027c31c412eda052953a58ef487fb907754
parentaaf4ffc9411d394897c72f39c132ee24cee28013 (diff)
downloadwallet-core-3e471d5f1c0ae5a647859d22d40ef162d841f70e.tar.xz
filter obs event
-rw-r--r--packages/taler-wallet-webextension/src/components/WalletActivity.tsx505
-rw-r--r--packages/taler-wallet-webextension/src/mui/Button.tsx6
-rw-r--r--packages/taler-wallet-webextension/src/wxApi.ts7
-rw-r--r--packages/taler-wallet-webextension/src/wxBackend.ts171
4 files changed, 395 insertions, 294 deletions
diff --git a/packages/taler-wallet-webextension/src/components/WalletActivity.tsx b/packages/taler-wallet-webextension/src/components/WalletActivity.tsx
index 69a2c0675..41b0c5c76 100644
--- a/packages/taler-wallet-webextension/src/components/WalletActivity.tsx
+++ b/packages/taler-wallet-webextension/src/components/WalletActivity.tsx
@@ -15,6 +15,7 @@
*/
import {
AbsoluteTime,
+ ExchangeStateTransitionNotification,
NotificationType,
ObservabilityEventType,
RequestProgressNotification,
@@ -26,38 +27,76 @@ import {
} from "@gnu-taler/taler-util";
import { WalletApiOperation } from "@gnu-taler/taler-wallet-core";
import { useTranslationContext } from "@gnu-taler/web-util/browser";
-import { Fragment, JSX, VNode, h } from "preact";
+import { Fragment, VNode, h } from "preact";
import { useEffect, useState } from "preact/hooks";
import { Pages } from "../NavigationBar.js";
import { useBackendContext } from "../context/backend.js";
import { useAsyncAsHook } from "../hooks/useAsyncAsHook.js";
import { useSettings } from "../hooks/useSettings.js";
import { Button } from "../mui/Button.js";
+import { SafeHandler } from "../mui/handlers.js";
import { WxApiType } from "../wxApi.js";
import { Modal } from "./Modal.js";
import { Time } from "./Time.js";
+import { TextField } from "../mui/TextField.js";
+import { WalletActivityTrack } from "../wxBackend.js";
-interface Props extends JSX.HTMLAttributes {}
+const OPEN_ACTIVITY_HEIGHT_PX = 250;
+const CLOSE_ACTIVITY_HEIGHT_PX = 40;
-export function WalletActivity({}: Props): VNode {
+export function WalletActivity(): VNode {
const { i18n } = useTranslationContext();
- const [settings, updateSettings] = useSettings();
- const api = useBackendContext();
+ const [, updateSettings] = useSettings();
+
+ const [collapsed, setCollcapsed] = useState(true);
+
useEffect(() => {
- document.body.style.marginBottom = "250px";
+ document.body.style.marginBottom = `${
+ collapsed ? CLOSE_ACTIVITY_HEIGHT_PX : OPEN_ACTIVITY_HEIGHT_PX
+ }px`;
return () => {
document.body.style.marginBottom = "0px";
};
- });
- const [table, setTable] = useState<"tasks" | "events">("tasks");
+ }, [collapsed]);
+
+ const [table, setTable] = useState<"tasks" | "events">("events");
+ if (collapsed) {
+ return (
+ <div
+ style={{
+ position: "fixed",
+ bottom: 0,
+ background: "lightgrey",
+ zIndex: 1,
+ height: CLOSE_ACTIVITY_HEIGHT_PX,
+ overflowY: "scroll",
+ width: "100%",
+ }}
+ onClick={() => {
+ setCollcapsed(!collapsed);
+ }}
+ >
+ <div
+ style={{
+ display: "flex",
+ justifyContent: "space-around",
+ marginTop: 10,
+ cursor: "pointer",
+ }}
+ >
+ click here to open
+ </div>
+ </div>
+ );
+ }
return (
<div
style={{
position: "fixed",
bottom: 0,
- background: "white",
+ background: "lightgrey",
zIndex: 1,
- height: 250,
+ height: OPEN_ACTIVITY_HEIGHT_PX,
overflowY: "scroll",
width: "100%",
}}
@@ -65,23 +104,22 @@ export function WalletActivity({}: Props): VNode {
<div
style={{
display: "flex",
- justifyContent: "space-between",
- float: "right",
+ justifyContent: "space-around",
+ cursor: "pointer",
+ }}
+ onClick={() => {
+ setCollcapsed(!collapsed);
}}
>
- <div />
- <div>
- <div
- style={{ padding: 4, margin: 2, border: "solid 1px black" }}
- onClick={() => {
- updateSettings("showWalletActivity", false);
- }}
- >
- close
- </div>
- </div>
- </div>
- <div style={{ display: "flex", justifyContent: "space-around" }}>
+ <Button
+ variant={table === "events" ? "contained" : "outlined"}
+ style={{ margin: 4 }}
+ onClick={async () => {
+ setTable("events");
+ }}
+ >
+ <i18n.Translate>Events</i18n.Translate>
+ </Button>
<Button
variant={table === "tasks" ? "contained" : "outlined"}
style={{ margin: 4 }}
@@ -89,31 +127,38 @@ export function WalletActivity({}: Props): VNode {
setTable("tasks");
}}
>
- <i18n.Translate>Tasks</i18n.Translate>
+ <i18n.Translate>Active tasks</i18n.Translate>
</Button>
+
<Button
- variant={table === "events" ? "contained" : "outlined"}
+ variant="outlined"
style={{ margin: 4 }}
onClick={async () => {
- setTable("events");
+ updateSettings("showWalletActivity", false);
}}
>
- <i18n.Translate>Events</i18n.Translate>
+ <i18n.Translate>Close</i18n.Translate>
</Button>
</div>
- {(function (): VNode {
- switch (table) {
- case "events": {
- return <ObservabilityEventsTable />;
- }
- case "tasks": {
- return <ActiveTasksTable />;
- }
- default: {
- assertUnreachable(table);
+ <div
+ style={{
+ backgroundColor: "white",
+ }}
+ >
+ {(function (): VNode {
+ switch (table) {
+ case "events": {
+ return <ObservabilityEventsTable />;
+ }
+ case "tasks": {
+ return <ActiveTasksTable />;
+ }
+ default: {
+ assertUnreachable(table);
+ }
}
- }
- })()}
+ })()}
+ </div>
</div>
);
}
@@ -122,21 +167,6 @@ interface MoreInfoPRops {
events: (WalletNotification & { when: AbsoluteTime })[];
onClick: (content: VNode) => void;
}
-type Notif = {
- id: string;
- events: (WalletNotification & { when: AbsoluteTime })[];
- description: string;
- start: AbsoluteTime;
- end: AbsoluteTime;
- reference:
- | {
- eventType: NotificationType;
- referenceType: "task" | "transaction" | "operation" | "exchange";
- id: string;
- }
- | undefined;
- MoreInfo: (p: MoreInfoPRops) => VNode;
-};
function ShowBalanceChange({ events }: MoreInfoPRops): VNode {
if (!events.length) return <Fragment />;
@@ -267,10 +297,7 @@ function ShowTransactionStateTransition({
</Fragment>
);
}
-function ShowExchangeStateTransition({
- events,
- onClick,
-}: MoreInfoPRops): VNode {
+function ShowExchangeStateTransition({ events }: MoreInfoPRops): VNode {
if (!events.length) return <Fragment />;
const not = events[0];
if (not.type !== NotificationType.ExchangeStateTransition)
@@ -323,7 +350,7 @@ type ObservaNotifWithTime = (
};
function ShowObservabilityEvent({ events, onClick }: MoreInfoPRops): VNode {
// let prev: ObservaNotifWithTime;
- const asd = events.map((not) => {
+ const asd = events.map((not, idx) => {
if (
not.type !== NotificationType.RequestObservabilityEvent &&
not.type !== NotificationType.TaskObservabilityEvent
@@ -364,7 +391,12 @@ function ShowObservabilityEvent({ events, onClick }: MoreInfoPRops): VNode {
})();
return (
- <ShowObervavilityDetails title={title} notif={not} onClick={onClick} />
+ <ShowObervavilityDetails
+ key={idx}
+ title={title}
+ notif={not}
+ onClick={onClick}
+ />
);
});
return (
@@ -673,235 +705,64 @@ function ShowObervavilityDetails({
}
}
-function getNotificationFor(
- id: string,
- event: WalletNotification,
- start: AbsoluteTime,
- list: Notif[],
-): Notif | undefined {
- const eventWithTime = { ...event, when: start };
- switch (event.type) {
- case NotificationType.BalanceChange: {
- return {
- id,
- events: [eventWithTime],
- reference: {
- eventType: event.type,
- referenceType: "transaction",
- id: event.hintTransactionId,
- },
- description: "Balance change",
- start,
- end: AbsoluteTime.never(),
- MoreInfo: ShowBalanceChange,
- };
- }
- case NotificationType.BackupOperationError: {
- return {
- id,
- events: [eventWithTime],
- reference: undefined,
- description: "Backup error",
- start,
- end: AbsoluteTime.never(),
- MoreInfo: ShowBackupOperationError,
- };
- }
- case NotificationType.TransactionStateTransition: {
- const found = list.find(
- (a) =>
- a.reference?.eventType === event.type &&
- a.reference.id === event.transactionId,
- );
- if (found) {
- found.end = start;
- found.events.unshift(eventWithTime);
- return undefined;
- }
- return {
- id,
- events: [eventWithTime],
- reference: {
- eventType: event.type,
- referenceType: "transaction",
- id: event.transactionId,
- },
- description: event.type,
- start,
- end: AbsoluteTime.never(),
- MoreInfo: ShowTransactionStateTransition,
- };
- }
- case NotificationType.ExchangeStateTransition: {
- const found = list.find(
- (a) =>
- a.reference?.eventType === event.type &&
- a.reference.id === event.exchangeBaseUrl,
- );
- if (found) {
- found.end = start;
- found.events.unshift(eventWithTime);
- return undefined;
- }
- return {
- id,
- events: [eventWithTime],
- description: "Exchange update",
- reference: {
- eventType: event.type,
- referenceType: "exchange",
- id: event.exchangeBaseUrl,
- },
- start,
- end: AbsoluteTime.never(),
- MoreInfo: ShowExchangeStateTransition,
- };
- }
- case NotificationType.TaskObservabilityEvent: {
- const found = list.find(
- (a) =>
- a.reference?.eventType === event.type &&
- a.reference.id === event.taskId,
- );
- if (found) {
- found.end = start;
- found.events.unshift(eventWithTime);
- return undefined;
- }
- return {
- id,
- events: [eventWithTime],
- reference: {
- eventType: event.type,
- referenceType: "task",
- id: event.taskId,
- },
- description: `Task update ${event.taskId}`,
- start,
- end: AbsoluteTime.never(),
- MoreInfo: ShowObservabilityEvent,
- };
- }
- case NotificationType.WithdrawalOperationTransition: {
- const found = list.find(
- (a) =>
- a.reference?.eventType === event.type && a.reference.id === event.uri,
- );
- if (found) {
- found.end = start;
- found.events.unshift(eventWithTime);
- return undefined;
- }
- return {
- id,
- events: [eventWithTime],
- reference: {
- eventType: event.type,
- referenceType: "task",
- id: event.uri,
- },
- description: `Withdrawal operation updated`,
- start,
- end: AbsoluteTime.never(),
- MoreInfo: ShowObservabilityEvent,
- };
- }
- case NotificationType.RequestObservabilityEvent: {
- const found = list.find(
- (a) =>
- a.reference?.eventType === event.type &&
- a.reference.id === event.requestId,
- );
- if (found) {
- found.end = start;
- found.events.unshift(eventWithTime);
- return undefined;
- }
- return {
- id,
- events: [eventWithTime],
- reference: {
- eventType: event.type,
- referenceType: "operation",
- id: event.requestId,
- },
- description: `wallet.${event.operation}(${event.requestId})`,
- start,
- end: AbsoluteTime.never(),
- MoreInfo: ShowObservabilityEvent,
- };
- }
- case NotificationType.Idle:
- return undefined;
- default: {
- assertUnreachable(event);
- }
- }
-}
-
-function refresh(api: WxApiType, onUpdate: (list: Notif[]) => void) {
+function refresh(
+ api: WxApiType,
+ onUpdate: (list: WalletActivityTrack[]) => void,
+ filter: string,
+) {
api.background
- .call("getNotifications", undefined)
+ .call("getNotifications", { filter })
.then((notif) => {
- const list: Notif[] = [];
- for (const n of notif) {
- if (
- n.notification.type === NotificationType.RequestObservabilityEvent &&
- n.notification.operation === "getActiveTasks"
- ) {
- //ignore monitor request
- continue;
- }
- const event = getNotificationFor(
- String(list.length),
- n.notification,
- n.when,
- list,
- );
- // pepe.
- if (event) {
- list.unshift(event);
- }
- }
- onUpdate(list);
+ onUpdate(notif);
})
.catch((error) => {
console.log(error);
});
}
-export function ObservabilityEventsTable({}: {}): VNode {
+export function ObservabilityEventsTable(): VNode {
const { i18n } = useTranslationContext();
const api = useBackendContext();
- const [notifications, setNotifications] = useState<Notif[]>([]);
+ const [notifications, setNotifications] = useState<WalletActivityTrack[]>([]);
const [showDetails, setShowDetails] = useState<VNode>();
+ const [filter, onChangeFilter] = useState("");
useEffect(() => {
let lastTimeout: ReturnType<typeof setTimeout>;
function periodicRefresh() {
- refresh(api, setNotifications);
+ refresh(api, setNotifications, filter);
lastTimeout = setTimeout(() => {
periodicRefresh();
}, 1000);
- //clear on unload
return () => {
clearTimeout(lastTimeout);
};
}
return periodicRefresh();
- }, [1]);
+ }, [filter]);
return (
<div>
<div style={{ display: "flex", justifyContent: "space-between" }}>
+ <TextField
+ label="Filter"
+ variant="outlined"
+ value={filter}
+ onChange={onChangeFilter}
+ />
<div
- style={{ padding: 4, margin: 2, border: "solid 1px black" }}
+ style={{
+ padding: 4,
+ margin: 2,
+ border: "solid 1px black",
+ alignSelf: "center",
+ }}
onClick={() => {
- api.background.call("clearNotifications", undefined).then((d) => {
- refresh(api, setNotifications);
+ api.background.call("clearNotifications", undefined).then(() => {
+ refresh(api, setNotifications, filter);
});
}}
>
@@ -914,7 +775,7 @@ export function ObservabilityEventsTable({}: {}): VNode {
onClose={{
onClick: (async () => {
setShowDetails(undefined);
- }) as any,
+ }) as SafeHandler<void>,
}}
>
{showDetails}
@@ -932,7 +793,40 @@ export function ObservabilityEventsTable({}: {}): VNode {
padding: 4,
}}
>
- <div style={{ padding: 4 }}>{not.description}</div>
+ <div style={{ padding: 4 }}>
+ {(() => {
+ switch (not.type) {
+ case NotificationType.BalanceChange:
+ return i18n.str`Balance change`;
+ case NotificationType.BackupOperationError:
+ return i18n.str`Backup failed`;
+ case NotificationType.TransactionStateTransition:
+ return i18n.str`Transaction updated`;
+ case NotificationType.ExchangeStateTransition:
+ return i18n.str`Exchange updated`;
+ case NotificationType.Idle:
+ return i18n.str`Idle`;
+ case NotificationType.TaskObservabilityEvent:
+ return i18n.str`task.${
+ (not.events[0] as TaskProgressNotification).taskId
+ }`;
+ case NotificationType.RequestObservabilityEvent:
+ return i18n.str`wallet.${
+ (not.events[0] as RequestProgressNotification)
+ .operation
+ }(${
+ (not.events[0] as RequestProgressNotification)
+ .requestId
+ })`;
+ case NotificationType.WithdrawalOperationTransition: {
+ return `---`;
+ }
+ default: {
+ assertUnreachable(not.type);
+ }
+ }
+ })()}
+ </div>
<div style={{ padding: 4 }}>
<Time timestamp={not.start} format="yyyy/MM/dd HH:mm:ss" />
</div>
@@ -941,12 +835,76 @@ export function ObservabilityEventsTable({}: {}): VNode {
</div>
</div>
</summary>
- <not.MoreInfo
- events={not.events}
- onClick={(details) => {
- setShowDetails(details);
- }}
- />
+ {(() => {
+ switch (not.type) {
+ case NotificationType.BalanceChange: {
+ return (
+ <ShowBalanceChange
+ events={not.events}
+ onClick={(details) => {
+ setShowDetails(details);
+ }}
+ />
+ );
+ }
+ case NotificationType.BackupOperationError: {
+ return (
+ <ShowBackupOperationError
+ events={not.events}
+ onClick={(details) => {
+ setShowDetails(details);
+ }}
+ />
+ );
+ }
+ case NotificationType.TransactionStateTransition: {
+ return (
+ <ShowTransactionStateTransition
+ events={not.events}
+ onClick={(details) => {
+ setShowDetails(details);
+ }}
+ />
+ );
+ }
+ case NotificationType.ExchangeStateTransition: {
+ return (
+ <ShowExchangeStateTransition
+ events={not.events}
+ onClick={(details) => {
+ setShowDetails(details);
+ }}
+ />
+ );
+ }
+ case NotificationType.Idle: {
+ return <div>not implemented</div>;
+ }
+ case NotificationType.TaskObservabilityEvent: {
+ return (
+ <ShowObservabilityEvent
+ events={not.events}
+ onClick={(details) => {
+ setShowDetails(details);
+ }}
+ />
+ );
+ }
+ case NotificationType.RequestObservabilityEvent: {
+ return (
+ <ShowObservabilityEvent
+ events={not.events}
+ onClick={(details) => {
+ setShowDetails(details);
+ }}
+ />
+ );
+ }
+ case NotificationType.WithdrawalOperationTransition: {
+ return <div>not implemented</div>;
+ }
+ }
+ })()}
</details>
);
})}
@@ -965,7 +923,7 @@ function ErroDetailModal({
<Modal
title="Full detail"
onClose={{
- onClick: onClose as any,
+ onClick: onClose as SafeHandler<void>,
}}
>
<dl>
@@ -987,7 +945,7 @@ function ErroDetailModal({
);
}
-export function ActiveTasksTable({}: {}): VNode {
+export function ActiveTasksTable(): VNode {
const { i18n } = useTranslationContext();
const api = useBackendContext();
const state = useAsyncAsHook(() => {
@@ -1006,13 +964,6 @@ export function ActiveTasksTable({}: {}): VNode {
};
}, [tasks]);
- // const listenAllEvents = Array.from<NotificationType>({ length: 1 });
- // listenAllEvents.includes = () => true
- // useEffect(() => {
- // return api.listener.onUpdateNotification(listenAllEvents, (notif) => {
- // state?.retry()
- // });
- // });
return (
<Fragment>
{showError && (
@@ -1051,7 +1002,7 @@ export function ActiveTasksTable({}: {}): VNode {
{tasks.map((task) => {
const [type, id] = task.taskId.split(":");
return (
- <tr>
+ <tr key={id}>
<td>{type}</td>
<td title={id}>{id.substring(0, 10)}</td>
<td>
diff --git a/packages/taler-wallet-webextension/src/mui/Button.tsx b/packages/taler-wallet-webextension/src/mui/Button.tsx
index 1af281d42..12a4d91ea 100644
--- a/packages/taler-wallet-webextension/src/mui/Button.tsx
+++ b/packages/taler-wallet-webextension/src/mui/Button.tsx
@@ -371,7 +371,11 @@ function ButtonBase({
);
}
return (
- <button onClick={doClick} class={classNames} {...rest}>
+ <button onClick={(e) => {
+ e.preventDefault();
+ e.stopPropagation();
+ doClick();
+ }} class={classNames} {...rest}>
{children}
</button>
);
diff --git a/packages/taler-wallet-webextension/src/wxApi.ts b/packages/taler-wallet-webextension/src/wxApi.ts
index 195efecd4..4394a982f 100644
--- a/packages/taler-wallet-webextension/src/wxApi.ts
+++ b/packages/taler-wallet-webextension/src/wxApi.ts
@@ -46,6 +46,7 @@ import {
MessageFromFrontendWallet,
} from "./platform/api.js";
import { platform } from "./platform/foreground.js";
+import { WalletActivityTrack } from "./wxBackend.js";
/**
*
@@ -74,8 +75,10 @@ export interface BackgroundOperations {
response: void;
};
getNotifications: {
- request: void;
- response: WalletEvent[];
+ request: {
+ filter: string;
+ };
+ response: WalletActivityTrack[];
};
clearNotifications: {
request: void;
diff --git a/packages/taler-wallet-webextension/src/wxBackend.ts b/packages/taler-wallet-webextension/src/wxBackend.ts
index 008f80c57..5fa255f5d 100644
--- a/packages/taler-wallet-webextension/src/wxBackend.ts
+++ b/packages/taler-wallet-webextension/src/wxBackend.ts
@@ -25,7 +25,6 @@
*/
import {
AbsoluteTime,
- BalanceFlag,
LogLevel,
Logger,
NotificationType,
@@ -34,14 +33,13 @@ import {
TalerError,
TalerErrorCode,
TalerErrorDetail,
- TransactionMajorState,
TransactionMinorState,
WalletNotification,
getErrorDetailFromException,
makeErrorDetail,
openPromise,
setGlobalLogLevelFromString,
- setLogLevelFromString,
+ setLogLevelFromString
} from "@gnu-taler/taler-util";
import { HttpRequestLibrary } from "@gnu-taler/taler-util/http";
import {
@@ -55,11 +53,11 @@ import {
exportDb,
importDb,
} from "@gnu-taler/taler-wallet-core";
+import { BrowserFetchHttpLib } from "@gnu-taler/web-util/browser";
import { MessageFromFrontend, MessageResponse } from "./platform/api.js";
import { platform } from "./platform/background.js";
import { ExtensionOperations } from "./taler-wallet-interaction-loader.js";
-import { BackgroundOperations, WalletEvent } from "./wxApi.js";
-import { BrowserFetchHttpLib } from "@gnu-taler/web-util/browser";
+import { BackgroundOperations } from "./wxApi.js";
/**
* Currently active wallet instance. Might be unloaded and
@@ -92,14 +90,162 @@ async function resetDb(): Promise<void> {
await reinitWallet();
}
+export type WalletActivityTrack = {
+ id: number;
+ events: (WalletNotification & {when: AbsoluteTime})[];
+ start: AbsoluteTime;
+ type: NotificationType;
+ end: AbsoluteTime;
+ groupId: string;
+};
+
+let counter = 0;
+function getUniqueId(): number {
+ return counter++;
+}
+
//FIXME: maybe circular buffer
-const notifications: WalletEvent[] = [];
-async function getNotifications(): Promise<WalletEvent[]> {
- return notifications;
+const activity: WalletActivityTrack[] = [];
+
+function addNewWalletActivityNotification(list: WalletActivityTrack[], n: WalletNotification) {
+ const start = AbsoluteTime.now();
+ const ev = {...n, when:start};
+ switch (n.type) {
+ case NotificationType.BalanceChange: {
+ const groupId = `${n.type}:${n.hintTransactionId}`;
+ const found = list.find((a)=>a.groupId === groupId)
+ if (found) {
+ found.end = start;
+ found.events.unshift(ev)
+ return;
+ }
+ list.push({
+ id: getUniqueId(),
+ type: n.type,
+ start,
+ end: AbsoluteTime.never(),
+ events: [ev],
+ groupId,
+ });
+ return;
+ }
+ case NotificationType.BackupOperationError: {
+ const groupId = "";
+ list.push({
+ id: getUniqueId(),
+ type: n.type,
+ start,
+ end: AbsoluteTime.never(),
+ events: [ev],
+ groupId,
+ });
+ return;
+ }
+ case NotificationType.TransactionStateTransition: {
+ const groupId = `${n.type}:${n.transactionId}`;
+ const found = list.find((a)=>a.groupId === groupId)
+ if (found) {
+ found.end = start;
+ found.events.unshift(ev)
+ return;
+ }
+ list.push({
+ id: getUniqueId(),
+ type: n.type,
+ start,
+ end: AbsoluteTime.never(),
+ events: [ev],
+ groupId,
+ });
+ return;
+ }
+ case NotificationType.WithdrawalOperationTransition: {
+ return;
+ }
+ case NotificationType.ExchangeStateTransition: {
+ const groupId = `${n.type}:${n.exchangeBaseUrl}`;
+ const found = list.find((a)=>a.groupId === groupId)
+ if (found) {
+ found.end = start;
+ found.events.unshift(ev)
+ return;
+ }
+ list.push({
+ id: getUniqueId(),
+ type: n.type,
+ start,
+ end: AbsoluteTime.never(),
+ events: [ev],
+ groupId,
+ });
+ return;
+ }
+ case NotificationType.Idle: {
+ const groupId = "";
+ list.push({
+ id: getUniqueId(),
+ type: n.type,
+ start,
+ end: AbsoluteTime.never(),
+ events: [ev],
+ groupId,
+ });
+ return;
+ }
+ case NotificationType.TaskObservabilityEvent: {
+ const groupId = `${n.type}:${n.taskId}`;
+ const found = list.find((a)=>a.groupId === groupId)
+ if (found) {
+ found.end = start;
+ found.events.unshift(ev)
+ return;
+ }
+ list.push({
+ id: getUniqueId(),
+ type: n.type,
+ start,
+ end: AbsoluteTime.never(),
+ events: [ev],
+ groupId,
+ });
+ return;
+ }
+ case NotificationType.RequestObservabilityEvent: {
+ const groupId = `${n.type}:${n.operation}:${n.requestId}`;
+ const found = list.find((a)=>a.groupId === groupId)
+ if (found) {
+ found.end = start;
+ found.events.unshift(ev)
+ return;
+ }
+ list.push({
+ id: getUniqueId(),
+ type: n.type,
+ start,
+ end: AbsoluteTime.never(),
+ events: [ev],
+ groupId,
+ });
+ return;
+ }
+ }
+}
+
+async function getNotifications({
+ filter,
+}: {
+ filter: string;
+}): Promise<WalletActivityTrack[]> {
+ if (!filter) return activity;
+
+ const rg = new RegExp(`.*${filter}.*`);
+ return activity.filter((event) => {
+ return rg.test(event.groupId.toLowerCase());
+ });
}
async function clearNotifications(): Promise<void> {
- notifications.splice(0, notifications.length);
+ activity.splice(0, activity.length);
}
async function runGarbageCollector(): Promise<void> {
@@ -327,10 +473,7 @@ async function reinitWallet(): Promise<void> {
}
wallet.addNotificationListener((message) => {
if (settings.showWalletActivity) {
- notifications.push({
- notification: message,
- when: AbsoluteTime.now(),
- });
+ addNewWalletActivityNotification(activity, message);
}
processWalletNotification(message);
@@ -394,7 +537,7 @@ async function updateIconBasedOnBalance() {
let showAlert = false;
for (const b of balance.balances) {
if (b.flags.length > 0) {
- console.log("b.flags", JSON.stringify(b.flags))
+ console.log("b.flags", JSON.stringify(b.flags));
showAlert = true;
break;
}