fix(keep-notes): sidebar chevron, labels sync, batch org errors, perf guards

- Notebooks: chevron visible when expanded (remove overflow clip), functional expand state
- Labels: sync/cleanup by notebookId, reconcile after note move
- Settings: refresh notebooks after cleanup; label dialog routing
- ConnectionsBadge lazy-load; reminder check persistence; i18n keys

Made-with: Cursor
This commit is contained in:
Sepehr Ramezani
2026-04-13 22:07:09 +02:00
parent fa7e166f3e
commit 39671c6472
16 changed files with 469 additions and 303 deletions

View File

@@ -1,6 +1,6 @@
'use client'
import { memo, useState, useEffect } from 'react'
import { memo, useState, useEffect, useRef, useCallback } from 'react'
import { Sparkles } from 'lucide-react'
import { cn } from '@/lib/utils'
import { useLanguage } from '@/lib/i18n/LanguageProvider'
@@ -15,45 +15,40 @@ interface ConnectionsBadgeProps {
export const ConnectionsBadge = memo(function ConnectionsBadge({ noteId, onClick, className }: ConnectionsBadgeProps) {
const { t } = useLanguage()
const [connectionCount, setConnectionCount] = useState<number>(0)
const [isLoading, setIsLoading] = useState(false)
const [isHovered, setIsHovered] = useState(false)
const [fetchAttempted, setFetchAttempted] = useState(false)
const containerRef = useRef<HTMLSpanElement>(null)
const fetchedRef = useRef(false)
const fetchConnections = useCallback(async () => {
if (fetchedRef.current) return
fetchedRef.current = true
try {
const count = await getConnectionsCount(noteId)
setConnectionCount(count)
} catch {
setConnectionCount(0)
}
}, [noteId])
useEffect(() => {
if (fetchAttempted) return
setFetchAttempted(true)
const el = containerRef.current
if (!el) return
let isMounted = true
const fetchConnections = async () => {
setIsLoading(true)
try {
const count = await getConnectionsCount(noteId)
if (isMounted) {
setConnectionCount(count)
const observer = new IntersectionObserver(
([entry]) => {
if (entry.isIntersecting) {
fetchConnections()
observer.disconnect()
}
} catch (error) {
console.error('[ConnectionsBadge] Failed to fetch connections:', error)
if (isMounted) {
setConnectionCount(0)
}
} finally {
if (isMounted) {
setIsLoading(false)
}
}
}
},
{ rootMargin: '200px' }
)
observer.observe(el)
return () => observer.disconnect()
}, [fetchConnections])
fetchConnections()
return () => {
isMounted = false
}
}, [noteId]) // eslint-disable-line react-hooks/exhaustive-deps
// Don't render if no connections or still loading
if (connectionCount === 0 || isLoading) {
return null
if (connectionCount === 0) {
return <span ref={containerRef} className="hidden" />
}
const plural = connectionCount > 1 ? 's' : ''