develop #1

Merged
darroyo merged 25 commits from develop into main 2026-03-24 01:31:17 +00:00
3 changed files with 35 additions and 10 deletions
Showing only changes of commit 33a4705f95 - Show all commits

View File

@@ -47,7 +47,7 @@ export function KeyboardNavigableNoteList({
}
}, [])
const { selectedIndex } = useNoteListKeyboard({
const { selectedIndex, prefetchNote } = useNoteListKeyboard({
notes,
onEdit,
onFavorite: handleFavorite,

View File

@@ -1,6 +1,7 @@
'use client'
import Link from 'next/link'
import { useRouter } from 'next/navigation'
import { Note } from '@/types/note'
import { Card, CardContent } from '@/components/ui/card'
import { Badge } from '@/components/ui/badge'
@@ -16,12 +17,21 @@ const typeColors: Record<string, string> = {
}
export function NoteCard({ note }: { note: Note }) {
const router = useRouter()
const preview = note.content.slice(0, 100) + (note.content.length > 100 ? '...' : '')
const typeColor = typeColors[note.type] || typeColors.note
const handleMouseEnter = () => {
// Prefetch on hover for faster navigation
router.prefetch(`/notes/${note.id}`)
}
return (
<Link href={`/notes/${note.id}`}>
<Card className="hover:shadow-md transition-shadow cursor-pointer h-full">
<Link href={`/notes/${note.id}`} prefetch={true}>
<Card
className="hover:shadow-md transition-shadow cursor-pointer h-full"
onMouseEnter={handleMouseEnter}
>
<CardContent className="p-4">
<div className="flex items-start justify-between gap-2 mb-2">
<h3 className="font-semibold text-lg line-clamp-1">{note.title}</h3>

View File

@@ -1,4 +1,4 @@
import { useEffect, useCallback, useState } from 'react'
import { useEffect, useCallback, useState, useRef } from 'react'
import { useRouter } from 'next/navigation'
import { Note } from '@/types/note'
@@ -17,10 +17,19 @@ export function useNoteListKeyboard({
}: UseNoteListKeyboardOptions) {
const [selectedIndex, setSelectedIndex] = useState(-1)
const router = useRouter()
const prefetchedRef = useRef<Set<string>>(new Set())
// Prefetch a note's page data for faster navigation
const prefetchNote = useCallback((noteId: string) => {
if (prefetchedRef.current.has(noteId)) return
prefetchedRef.current.add(noteId)
router.prefetch(`/notes/${noteId}`)
}, [router])
// Reset selection when notes change
useEffect(() => {
setSelectedIndex(-1)
prefetchedRef.current.clear()
}, [notes.length])
const handleKeyDown = useCallback(
@@ -38,13 +47,19 @@ export function useNoteListKeyboard({
switch (e.key) {
case 'ArrowDown':
e.preventDefault()
setSelectedIndex((prev) =>
prev < notes.length - 1 ? prev + 1 : notes.length - 1
)
setSelectedIndex((prev) => {
const next = prev < notes.length - 1 ? prev + 1 : notes.length - 1
if (notes[next]) prefetchNote(notes[next].id)
return next
})
break
case 'ArrowUp':
e.preventDefault()
setSelectedIndex((prev) => (prev > 0 ? prev - 1 : -1))
setSelectedIndex((prev) => {
const next = prev > 0 ? prev - 1 : -1
if (next >= 0 && notes[next]) prefetchNote(notes[next].id)
return next
})
break
case 'Enter':
e.preventDefault()
@@ -75,7 +90,7 @@ export function useNoteListKeyboard({
break
}
},
[notes, selectedIndex, router, onEdit, onFavorite, onPin]
[notes, selectedIndex, router, onEdit, onFavorite, onPin, prefetchNote]
)
useEffect(() => {
@@ -83,5 +98,5 @@ export function useNoteListKeyboard({
return () => window.removeEventListener('keydown', handleKeyDown)
}, [handleKeyDown])
return { selectedIndex, setSelectedIndex }
return { selectedIndex, setSelectedIndex, prefetchNote }
}