gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-core] branch master updated: filter obs event


From: gnunet
Subject: [taler-wallet-core] branch master updated: filter obs event
Date: Tue, 07 May 2024 20:37:03 +0200

This is an automated email from the git hooks/post-receive script.

sebasjm pushed a commit to branch master
in repository wallet-core.

The following commit(s) were added to refs/heads/master by this push:
     new 3e471d5f1 filter obs event
3e471d5f1 is described below

commit 3e471d5f1c0ae5a647859d22d40ef162d841f70e
Author: Sebastian <sebasjm@gmail.com>
AuthorDate: Tue May 7 15:36:57 2024 -0300

    filter obs event
---
 .../src/components/WalletActivity.tsx              | 505 ++++++++++-----------
 .../taler-wallet-webextension/src/mui/Button.tsx   |   6 +-
 packages/taler-wallet-webextension/src/wxApi.ts    |   7 +-
 .../taler-wallet-webextension/src/wxBackend.ts     | 171 ++++++-
 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;
       }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]