mirror of
https://github.com/supermemoryai/supermemory.git
synced 2026-08-28 05:25:33 +00:00
feat(graph): auto-paginate consumer graph + loading progress chip (#966)
This commit is contained in:
parent
39f30f10b2
commit
fbd9f5e4cf
3 changed files with 58 additions and 4 deletions
|
|
@ -46,6 +46,7 @@ export const GraphLayoutView = memo(function GraphLayoutView({
|
|||
maxNodes={undefined}
|
||||
canvasRef={canvasRef}
|
||||
onOpenDocument={onOpenDocument}
|
||||
autoFetchAll
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
"use client"
|
||||
|
||||
import { useInfiniteQuery } from "@tanstack/react-query"
|
||||
import { useMemo } from "react"
|
||||
import { useEffect, useMemo } from "react"
|
||||
import { $fetch } from "@lib/api"
|
||||
import type {
|
||||
GraphApiDocument,
|
||||
|
|
@ -15,6 +15,7 @@ interface UseGraphApiOptions {
|
|||
containerTags?: string[]
|
||||
documentIds?: string[]
|
||||
enabled?: boolean
|
||||
autoFetchAll?: boolean
|
||||
}
|
||||
|
||||
interface ApiMemoryEntry {
|
||||
|
|
@ -108,7 +109,12 @@ function toGraphDocument(
|
|||
}
|
||||
|
||||
export function useGraphApi(options: UseGraphApiOptions = {}) {
|
||||
const { containerTags, documentIds, enabled = true } = options
|
||||
const {
|
||||
containerTags,
|
||||
documentIds,
|
||||
enabled = true,
|
||||
autoFetchAll = false,
|
||||
} = options
|
||||
const filteredDocumentIds = documentIds?.filter(Boolean)
|
||||
const hasDocumentIds =
|
||||
filteredDocumentIds != null && filteredDocumentIds.length > 0
|
||||
|
|
@ -163,6 +169,19 @@ export function useGraphApi(options: UseGraphApiOptions = {}) {
|
|||
enabled,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (!autoFetchAll || !enabled) return
|
||||
if (!hasNextPage || isPending || isFetchingNextPage) return
|
||||
fetchNextPage()
|
||||
}, [
|
||||
autoFetchAll,
|
||||
enabled,
|
||||
hasNextPage,
|
||||
isPending,
|
||||
isFetchingNextPage,
|
||||
fetchNextPage,
|
||||
])
|
||||
|
||||
const documents = useMemo(() => {
|
||||
if (!data?.pages) return []
|
||||
return data.pages.flatMap((page) =>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,11 @@
|
|||
"use client"
|
||||
|
||||
import { useEffect, useRef, useState } from "react"
|
||||
import { useEffect, useMemo, useRef, useState } from "react"
|
||||
import { Loader2 } from "lucide-react"
|
||||
import { MemoryGraph as MemoryGraphBase } from "@supermemory/memory-graph"
|
||||
import type { GraphThemeColors } from "@supermemory/memory-graph"
|
||||
import { useGraphApi } from "./hooks/use-graph-api"
|
||||
import { cn } from "@lib/utils"
|
||||
|
||||
export interface MemoryGraphWrapperProps {
|
||||
children?: React.ReactNode
|
||||
|
|
@ -21,6 +23,7 @@ export interface MemoryGraphWrapperProps {
|
|||
onSlideshowStop?: () => void
|
||||
canvasRef?: React.RefObject<HTMLCanvasElement | null>
|
||||
onOpenDocument?: (documentId: string) => void
|
||||
autoFetchAll?: boolean
|
||||
}
|
||||
|
||||
export function MemoryGraph({
|
||||
|
|
@ -32,6 +35,7 @@ export function MemoryGraph({
|
|||
documentIds,
|
||||
maxNodes,
|
||||
canvasRef,
|
||||
autoFetchAll = false,
|
||||
...rest
|
||||
}: MemoryGraphWrapperProps) {
|
||||
const [containerSize, setContainerSize] = useState({ width: 0, height: 0 })
|
||||
|
|
@ -60,10 +64,22 @@ export function MemoryGraph({
|
|||
containerTags,
|
||||
documentIds,
|
||||
enabled: containerSize.width > 0 && containerSize.height > 0,
|
||||
autoFetchAll,
|
||||
})
|
||||
|
||||
const loadedDocCount = documents.length
|
||||
const loadedMemoryCount = useMemo(
|
||||
() => documents.reduce((sum, doc) => sum + doc.memories.length, 0),
|
||||
[documents],
|
||||
)
|
||||
const showProgress =
|
||||
autoFetchAll &&
|
||||
!apiIsLoading &&
|
||||
totalCount > 0 &&
|
||||
(hasMore || isLoadingMore || loadedDocCount < totalCount)
|
||||
|
||||
return (
|
||||
<div ref={containerRef} className="size-full [&>div]:!bg-none">
|
||||
<div ref={containerRef} className="relative size-full [&>div]:!bg-none">
|
||||
<MemoryGraphBase
|
||||
documents={documents}
|
||||
isLoading={externalIsLoading || apiIsLoading}
|
||||
|
|
@ -85,6 +101,24 @@ export function MemoryGraph({
|
|||
>
|
||||
{children}
|
||||
</MemoryGraphBase>
|
||||
{showProgress && (
|
||||
<div
|
||||
className={cn(
|
||||
"absolute right-3 top-3 z-15 md:right-4 md:top-4",
|
||||
"flex items-center gap-2 rounded-full",
|
||||
"bg-background/85 px-3 py-1.5 text-xs backdrop-blur-md",
|
||||
"border border-border/60 shadow-sm",
|
||||
)}
|
||||
aria-live="polite"
|
||||
>
|
||||
<Loader2 className="size-3 shrink-0 animate-spin text-muted-foreground" />
|
||||
<span className="tabular-nums">
|
||||
{loadedMemoryCount.toLocaleString()} memories ·{" "}
|
||||
{loadedDocCount.toLocaleString()}/{totalCount.toLocaleString()}{" "}
|
||||
documents
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue