diff options
| author | Adam <[email protected]> | 2026-01-06 21:38:08 -0600 |
|---|---|---|
| committer | Adam <[email protected]> | 2026-01-06 21:42:03 -0600 |
| commit | 761863ae355b3ca1e606ea5eb2106772fa763c19 (patch) | |
| tree | f8fef26687875e75f4279b6695e35a33977b728c /packages/app/src/context/notification.tsx | |
| parent | dadc08ddc7f3c9b1a34e6f401a99406b6714b965 (diff) | |
| download | opencode-761863ae355b3ca1e606ea5eb2106772fa763c19.tar.gz opencode-761863ae355b3ca1e606ea5eb2106772fa763c19.zip | |
chore(app): rework storage approach
Diffstat (limited to 'packages/app/src/context/notification.tsx')
| -rw-r--r-- | packages/app/src/context/notification.tsx | 33 |
1 files changed, 28 insertions, 5 deletions
diff --git a/packages/app/src/context/notification.tsx b/packages/app/src/context/notification.tsx index 09f32a3c4..16b3d306c 100644 --- a/packages/app/src/context/notification.tsx +++ b/packages/app/src/context/notification.tsx @@ -1,5 +1,5 @@ import { createStore } from "solid-js/store" -import { onCleanup } from "solid-js" +import { createEffect, onCleanup } from "solid-js" import { createSimpleContext } from "@opencode-ai/ui/context" import { useGlobalSDK } from "./global-sdk" import { useGlobalSync } from "./global-sync" @@ -10,7 +10,7 @@ import { EventSessionError } from "@opencode-ai/sdk/v2" import { makeAudioPlayer } from "@solid-primitives/audio" import idleSound from "@opencode-ai/ui/audio/staplebops-01.aac" import errorSound from "@opencode-ai/ui/audio/nope-03.aac" -import { persisted } from "@/utils/persist" +import { Persist, persisted } from "@/utils/persist" type NotificationBase = { directory?: string @@ -31,6 +31,16 @@ type ErrorNotification = NotificationBase & { export type Notification = TurnCompleteNotification | ErrorNotification +const MAX_NOTIFICATIONS = 500 +const NOTIFICATION_TTL_MS = 1000 * 60 * 60 * 24 * 30 + +function pruneNotifications(list: Notification[]) { + const cutoff = Date.now() - NOTIFICATION_TTL_MS + const pruned = list.filter((n) => n.time >= cutoff) + if (pruned.length <= MAX_NOTIFICATIONS) return pruned + return pruned.slice(pruned.length - MAX_NOTIFICATIONS) +} + export const { use: useNotification, provider: NotificationProvider } = createSimpleContext({ name: "Notification", init: () => { @@ -49,12 +59,25 @@ export const { use: useNotification, provider: NotificationProvider } = createSi const platform = usePlatform() const [store, setStore, _, ready] = persisted( - "notification.v1", + Persist.global("notification", ["notification.v1"]), createStore({ list: [] as Notification[], }), ) + const meta = { pruned: false } + + createEffect(() => { + if (!ready()) return + if (meta.pruned) return + meta.pruned = true + setStore("list", pruneNotifications(store.list)) + }) + + const append = (notification: Notification) => { + setStore("list", (list) => pruneNotifications([...list, notification])) + } + const unsub = globalSDK.event.listen((e) => { const directory = e.name const event = e.details @@ -73,7 +96,7 @@ export const { use: useNotification, provider: NotificationProvider } = createSi try { idlePlayer?.play() } catch {} - setStore("list", store.list.length, { + append({ ...base, type: "turn-complete", session: sessionID, @@ -92,7 +115,7 @@ export const { use: useNotification, provider: NotificationProvider } = createSi errorPlayer?.play() } catch {} const error = "error" in event.properties ? event.properties.error : undefined - setStore("list", store.list.length, { + append({ ...base, type: "error", session: sessionID ?? "global", |
