From c87232d5dfee75d117f450181457ebf328c6e5c6 Mon Sep 17 00:00:00 2001 From: adamelmore <2363879+adamdottv@users.noreply.github.com> Date: Mon, 26 Jan 2026 06:06:10 -0600 Subject: [PATCH] perf(app): performance improvements --- packages/app/src/context/notification.tsx | 71 ++++++++++++++++++++--- packages/app/src/pages/home.tsx | 11 ++-- packages/app/src/pages/layout.tsx | 59 ++++++++++--------- 3 files changed, 101 insertions(+), 40 deletions(-) diff --git a/packages/app/src/context/notification.tsx b/packages/app/src/context/notification.tsx index 1c5953b3f..5e35f6ac0 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 { createEffect, onCleanup } from "solid-js" +import { createEffect, createMemo, onCleanup } from "solid-js" import { useParams } from "@solidjs/router" import { createSimpleContext } from "@opencode-ai/ui/context" import { useGlobalSDK } from "./global-sdk" @@ -52,6 +52,15 @@ export const { use: useNotification, provider: NotificationProvider } = createSi const settings = useSettings() const language = useLanguage() + const empty: Notification[] = [] + + const currentDirectory = createMemo(() => { + if (!params.dir) return + return base64Decode(params.dir) + }) + + const currentSession = createMemo(() => params.id) + const [store, setStore, _, ready] = persisted( Persist.global("notification", ["notification.v1"]), createStore({ @@ -72,13 +81,59 @@ export const { use: useNotification, provider: NotificationProvider } = createSi setStore("list", (list) => pruneNotifications([...list, notification])) } + const index = createMemo(() => { + const sessionAll = new Map() + const sessionUnseen = new Map() + const projectAll = new Map() + const projectUnseen = new Map() + + for (const notification of store.list) { + const session = notification.session + if (session) { + const list = sessionAll.get(session) + if (list) list.push(notification) + else sessionAll.set(session, [notification]) + if (!notification.viewed) { + const unseen = sessionUnseen.get(session) + if (unseen) unseen.push(notification) + else sessionUnseen.set(session, [notification]) + } + } + + const directory = notification.directory + if (directory) { + const list = projectAll.get(directory) + if (list) list.push(notification) + else projectAll.set(directory, [notification]) + if (!notification.viewed) { + const unseen = projectUnseen.get(directory) + if (unseen) unseen.push(notification) + else projectUnseen.set(directory, [notification]) + } + } + } + + return { + session: { + all: sessionAll, + unseen: sessionUnseen, + }, + project: { + all: projectAll, + unseen: projectUnseen, + }, + } + }) + const unsub = globalSDK.event.listen((e) => { - const directory = e.name const event = e.details + if (event.type !== "session.idle" && event.type !== "session.error") return + + const directory = e.name const time = Date.now() - const activeDirectory = params.dir ? base64Decode(params.dir) : undefined - const activeSession = params.id const viewed = (sessionID?: string) => { + const activeDirectory = currentDirectory() + const activeSession = currentSession() if (!activeDirectory) return false if (!activeSession) return false if (!sessionID) return false @@ -148,10 +203,10 @@ export const { use: useNotification, provider: NotificationProvider } = createSi ready, session: { all(session: string) { - return store.list.filter((n) => n.session === session) + return index().session.all.get(session) ?? empty }, unseen(session: string) { - return store.list.filter((n) => n.session === session && !n.viewed) + return index().session.unseen.get(session) ?? empty }, markViewed(session: string) { setStore("list", (n) => n.session === session, "viewed", true) @@ -159,10 +214,10 @@ export const { use: useNotification, provider: NotificationProvider } = createSi }, project: { all(directory: string) { - return store.list.filter((n) => n.directory === directory) + return index().project.all.get(directory) ?? empty }, unseen(directory: string) { - return store.list.filter((n) => n.directory === directory && !n.viewed) + return index().project.unseen.get(directory) ?? empty }, markViewed(directory: string) { setStore("list", (n) => n.directory === directory, "viewed", true) diff --git a/packages/app/src/pages/home.tsx b/packages/app/src/pages/home.tsx index 0c04c0767..10f7dac53 100644 --- a/packages/app/src/pages/home.tsx +++ b/packages/app/src/pages/home.tsx @@ -23,6 +23,11 @@ export default function Home() { const server = useServer() const language = useLanguage() const homedir = createMemo(() => sync.data.path.home) + const recent = createMemo(() => { + return sync.data.project + .toSorted((a, b) => (b.time.updated ?? b.time.created) - (a.time.updated ?? a.time.created)) + .slice(0, 5) + }) function openProject(directory: string) { layout.projects.open(directory) @@ -84,11 +89,7 @@ export default function Home() {
    - (b.time.updated ?? b.time.created) - (a.time.updated ?? a.time.created)) - .slice(0, 5)} - > + {(project) => (