feat: 8 AI providers, rich text editor, agent notifications, UI contrast & font settings
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 1m25s
All checks were successful
Deploy to Production / Build and Deploy (push) Successful in 1m25s
- Add DeepSeek, OpenRouter, Mistral, Z.AI, LM Studio as AI providers with editable model names via Combobox in admin settings - Fix OpenRouter broken by normalizeProvider bug in config.ts - Convert agent-created notes from Markdown to HTML (TipTap rich text) - Add Notification model + in-app notifications for agent results - Agent notification click opens the created note directly - Add note count display on notebook and inbox headers - Fix checklist toggle in card view (persist state via localCheckItems) - Add checklist creation option in tabs/list view (dropdown on + button) - Fix image description ENOENT error with HTTP fallback - Improve UI contrast across all themes (input, border, checkbox visibility) - Add font family setting (Inter vs System Default) in Appearance settings - Fix CSS font-sans variable conflict (removed dead Geist references) - Update README with new features and 8 providers Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -218,6 +218,13 @@ export const NoteCard = memo(function NoteCard({
|
||||
|
||||
// Local color state so color persists after transition ends
|
||||
const [localColor, setLocalColor] = useState(note.color)
|
||||
// Local checkItems state so checklist toggles persist after transition ends
|
||||
const [localCheckItems, setLocalCheckItems] = useState(note.checkItems)
|
||||
|
||||
// Sync local state when parent data refreshes
|
||||
useEffect(() => {
|
||||
setLocalCheckItems(note.checkItems)
|
||||
}, [note.checkItems])
|
||||
|
||||
const colorClasses = NOTE_COLORS[(localColor || optimisticNote.color) as NoteColor] || NOTE_COLORS.default
|
||||
|
||||
@@ -373,14 +380,15 @@ export const NoteCard = memo(function NoteCard({
|
||||
}
|
||||
|
||||
const handleCheckItem = async (checkItemId: string) => {
|
||||
if (note.type === 'checklist' && Array.isArray(note.checkItems)) {
|
||||
const updatedItems = note.checkItems.map(item =>
|
||||
if (note.type === 'checklist') {
|
||||
const currentItems = localCheckItems || note.checkItems || []
|
||||
const updatedItems = currentItems.map(item =>
|
||||
item.id === checkItemId ? { ...item, checked: !item.checked } : item
|
||||
)
|
||||
setLocalCheckItems(updatedItems) // instant visual update, survives transition
|
||||
startTransition(async () => {
|
||||
addOptimisticNote({ checkItems: updatedItems })
|
||||
await updateNote(note.id, { checkItems: updatedItems })
|
||||
// No router.refresh() — optimistic update is sufficient and avoids grid rebuild
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -621,7 +629,7 @@ export const NoteCard = memo(function NoteCard({
|
||||
{/* Content */}
|
||||
{optimisticNote.type === 'checklist' ? (
|
||||
<NoteChecklist
|
||||
items={optimisticNote.checkItems || []}
|
||||
items={localCheckItems || optimisticNote.checkItems || []}
|
||||
onToggleItem={handleCheckItem}
|
||||
/>
|
||||
) : optimisticNote.type === 'richtext' ? (
|
||||
|
||||
Reference in New Issue
Block a user