aboutsummaryrefslogtreecommitdiff
path: root/apps
diff options
context:
space:
mode:
authorMaheshtheDev <[email protected]>2025-11-09 07:32:51 +0000
committerMaheshtheDev <[email protected]>2025-11-09 07:32:52 +0000
commit10ada4a1e21ff913ab8edc58ca71039d91cc0ece (patch)
treee76b4361f4bd381be83431a9df25515e5b66256e /apps
parentchore: update posthog findings (#569) (diff)
downloadsupermemory-10ada4a1e21ff913ab8edc58ca71039d91cc0ece.tar.xz
supermemory-10ada4a1e21ff913ab8edc58ca71039d91cc0ece.zip
fix(web): sentry issues across the web app (#570)11-08-fix_web_sentry_issues_across_the_web_app
Fixes all following sentry issues - CONSUMER-APP-FF - CONSUMER-APP-1T - CONSUMER-APP-86 - CONSUMER-APP-7H - CONSUMER-APP-4F - CONSUMER-APP-7X
Diffstat (limited to 'apps')
-rw-r--r--apps/web/components/graph-dialog.tsx3
-rw-r--r--apps/web/components/memories.tsx99
-rw-r--r--apps/web/components/views/chat/chat-messages.tsx55
-rw-r--r--apps/web/stores/chat.ts2
4 files changed, 104 insertions, 55 deletions
diff --git a/apps/web/components/graph-dialog.tsx b/apps/web/components/graph-dialog.tsx
index 9378b592..2e74b3b1 100644
--- a/apps/web/components/graph-dialog.tsx
+++ b/apps/web/components/graph-dialog.tsx
@@ -62,6 +62,9 @@ export function GraphDialog() {
return response.data
},
getNextPageParam: (lastPage, allPages) => {
+ if (!lastPage || !lastPage.pagination) return undefined
+ if (!Array.isArray(allPages)) return undefined
+
const loaded = allPages.reduce(
(acc, p) => acc + (p.documents?.length ?? 0),
0,
diff --git a/apps/web/components/memories.tsx b/apps/web/components/memories.tsx
index 161d4f14..faf146c5 100644
--- a/apps/web/components/memories.tsx
+++ b/apps/web/components/memories.tsx
@@ -60,6 +60,9 @@ export function Memories() {
return response.data
},
getNextPageParam: (lastPage, allPages) => {
+ if (!lastPage || !lastPage.pagination) return undefined
+ if (!Array.isArray(allPages)) return undefined
+
const loaded = allPages.reduce(
(acc, p) => acc + (p.documents?.length ?? 0),
0,
@@ -177,42 +180,22 @@ export function Memories() {
}
return (
- <>
- <div className="relative h-full mx-4 md:mx-24">
- <MasonryMemoryList
- documents={allDocuments}
- error={error}
- hasMore={hasMore}
- isLoading={isPending}
- isLoadingMore={isLoadingMore}
- loadMoreDocuments={loadMoreDocuments}
- totalLoaded={totalLoaded}
- >
- <div className="absolute inset-0 flex items-center justify-center">
- {!isMobile ? (
- <ConnectAIModal
- onOpenChange={setShowConnectAIModal}
- open={showConnectAIModal}
- >
- <div className="rounded-xl overflow-hidden cursor-pointer hover:bg-white/5 transition-colors p-6">
- <div className="relative z-10 text-slate-200 text-center">
- <div className="flex flex-col gap-3">
- <button
- className="text-sm text-blue-400 hover:text-blue-300 transition-colors underline"
- onClick={(e) => {
- e.stopPropagation()
- setShowAddMemoryView(true)
- setShowConnectAIModal(false)
- }}
- type="button"
- >
- Add your first memory
- </button>
- </div>
- </div>
- </div>
- </ConnectAIModal>
- ) : (
+ <div className="relative h-full mx-4 md:mx-24">
+ <MasonryMemoryList
+ documents={allDocuments}
+ error={error}
+ hasMore={hasMore}
+ isLoading={isPending}
+ isLoadingMore={isLoadingMore}
+ loadMoreDocuments={loadMoreDocuments}
+ totalLoaded={totalLoaded}
+ >
+ <div className="absolute inset-0 flex items-center justify-center">
+ {!isMobile ? (
+ <ConnectAIModal
+ onOpenChange={setShowConnectAIModal}
+ open={showConnectAIModal}
+ >
<div className="rounded-xl overflow-hidden cursor-pointer hover:bg-white/5 transition-colors p-6">
<div className="relative z-10 text-slate-200 text-center">
<div className="flex flex-col gap-3">
@@ -221,6 +204,7 @@ export function Memories() {
onClick={(e) => {
e.stopPropagation()
setShowAddMemoryView(true)
+ setShowConnectAIModal(false)
}}
type="button"
>
@@ -229,17 +213,34 @@ export function Memories() {
</div>
</div>
</div>
- )}
- </div>
- </MasonryMemoryList>
-
- {showAddMemoryView && (
- <AddMemoryView
- initialTab="note"
- onClose={() => setShowAddMemoryView(false)}
- />
- )}
- </div>
- </>
+ </ConnectAIModal>
+ ) : (
+ <div className="rounded-xl overflow-hidden cursor-pointer hover:bg-white/5 transition-colors p-6">
+ <div className="relative z-10 text-slate-200 text-center">
+ <div className="flex flex-col gap-3">
+ <button
+ className="text-sm text-blue-400 hover:text-blue-300 transition-colors underline"
+ onClick={(e) => {
+ e.stopPropagation()
+ setShowAddMemoryView(true)
+ }}
+ type="button"
+ >
+ Add your first memory
+ </button>
+ </div>
+ </div>
+ </div>
+ )}
+ </div>
+ </MasonryMemoryList>
+
+ {showAddMemoryView && (
+ <AddMemoryView
+ initialTab="note"
+ onClose={() => setShowAddMemoryView(false)}
+ />
+ )}
+ </div>
)
-} \ No newline at end of file
+}
diff --git a/apps/web/components/views/chat/chat-messages.tsx b/apps/web/components/views/chat/chat-messages.tsx
index ff4eca34..0c795ec0 100644
--- a/apps/web/components/views/chat/chat-messages.tsx
+++ b/apps/web/components/views/chat/chat-messages.tsx
@@ -1,6 +1,6 @@
"use client"
-import { useChat, useCompletion } from "@ai-sdk/react"
+import { useChat, useCompletion, type UIMessage } from "@ai-sdk/react"
import { cn } from "@lib/utils"
import { Button } from "@ui/components/button"
import { DefaultChatTransport } from "ai"
@@ -21,6 +21,7 @@ import { usePersistentChat, useProject } from "@/stores"
import { useGraphHighlights } from "@/stores/highlights"
import { modelNames, ModelIcon } from "@/lib/models"
import { Spinner } from "../../spinner"
+import { areUIMessageArraysEqual } from "@/stores/chat"
interface MemoryResult {
documentId?: string
@@ -247,6 +248,10 @@ export function ChatMessages() {
const activeChatIdRef = useRef<string | null>(null)
const shouldGenerateTitleRef = useRef<boolean>(false)
const hasRunInitialMessageRef = useRef<boolean>(false)
+ const lastSavedMessagesRef = useRef<UIMessage[] | null>(null)
+ const lastSavedActiveIdRef = useRef<string | null>(null)
+ const lastLoadedChatIdRef = useRef<string | null>(null)
+ const lastLoadedMessagesRef = useRef<UIMessage[] | null>(null)
const { setDocumentIds } = useGraphHighlights()
@@ -283,6 +288,10 @@ export function ChatMessages() {
})
useEffect(() => {
+ lastLoadedMessagesRef.current = messages
+ }, [messages])
+
+ useEffect(() => {
activeChatIdRef.current = currentChatId ?? id ?? null
}, [currentChatId, id])
@@ -326,20 +335,56 @@ export function ChatMessages() {
}, [id, currentChatId, setCurrentChatId])
useEffect(() => {
+ if (currentChatId !== lastLoadedChatIdRef.current) {
+ lastLoadedMessagesRef.current = null
+ lastSavedMessagesRef.current = null
+ }
+
+ if (currentChatId === lastLoadedChatIdRef.current) {
+ setInput("")
+ return
+ }
+
const msgs = getCurrentConversation()
+
if (msgs && msgs.length > 0) {
- setMessages(msgs)
+ const currentMessages = lastLoadedMessagesRef.current
+ if (!currentMessages || !areUIMessageArraysEqual(currentMessages, msgs)) {
+ lastLoadedMessagesRef.current = msgs
+ setMessages(msgs)
+ }
} else if (!currentChatId) {
- setMessages([])
+ if (
+ lastLoadedMessagesRef.current &&
+ lastLoadedMessagesRef.current.length > 0
+ ) {
+ lastLoadedMessagesRef.current = []
+ setMessages([])
+ }
}
+
+ lastLoadedChatIdRef.current = currentChatId
setInput("")
}, [currentChatId, getCurrentConversation, setMessages])
useEffect(() => {
const activeId = currentChatId ?? id
- if (activeId && messages.length > 0) {
- setConversation(activeId, messages)
+ if (!activeId || messages.length === 0) {
+ return
}
+
+ if (activeId !== lastSavedActiveIdRef.current) {
+ lastSavedMessagesRef.current = null
+ lastSavedActiveIdRef.current = activeId
+ }
+
+ const lastSaved = lastSavedMessagesRef.current
+ if (lastSaved && areUIMessageArraysEqual(lastSaved, messages)) {
+ return
+ }
+
+ lastSavedMessagesRef.current = messages
+ setConversation(activeId, messages)
}, [messages, currentChatId, id, setConversation])
const { complete } = useCompletion({
diff --git a/apps/web/stores/chat.ts b/apps/web/stores/chat.ts
index f1701139..24f4084b 100644
--- a/apps/web/stores/chat.ts
+++ b/apps/web/stores/chat.ts
@@ -7,7 +7,7 @@ import { indexedDBStorage } from "./indexeddb-storage"
/**
* Deep equality check for UIMessage arrays to prevent unnecessary state updates
*/
-function areUIMessageArraysEqual(a: UIMessage[], b: UIMessage[]): boolean {
+export function areUIMessageArraysEqual(a: UIMessage[], b: UIMessage[]): boolean {
if (a === b) return true
if (a.length !== b.length) return false