fix: note en double au retour et barre Gras/Italique à l’ouverture
All checks were successful
CI / Lint, Unit Tests & Build (push) Successful in 7m1s
CI / Deploy production (on server) (push) Successful in 23s

Ne plus réinjecter une note déjà dans la liste, et n’afficher le menu de formatage que sur une vraie sélection de texte.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Antigravity
2026-08-30 08:30:06 +00:00
parent 80ccc1f6de
commit e0fd5393ca
2 changed files with 34 additions and 16 deletions

View File

@@ -318,6 +318,8 @@ export function HomeClient({
}
setNotes((prevNotes) => {
if (prevNotes.some((n) => n.id === note.id)) return prevNotes
const notebookFilter = searchParams.get('notebook')
const labelFilter = searchParams.get('labels')?.split(',').filter(Boolean) || []
const colorFilter = searchParams.get('color')
@@ -630,12 +632,16 @@ export function HomeClient({
removeNoteFromList(detail.noteId)
setPinnedNotes(prev => prev.filter(n => n.id !== detail.noteId))
} else if (detail.type === 'created' && detail.note) {
setNotes(prev => [detail.note, ...prev])
setNotes((prev) => {
if (prev.some((n) => n.id === detail.note.id)) return prev
if (filterNotesForCurrentView([detail.note]).length === 0) return prev
return [detail.note, ...prev]
})
}
}
window.addEventListener(NOTE_CHANGE_EVENT, onNoteChange)
return () => window.removeEventListener(NOTE_CHANGE_EVENT, onNoteChange)
}, [patchNoteInList])
}, [patchNoteInList, filterNotesForCurrentView])
const handleGridReorder = useCallback(
async (orderedIds: string[]) => {
@@ -787,7 +793,12 @@ export function HomeClient({
// Apply sort order to notes
const sortedNotes = useMemo(() => {
let sorted = [...notes]
const seen = new Set<string>()
let sorted = notes.filter((n) => {
if (seen.has(n.id)) return false
seen.add(n.id)
return true
})
if (sortOrder === 'newest') sorted.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())
if (sortOrder === 'oldest') sorted.sort((a, b) => new Date(a.createdAt).getTime() - new Date(b.createdAt).getTime())
if (sortOrder === 'alpha') sorted.sort((a, b) => (a.title || '').localeCompare(b.title || ''))

View File

@@ -61,8 +61,7 @@ import { applyClipRtlDirection } from '@/lib/editor/apply-clip-rtl-direction'
import { NOTE_REQUEST_SAVE_EVENT } from '@/lib/note-change-sync'
import { openNotePeek } from '@/lib/note-peek-sync'
import { useAiConsent } from '@/components/legal/ai-consent-provider'
import type { Editor } from '@tiptap/core'
import type { EditorState } from '@tiptap/pm/state'
import { isTextSelection, type Editor } from '@tiptap/core'
import {
Bold, Italic, Underline as UnderlineIcon, Strikethrough, Code,
Heading1, Heading2, Heading3, List, ListOrdered, CheckSquare,
@@ -75,7 +74,7 @@ import {
} from 'lucide-react'
import { cn } from '@/lib/utils'
import { toast } from 'sonner'
import { NodeSelection } from '@tiptap/pm/state'
import { AllSelection, NodeSelection } from '@tiptap/pm/state'
export interface RichTextEditorHandle {
getEditor: () => Editor | null
@@ -1403,17 +1402,25 @@ export const RichTextEditor = forwardRef<RichTextEditorHandle, RichTextEditorPro
<BubbleMenu
editor={editor}
className="notion-bubble-menu"
{...({
tippyOptions: {
appendTo: () => document.body,
zIndex: 99999,
fallbackPlacements: ['bottom', 'top']
appendTo={() => document.body}
shouldShow={({ editor: e, state, from, to, view, element }) => {
if (!e.isEditable || e.isActive('codeBlock')) return false
const { selection } = state
if (selection instanceof AllSelection) return false
if (selection instanceof NodeSelection) {
return selection.node.type.name === 'image'
}
} as any)}
shouldShow={({ editor: e, state }: { editor: Editor; state: EditorState }) => {
const { from, to } = state.selection
const isImage = e.isActive('image')
return (from !== to && !e.isActive('codeBlock')) || isImage
if (!isTextSelection(selection) || selection.empty) return false
const selectedText = state.doc.textBetween(from, to)
if (!selectedText.length) return false
// setContent à louverture sélectionne parfois tout le document
const docSize = state.doc.content.size
if (docSize > 4 && from <= 1 && to >= docSize - 1) return false
return view.hasFocus() || element.contains(document.activeElement)
}}
>
<BubbleToolbar editor={editor} onSuggestCharts={handleOpenChartSuggestions} />