2025-12-06 12:46:40 +09:00
|
|
|
"use client"
|
2025-03-26 00:30:00 +00:00
|
|
|
|
2025-12-06 12:46:40 +09:00
|
|
|
import type React from "react"
|
2025-12-18 20:14:10 +08:00
|
|
|
import { createContext, useContext, useEffect, useRef, useState } from "react"
|
2025-12-06 12:46:40 +09:00
|
|
|
import type { DrawIoEmbedRef } from "react-drawio"
|
2026-01-04 09:41:32 +05:30
|
|
|
import { toast } from "sonner"
|
2025-12-06 12:46:40 +09:00
|
|
|
import type { ExportFormat } from "@/components/save-dialog"
|
2025-12-22 19:58:55 +05:30
|
|
|
import { getApiEndpoint } from "@/lib/base-path"
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
import {
|
|
|
|
|
extractDiagramXML,
|
|
|
|
|
isRealDiagram,
|
|
|
|
|
validateAndFixXml,
|
|
|
|
|
} from "../lib/utils"
|
2025-03-26 00:30:00 +00:00
|
|
|
|
|
|
|
|
interface DiagramContextType {
|
2025-12-06 12:46:40 +09:00
|
|
|
chartXML: string
|
|
|
|
|
latestSvg: string
|
|
|
|
|
diagramHistory: { svg: string; xml: string }[]
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
setDiagramHistory: (history: { svg: string; xml: string }[]) => void
|
2025-12-07 14:38:15 +09:00
|
|
|
loadDiagram: (chart: string, skipValidation?: boolean) => string | null
|
2025-12-06 12:46:40 +09:00
|
|
|
handleExport: () => void
|
|
|
|
|
handleExportWithoutHistory: () => void
|
|
|
|
|
resolverRef: React.Ref<((value: string) => void) | null>
|
|
|
|
|
drawioRef: React.Ref<DrawIoEmbedRef | null>
|
|
|
|
|
handleDiagramExport: (data: any) => void
|
|
|
|
|
clearDiagram: () => void
|
|
|
|
|
saveDiagramToFile: (
|
|
|
|
|
filename: string,
|
|
|
|
|
format: ExportFormat,
|
|
|
|
|
sessionId?: string,
|
2026-01-04 09:41:32 +05:30
|
|
|
successMessage?: string,
|
2025-12-06 12:46:40 +09:00
|
|
|
) => void
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
getThumbnailSvg: () => Promise<string | null>
|
2025-12-07 01:39:09 +09:00
|
|
|
isDrawioReady: boolean
|
|
|
|
|
onDrawioLoad: () => void
|
2025-12-10 08:21:15 +08:00
|
|
|
resetDrawioReady: () => void
|
2025-12-17 20:24:53 +09:00
|
|
|
showSaveDialog: boolean
|
|
|
|
|
setShowSaveDialog: (show: boolean) => void
|
2025-03-26 00:30:00 +00:00
|
|
|
}
|
|
|
|
|
|
2025-12-06 12:46:40 +09:00
|
|
|
const DiagramContext = createContext<DiagramContextType | undefined>(undefined)
|
2025-03-26 00:30:00 +00:00
|
|
|
|
|
|
|
|
export function DiagramProvider({ children }: { children: React.ReactNode }) {
|
2025-12-06 12:46:40 +09:00
|
|
|
const [chartXML, setChartXML] = useState<string>("")
|
|
|
|
|
const [latestSvg, setLatestSvg] = useState<string>("")
|
2025-03-26 00:30:00 +00:00
|
|
|
const [diagramHistory, setDiagramHistory] = useState<
|
|
|
|
|
{ svg: string; xml: string }[]
|
2025-12-06 12:46:40 +09:00
|
|
|
>([])
|
2025-12-07 01:39:09 +09:00
|
|
|
const [isDrawioReady, setIsDrawioReady] = useState(false)
|
2025-12-17 20:24:53 +09:00
|
|
|
const [showSaveDialog, setShowSaveDialog] = useState(false)
|
2025-12-07 01:39:09 +09:00
|
|
|
const hasCalledOnLoadRef = useRef(false)
|
2025-12-06 12:46:40 +09:00
|
|
|
const drawioRef = useRef<DrawIoEmbedRef | null>(null)
|
|
|
|
|
const resolverRef = useRef<((value: string) => void) | null>(null)
|
2025-12-03 13:53:16 +09:00
|
|
|
// Track if we're expecting an export for history (user-initiated)
|
2025-12-06 12:46:40 +09:00
|
|
|
const expectHistoryExportRef = useRef<boolean>(false)
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
// Track if diagram has been restored after DrawIO remount (e.g., theme change)
|
2025-12-18 20:14:10 +08:00
|
|
|
const hasDiagramRestoredRef = useRef<boolean>(false)
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
// Track latest chartXML for restoration after remount
|
|
|
|
|
const chartXMLRef = useRef<string>("")
|
2025-12-07 01:39:09 +09:00
|
|
|
|
|
|
|
|
const onDrawioLoad = () => {
|
|
|
|
|
// Only set ready state once to prevent infinite loops
|
|
|
|
|
if (hasCalledOnLoadRef.current) return
|
|
|
|
|
hasCalledOnLoadRef.current = true
|
|
|
|
|
setIsDrawioReady(true)
|
|
|
|
|
}
|
2025-12-10 08:21:15 +08:00
|
|
|
|
|
|
|
|
const resetDrawioReady = () => {
|
|
|
|
|
hasCalledOnLoadRef.current = false
|
|
|
|
|
setIsDrawioReady(false)
|
|
|
|
|
}
|
|
|
|
|
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
// Keep chartXMLRef in sync with state for restoration after remount
|
2025-12-18 20:14:10 +08:00
|
|
|
useEffect(() => {
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
chartXMLRef.current = chartXML
|
|
|
|
|
}, [chartXML])
|
|
|
|
|
|
|
|
|
|
// Restore diagram when DrawIO becomes ready after remount (e.g., theme/UI change)
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
// Reset restore flag when DrawIO is not ready (preparing for next restore cycle)
|
2025-12-18 20:14:10 +08:00
|
|
|
if (!isDrawioReady) {
|
|
|
|
|
hasDiagramRestoredRef.current = false
|
|
|
|
|
return
|
|
|
|
|
}
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
// Only restore once per ready cycle
|
2025-12-18 20:14:10 +08:00
|
|
|
if (hasDiagramRestoredRef.current) return
|
|
|
|
|
hasDiagramRestoredRef.current = true
|
|
|
|
|
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
// Restore diagram from ref if we have one
|
|
|
|
|
const xmlToRestore = chartXMLRef.current
|
|
|
|
|
if (isRealDiagram(xmlToRestore) && drawioRef.current) {
|
|
|
|
|
drawioRef.current.load({ xml: xmlToRestore })
|
2025-12-18 20:14:10 +08:00
|
|
|
}
|
|
|
|
|
}, [isDrawioReady])
|
|
|
|
|
|
2025-12-04 22:56:59 +09:00
|
|
|
// Track if we're expecting an export for file save (stores raw export data)
|
|
|
|
|
const saveResolverRef = useRef<{
|
2025-12-06 12:46:40 +09:00
|
|
|
resolver: ((data: string) => void) | null
|
|
|
|
|
format: ExportFormat | null
|
|
|
|
|
}>({ resolver: null, format: null })
|
2025-03-26 00:30:00 +00:00
|
|
|
|
|
|
|
|
const handleExport = () => {
|
|
|
|
|
if (drawioRef.current) {
|
2025-12-03 13:53:16 +09:00
|
|
|
// Mark that this export should be saved to history
|
2025-12-06 12:46:40 +09:00
|
|
|
expectHistoryExportRef.current = true
|
2025-03-26 00:30:00 +00:00
|
|
|
drawioRef.current.exportDiagram({
|
|
|
|
|
format: "xmlsvg",
|
2025-12-06 12:46:40 +09:00
|
|
|
})
|
2025-03-26 00:30:00 +00:00
|
|
|
}
|
2025-12-06 12:46:40 +09:00
|
|
|
}
|
2025-03-26 00:30:00 +00:00
|
|
|
|
2025-12-03 21:58:48 +09:00
|
|
|
const handleExportWithoutHistory = () => {
|
|
|
|
|
if (drawioRef.current) {
|
|
|
|
|
// Export without saving to history (for edit_diagram fetching current state)
|
|
|
|
|
drawioRef.current.exportDiagram({
|
|
|
|
|
format: "xmlsvg",
|
2025-12-06 12:46:40 +09:00
|
|
|
})
|
2025-12-03 21:58:48 +09:00
|
|
|
}
|
2025-12-06 12:46:40 +09:00
|
|
|
}
|
2025-12-03 21:58:48 +09:00
|
|
|
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
// Get current diagram as SVG for thumbnail (used by session storage)
|
|
|
|
|
const getThumbnailSvg = async (): Promise<string | null> => {
|
|
|
|
|
if (!drawioRef.current) return null
|
|
|
|
|
// Don't export if diagram is empty
|
|
|
|
|
if (!isRealDiagram(chartXML)) return null
|
2025-12-15 19:10:21 +05:30
|
|
|
|
|
|
|
|
try {
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
const svgData = await Promise.race([
|
2025-12-15 19:10:21 +05:30
|
|
|
new Promise<string>((resolve) => {
|
|
|
|
|
resolverRef.current = resolve
|
|
|
|
|
drawioRef.current?.exportDiagram({ format: "xmlsvg" })
|
|
|
|
|
}),
|
|
|
|
|
new Promise<string>((_, reject) =>
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
setTimeout(() => reject(new Error("Export timeout")), 3000),
|
2025-12-15 19:10:21 +05:30
|
|
|
),
|
|
|
|
|
])
|
|
|
|
|
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
// Update latestSvg so it's available for future saves
|
|
|
|
|
if (svgData?.includes("<svg")) {
|
|
|
|
|
setLatestSvg(svgData)
|
|
|
|
|
return svgData
|
2025-12-15 19:10:21 +05:30
|
|
|
}
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
return null
|
|
|
|
|
} catch {
|
|
|
|
|
// Timeout is expected occasionally - don't log as error
|
|
|
|
|
return null
|
2025-12-15 19:10:21 +05:30
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-07 14:38:15 +09:00
|
|
|
const loadDiagram = (
|
|
|
|
|
chart: string,
|
|
|
|
|
skipValidation?: boolean,
|
|
|
|
|
): string | null => {
|
2025-12-13 15:00:28 +09:00
|
|
|
let xmlToLoad = chart
|
|
|
|
|
|
2025-12-07 14:38:15 +09:00
|
|
|
// Validate XML structure before loading (unless skipped for internal use)
|
|
|
|
|
if (!skipValidation) {
|
2025-12-13 15:00:28 +09:00
|
|
|
const validation = validateAndFixXml(chart)
|
|
|
|
|
if (!validation.valid) {
|
|
|
|
|
console.warn(
|
|
|
|
|
"[loadDiagram] Validation error:",
|
|
|
|
|
validation.error,
|
|
|
|
|
)
|
|
|
|
|
return validation.error
|
|
|
|
|
}
|
|
|
|
|
// Use fixed XML if auto-fix was applied
|
|
|
|
|
if (validation.fixed) {
|
|
|
|
|
console.log(
|
|
|
|
|
"[loadDiagram] Auto-fixed XML issues:",
|
|
|
|
|
validation.fixes,
|
|
|
|
|
)
|
|
|
|
|
xmlToLoad = validation.fixed
|
2025-12-07 14:38:15 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-07 01:39:09 +09:00
|
|
|
// Keep chartXML in sync even when diagrams are injected (e.g., display_diagram tool)
|
2025-12-13 15:00:28 +09:00
|
|
|
setChartXML(xmlToLoad)
|
2025-12-07 01:39:09 +09:00
|
|
|
|
2025-03-26 00:30:00 +00:00
|
|
|
if (drawioRef.current) {
|
|
|
|
|
drawioRef.current.load({
|
2025-12-13 15:00:28 +09:00
|
|
|
xml: xmlToLoad,
|
2025-12-06 12:46:40 +09:00
|
|
|
})
|
2025-03-26 00:30:00 +00:00
|
|
|
}
|
2025-12-07 14:38:15 +09:00
|
|
|
|
|
|
|
|
return null
|
2025-12-06 12:46:40 +09:00
|
|
|
}
|
2025-03-26 00:30:00 +00:00
|
|
|
|
|
|
|
|
const handleDiagramExport = (data: any) => {
|
2025-12-04 22:56:59 +09:00
|
|
|
// Handle save to file if requested (process raw data before extraction)
|
|
|
|
|
if (saveResolverRef.current.resolver) {
|
2025-12-06 12:46:40 +09:00
|
|
|
const format = saveResolverRef.current.format
|
|
|
|
|
saveResolverRef.current.resolver(data.data)
|
|
|
|
|
saveResolverRef.current = { resolver: null, format: null }
|
2025-12-04 22:56:59 +09:00
|
|
|
// For non-xmlsvg formats, skip XML extraction as it will fail
|
|
|
|
|
// Only drawio (which uses xmlsvg internally) has the content attribute
|
|
|
|
|
if (format === "png" || format === "svg") {
|
2025-12-06 12:46:40 +09:00
|
|
|
return
|
2025-12-04 22:56:59 +09:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-06 12:46:40 +09:00
|
|
|
const extractedXML = extractDiagramXML(data.data)
|
|
|
|
|
setChartXML(extractedXML)
|
|
|
|
|
setLatestSvg(data.data)
|
2025-12-03 13:53:16 +09:00
|
|
|
|
|
|
|
|
// Only add to history if this was a user-initiated export
|
2025-12-14 21:23:14 +09:00
|
|
|
// Limit to 20 entries to prevent memory leaks during long sessions
|
|
|
|
|
const MAX_HISTORY_SIZE = 20
|
2025-12-03 13:53:16 +09:00
|
|
|
if (expectHistoryExportRef.current) {
|
2025-12-14 21:23:14 +09:00
|
|
|
setDiagramHistory((prev) => {
|
|
|
|
|
const newHistory = [
|
|
|
|
|
...prev,
|
|
|
|
|
{
|
|
|
|
|
svg: data.data,
|
|
|
|
|
xml: extractedXML,
|
|
|
|
|
},
|
|
|
|
|
]
|
|
|
|
|
// Keep only the last MAX_HISTORY_SIZE entries (circular buffer)
|
|
|
|
|
return newHistory.slice(-MAX_HISTORY_SIZE)
|
|
|
|
|
})
|
2025-12-06 12:46:40 +09:00
|
|
|
expectHistoryExportRef.current = false
|
2025-12-03 13:53:16 +09:00
|
|
|
}
|
|
|
|
|
|
2025-03-26 00:30:00 +00:00
|
|
|
if (resolverRef.current) {
|
2025-12-06 12:46:40 +09:00
|
|
|
resolverRef.current(extractedXML)
|
|
|
|
|
resolverRef.current = null
|
2025-03-26 00:30:00 +00:00
|
|
|
}
|
2025-12-06 12:46:40 +09:00
|
|
|
}
|
2025-03-26 00:30:00 +00:00
|
|
|
|
2025-03-27 08:09:22 +00:00
|
|
|
const clearDiagram = () => {
|
2025-12-06 12:46:40 +09:00
|
|
|
const emptyDiagram = `<mxfile><diagram name="Page-1" id="page-1"><mxGraphModel><root><mxCell id="0"/><mxCell id="1" parent="0"/></root></mxGraphModel></diagram></mxfile>`
|
2025-12-07 14:38:15 +09:00
|
|
|
// Skip validation for trusted internal template (loadDiagram also sets chartXML)
|
|
|
|
|
loadDiagram(emptyDiagram, true)
|
2025-12-06 12:46:40 +09:00
|
|
|
setLatestSvg("")
|
|
|
|
|
setDiagramHistory([])
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const saveDiagramToFile = (
|
|
|
|
|
filename: string,
|
|
|
|
|
format: ExportFormat,
|
|
|
|
|
sessionId?: string,
|
2026-01-04 09:41:32 +05:30
|
|
|
successMessage?: string,
|
2025-12-06 12:46:40 +09:00
|
|
|
) => {
|
2025-12-03 21:02:26 +09:00
|
|
|
if (!drawioRef.current) {
|
2025-12-06 12:46:40 +09:00
|
|
|
console.warn("Draw.io editor not ready")
|
|
|
|
|
return
|
2025-12-03 21:02:26 +09:00
|
|
|
}
|
|
|
|
|
|
2025-12-04 22:56:59 +09:00
|
|
|
// Map format to draw.io export format
|
2025-12-06 12:46:40 +09:00
|
|
|
const drawioFormat = format === "drawio" ? "xmlsvg" : format
|
2025-12-04 22:56:59 +09:00
|
|
|
|
|
|
|
|
// Set up the resolver before triggering export
|
|
|
|
|
saveResolverRef.current = {
|
|
|
|
|
resolver: (exportData: string) => {
|
2025-12-06 12:46:40 +09:00
|
|
|
let fileContent: string | Blob
|
|
|
|
|
let mimeType: string
|
|
|
|
|
let extension: string
|
2025-12-04 22:56:59 +09:00
|
|
|
|
|
|
|
|
if (format === "drawio") {
|
|
|
|
|
// Extract XML from SVG for .drawio format
|
2025-12-06 12:46:40 +09:00
|
|
|
const xml = extractDiagramXML(exportData)
|
|
|
|
|
let xmlContent = xml
|
2025-12-04 22:56:59 +09:00
|
|
|
if (!xml.includes("<mxfile")) {
|
2025-12-06 12:46:40 +09:00
|
|
|
xmlContent = `<mxfile><diagram name="Page-1" id="page-1">${xml}</diagram></mxfile>`
|
2025-12-04 22:56:59 +09:00
|
|
|
}
|
2025-12-06 12:46:40 +09:00
|
|
|
fileContent = xmlContent
|
|
|
|
|
mimeType = "application/xml"
|
|
|
|
|
extension = ".drawio"
|
2025-12-04 22:56:59 +09:00
|
|
|
} else if (format === "png") {
|
|
|
|
|
// PNG data comes as base64 data URL
|
2025-12-06 12:46:40 +09:00
|
|
|
fileContent = exportData
|
|
|
|
|
mimeType = "image/png"
|
|
|
|
|
extension = ".png"
|
2025-12-04 22:56:59 +09:00
|
|
|
} else {
|
|
|
|
|
// SVG format
|
2025-12-06 12:46:40 +09:00
|
|
|
fileContent = exportData
|
|
|
|
|
mimeType = "image/svg+xml"
|
|
|
|
|
extension = ".svg"
|
2025-12-04 22:56:59 +09:00
|
|
|
}
|
|
|
|
|
|
2025-12-05 21:15:02 +09:00
|
|
|
// Log save event to Langfuse (flags the trace)
|
2025-12-06 12:46:40 +09:00
|
|
|
logSaveToLangfuse(filename, format, sessionId)
|
2025-12-05 21:15:02 +09:00
|
|
|
|
2025-12-04 22:56:59 +09:00
|
|
|
// Handle download
|
2025-12-06 12:46:40 +09:00
|
|
|
let url: string
|
|
|
|
|
if (
|
|
|
|
|
typeof fileContent === "string" &&
|
|
|
|
|
fileContent.startsWith("data:")
|
|
|
|
|
) {
|
2025-12-04 22:56:59 +09:00
|
|
|
// Already a data URL (PNG)
|
2025-12-06 12:46:40 +09:00
|
|
|
url = fileContent
|
2025-12-04 22:56:59 +09:00
|
|
|
} else {
|
2025-12-06 12:46:40 +09:00
|
|
|
const blob = new Blob([fileContent], { type: mimeType })
|
|
|
|
|
url = URL.createObjectURL(blob)
|
2025-12-04 22:56:59 +09:00
|
|
|
}
|
|
|
|
|
|
2025-12-06 12:46:40 +09:00
|
|
|
const a = document.createElement("a")
|
|
|
|
|
a.href = url
|
|
|
|
|
a.download = `${filename}${extension}`
|
|
|
|
|
document.body.appendChild(a)
|
|
|
|
|
a.click()
|
|
|
|
|
document.body.removeChild(a)
|
2025-12-04 22:56:59 +09:00
|
|
|
|
2026-01-04 09:41:32 +05:30
|
|
|
// Show success toast after download is initiated
|
|
|
|
|
if (successMessage) {
|
|
|
|
|
toast.success(successMessage, {
|
|
|
|
|
position: "bottom-left",
|
|
|
|
|
duration: 2500,
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
|
2025-12-04 22:56:59 +09:00
|
|
|
// Delay URL revocation to ensure download completes
|
|
|
|
|
if (!url.startsWith("data:")) {
|
2025-12-06 12:46:40 +09:00
|
|
|
setTimeout(() => URL.revokeObjectURL(url), 100)
|
2025-12-04 22:56:59 +09:00
|
|
|
}
|
|
|
|
|
},
|
|
|
|
|
format,
|
2025-12-06 12:46:40 +09:00
|
|
|
}
|
2025-12-04 22:56:59 +09:00
|
|
|
|
|
|
|
|
// Export diagram - callback will be handled in handleDiagramExport
|
2025-12-06 12:46:40 +09:00
|
|
|
drawioRef.current.exportDiagram({ format: drawioFormat })
|
|
|
|
|
}
|
2025-12-04 22:56:59 +09:00
|
|
|
|
2025-12-05 21:15:02 +09:00
|
|
|
// Log save event to Langfuse (just flags the trace, doesn't send content)
|
2025-12-06 12:46:40 +09:00
|
|
|
const logSaveToLangfuse = async (
|
|
|
|
|
filename: string,
|
|
|
|
|
format: string,
|
|
|
|
|
sessionId?: string,
|
|
|
|
|
) => {
|
2025-12-05 21:15:02 +09:00
|
|
|
try {
|
2025-12-22 19:58:55 +05:30
|
|
|
await fetch(getApiEndpoint("/api/log-save"), {
|
2025-12-05 21:15:02 +09:00
|
|
|
method: "POST",
|
|
|
|
|
headers: { "Content-Type": "application/json" },
|
|
|
|
|
body: JSON.stringify({ filename, format, sessionId }),
|
2025-12-06 12:46:40 +09:00
|
|
|
})
|
2025-12-05 21:15:02 +09:00
|
|
|
} catch (error) {
|
2025-12-06 12:46:40 +09:00
|
|
|
console.warn("Failed to log save to Langfuse:", error)
|
2025-12-05 21:15:02 +09:00
|
|
|
}
|
2025-12-06 12:46:40 +09:00
|
|
|
}
|
2025-12-05 21:15:02 +09:00
|
|
|
|
2025-03-26 00:30:00 +00:00
|
|
|
return (
|
|
|
|
|
<DiagramContext.Provider
|
|
|
|
|
value={{
|
|
|
|
|
chartXML,
|
|
|
|
|
latestSvg,
|
|
|
|
|
diagramHistory,
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
setDiagramHistory,
|
2025-03-26 00:30:00 +00:00
|
|
|
loadDiagram,
|
|
|
|
|
handleExport,
|
2025-12-03 21:58:48 +09:00
|
|
|
handleExportWithoutHistory,
|
2025-03-26 00:30:00 +00:00
|
|
|
resolverRef,
|
|
|
|
|
drawioRef,
|
|
|
|
|
handleDiagramExport,
|
2025-03-27 08:09:22 +00:00
|
|
|
clearDiagram,
|
2025-12-03 21:02:26 +09:00
|
|
|
saveDiagramToFile,
|
feat: add chat session history with IndexedDB persistence (#500)
* feat(session): add chat session history with IndexedDB storage
- Add session-storage.ts with IndexedDB wrapper using idb library
- Add use-session-manager.ts hook for session state management
- Add session-history-dropdown.tsx for session selection UI
- Integrate session system into chat-panel.tsx
- Auto-generate session titles from first user message
- Auto-save sessions on message completion
- Support session switching, deletion, and creation
- Migrate existing localStorage data to IndexedDB
- Add i18n translations for session history UI
* feat(session): improve history dropdown and persist diagram history
- Add time-based grouping (Today, Yesterday, This Week, Earlier)
- Add thumbnail previews using Next.js Image component
- Add staggered entrance animations with fade-in effects
- Improve active session indicator with left border accent
- Fix scrolling by using native overflow instead of ScrollArea
- Persist diagram version history to IndexedDB sessions
- Remove redundant diagram XML from localStorage
- Add i18n strings for time group labels (en, ja, zh)
* fix(session): prevent data loss on theme change and tab close
- Add isDrawioReady effect to restore diagram after DrawIO remount
- Add visibilitychange handler to save session when page becomes hidden
- Fix missing currentSessionId in saveCurrentSession dependency array
- Remove unused sanitizeMessages import from use-session-manager
* fix(session): fix diagram save and migration data loss bugs
- Add diagramHistory to save effect dependency array so diagram-only
edits trigger saves (previously only message changes did)
- Destructure stable sessionManager values to prevent unnecessary
effect re-runs on every render
- Add try-catch wrapper around debounced async save operation
- Make saveSession() return boolean to indicate success/failure
- Verify IndexedDB write succeeded before deleting localStorage data
during migration (prevents data loss if write silently fails)
- Keep localStorage data for retry if migration fails instead of
marking as complete anyway
* refactor(session): extract helpers to reduce code duplication
- Add syncUIWithSession helper to consolidate 4 duplicate UI sync blocks
- Add buildSessionData helper to consolidate 4 duplicate save logic blocks
- Remove unused saveTimeoutRef and its cleanup effect
- Net reduction of ~80 lines of duplicate code
* style(ui): improve history dropdown and delete dialog styling
- Change destructive color from coral to muted rose for refined look
- Make session history panel taller (400px fixed height)
- Fix popover alignment to prevent truncation
- Style delete button with soft red outline instead of solid fill
- Make delete dialog more compact (max-w-sm)
* fix(session): reset refs on new chat and show recent sessions
- Fix cached example diagrams not displaying after creating new session
- Reset previousXML, lastProcessedXmlRef and processedToolCalls when
messages become empty (new chat or session switch)
- Add recent chats section in empty chat state with collapsible examples
- Pass sessions and onSelectSession to ChatMessageDisplay
- Add loadedMessageIdsRef to skip animations on session restore
- Add debug console.log for diagram processing flow
* feat(session): add search bar and improve history UI
- Remove session history dropdown, use main panel instead
- Add search bar to filter history chats by title
- Show minutes (Xm ago) instead of "Just now" for recent sessions
- Scroll to top when switching to new/empty chat
- Remove title truncation limit for better searchability
- Remove debug console.log statements
* refactor: remove redundant code and fix nested button hydration error
- Remove unused 'sessions' from deleteSession dependency array
- Remove unused 'switchedTo' variable and simplify return type
- Remove unused 'restoredMessageIdsRef' (always empty)
- Fix nested button hydration error by using div with role=button
- Simplify handleDeleteSession callback
* fix(session): fix migration bug, improve metadata perf, truncate titles
- Fix migration retry loop when localStorage has empty array
- Use cursor-based iteration for getAllSessionMetadata
- Truncate session titles to 100 chars with ellipsis
* refactor: remove dead code and extract diagram length constant
- Remove unused exports: getAllSessions, createNewSession, updateSessionTitle
- Remove write-only CURRENT_SESSION_KEY and all localStorage calls
- Remove dead messagesEndRef and unused scroll effect
- Extract magic number 300 to MIN_REAL_DIAGRAM_LENGTH constant
- Add isRealDiagram() helper function for semantic clarity
2026-01-04 10:25:19 +09:00
|
|
|
getThumbnailSvg,
|
2025-12-07 01:39:09 +09:00
|
|
|
isDrawioReady,
|
|
|
|
|
onDrawioLoad,
|
2025-12-10 08:21:15 +08:00
|
|
|
resetDrawioReady,
|
2025-12-17 20:24:53 +09:00
|
|
|
showSaveDialog,
|
|
|
|
|
setShowSaveDialog,
|
2025-03-26 00:30:00 +00:00
|
|
|
}}
|
|
|
|
|
>
|
|
|
|
|
{children}
|
|
|
|
|
</DiagramContext.Provider>
|
2025-12-06 12:46:40 +09:00
|
|
|
)
|
2025-03-26 00:30:00 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export function useDiagram() {
|
2025-12-06 12:46:40 +09:00
|
|
|
const context = useContext(DiagramContext)
|
2025-03-26 00:30:00 +00:00
|
|
|
if (context === undefined) {
|
2025-12-06 12:46:40 +09:00
|
|
|
throw new Error("useDiagram must be used within a DiagramProvider")
|
2025-03-26 00:30:00 +00:00
|
|
|
}
|
2025-12-06 12:46:40 +09:00
|
|
|
return context
|
2025-03-26 00:30:00 +00:00
|
|
|
}
|