Compare commits

..

7 Commits

Author SHA1 Message Date
Dayuan Jiang
6fbc7b340f fix: move toast notifications to bottom-left (#489) 2026-01-01 22:08:05 +09:00
Dayuan Jiang
3c8f420c3c docs: add Cline MCP configuration instructions (#488) 2026-01-01 21:47:46 +09:00
Dayuan Jiang
f240c494ac fix: use npm install instead of npm ci in electron workflow (#487) 2026-01-01 17:42:39 +09:00
Dayuan Jiang
a22d7025a3 fix: sync package-lock.json (#486) 2026-01-01 17:32:25 +09:00
Dayuan Jiang
2159db5586 chore: bump version to 0.4.8 (#485) 2026-01-01 17:23:42 +09:00
Dayuan Jiang
ada06260db fix: faster message restore and skip panel animation on refresh (#483)
* fix: faster message restore and skip panel animation on refresh

- Use useLayoutEffect for localStorage restore (runs before paint)
- Track visibility changes to only animate panel when toggling, not on page load
- Use cn() utility for cleaner conditional className

* fix: reset animation state after completion for re-animation support

* revert: remove unnecessary animation reset timer
2026-01-01 16:25:39 +09:00
Dayuan Jiang
02527526ba fix: prevent flash of example panel and animations on page refresh (#482)
- Add isRestored state to track when localStorage restoration completes
- Show example panel only after confirming no saved messages exist
- Skip message animations for restored messages
- Default tool calls and reasoning blocks to collapsed for restored messages
2026-01-01 15:42:48 +09:00
5 changed files with 51 additions and 11 deletions

View File

@@ -38,7 +38,7 @@ jobs:
cache: "npm"
- name: Install dependencies
run: npm ci
run: npm install
- name: Build and publish Electron app
run: npm run dist:${{ matrix.platform }}

View File

@@ -10,7 +10,13 @@ import {
} from "lucide-react"
import Image from "next/image"
import type React from "react"
import { useCallback, useEffect, useRef, useState } from "react"
import {
useCallback,
useEffect,
useLayoutEffect,
useRef,
useState,
} from "react"
import { flushSync } from "react-dom"
import { Toaster, toast } from "sonner"
import { ButtonWithTooltip } from "@/components/button-with-tooltip"
@@ -28,7 +34,7 @@ import { formatMessage } from "@/lib/i18n/utils"
import { isPdfFile, isTextFile } from "@/lib/pdf-utils"
import { type FileData, useFileProcessor } from "@/lib/use-file-processor"
import { useQuotaManager } from "@/lib/use-quota-manager"
import { formatXML } from "@/lib/utils"
import { cn, formatXML } from "@/lib/utils"
import { ChatMessageDisplay } from "./chat-message-display"
import { DevXmlSimulator } from "./dev-xml-simulator"
@@ -203,6 +209,17 @@ export default function ChatPanel({
const hasRestoredRef = useRef(false)
const [isRestored, setIsRestored] = useState(false)
// Track previous isVisible to only animate when toggling (not on page load)
const prevIsVisibleRef = useRef(isVisible)
const [shouldAnimatePanel, setShouldAnimatePanel] = useState(false)
useEffect(() => {
// Only animate when visibility changes from false to true (not on initial load)
if (!prevIsVisibleRef.current && isVisible) {
setShouldAnimatePanel(true)
}
prevIsVisibleRef.current = isVisible
}, [isVisible])
// Ref to track latest chartXML for use in callbacks (avoids stale closure)
const chartXMLRef = useRef(chartXML)
useEffect(() => {
@@ -430,7 +447,8 @@ export default function ChatPanel({
const messagesEndRef = useRef<HTMLDivElement>(null)
// Restore messages and XML snapshots from localStorage on mount
useEffect(() => {
// useLayoutEffect runs synchronously before browser paint, so messages appear immediately
useLayoutEffect(() => {
if (hasRestoredRef.current) return
hasRestoredRef.current = true
@@ -461,7 +479,7 @@ export default function ChatPanel({
} finally {
setIsRestored(true)
}
}, [setMessages])
}, [setMessages, dict.errors.sessionCorrupted])
// Save messages to localStorage whenever they change (debounced to prevent blocking during streaming)
useEffect(() => {
@@ -918,12 +936,16 @@ export default function ChatPanel({
// Full view
return (
<div className="h-full flex flex-col bg-card shadow-soft animate-slide-in-right rounded-xl border border-border/30 relative">
<div
className={cn(
"h-full flex flex-col bg-card shadow-soft rounded-xl border border-border/30 relative",
shouldAnimatePanel && "animate-slide-in-right",
)}
>
<Toaster
position="bottom-center"
position="bottom-left"
richColors
expand
style={{ position: "absolute" }}
toastOptions={{
style: {
maxWidth: "480px",

4
package-lock.json generated
View File

@@ -1,12 +1,12 @@
{
"name": "next-ai-draw-io",
"version": "0.4.7",
"version": "0.4.8",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "next-ai-draw-io",
"version": "0.4.7",
"version": "0.4.8",
"license": "Apache-2.0",
"dependencies": {
"@ai-sdk/amazon-bedrock": "^4.0.1",

View File

@@ -1,6 +1,6 @@
{
"name": "next-ai-draw-io",
"version": "0.4.7",
"version": "0.4.8",
"license": "Apache-2.0",
"private": true,
"main": "dist-electron/main/index.js",

View File

@@ -64,6 +64,24 @@ Add to Cursor MCP config (`~/.cursor/mcp.json`):
}
```
### Cline (VS Code Extension)
1. Click the **MCP Servers** icon in Cline's top menu bar
2. Select the **Configure** tab
3. Click **Configure MCP Servers** to edit `cline_mcp_settings.json`
4. Add the drawio server:
```json
{
"mcpServers": {
"drawio": {
"command": "npx",
"args": ["@next-ai-drawio/mcp-server@latest"]
}
}
}
```
### Claude Code CLI
```bash