fix(diagram): fix autosave staleness and XML repair corrupting valid diagrams

- Autosave guard reads refs, so edits after a theme or dark mode switch are kept
- Duplicate-id check and rename run per page; repair loop no longer quadratic
- autoFixXml no longer breaks style values, rich text " or single-line cells
- extractCompleteMxCells keeps the cell after a self-closing cell
- Better truncation detection; object/UserObject wrapped cells are editable
- Exports for thumbnail, PNG and save are routed by tag instead of a shared resolver
- History stores the full document; storage errors are reported, no auto-deletion of chats
- IndexedDB connection reopens after errors; focus refresh throttled
- Keep ?session= on locale redirect, map zh-Hant to zh-tw for draw.io
This commit is contained in:
dayuan.jiang
2026-10-03 17:45:41 +09:00
parent 79b4c52741
commit 5c7613ea09
10 changed files with 602 additions and 315 deletions
+12 -17
View File
@@ -37,7 +37,6 @@ export default function Home() {
)
const chatPanelRef = useRef<ImperativePanelHandle>(null)
const isMobileRef = useRef(false)
// Load preferences from localStorage after mount
useEffect(() => {
@@ -48,7 +47,9 @@ export default function Home() {
const currentLocale = pathParts[0]
if (currentLocale !== savedLocale) {
pathParts[0] = savedLocale
router.replace(`/${pathParts.join("/")}`)
// Keep the query (e.g. ?session=) and hash
const { search, hash } = window.location
router.replace(`/${pathParts.join("/")}${search}${hash}`)
return // Wait for redirect
}
}
@@ -106,27 +107,17 @@ export default function Home() {
resetDrawioReady()
}
// Check mobile - reset draw.io before crossing breakpoint
const isInitialRenderRef = useRef(true)
// Check mobile. The draw.io iframe is not remounted when crossing the
// breakpoint (only the chat panel is), so its ready state stays as is.
useEffect(() => {
const checkMobile = () => {
const newIsMobile = window.innerWidth < 768
if (
!isInitialRenderRef.current &&
newIsMobile !== isMobileRef.current
) {
setIsDrawioReady(false)
resetDrawioReady()
}
isMobileRef.current = newIsMobile
isInitialRenderRef.current = false
setIsMobile(newIsMobile)
setIsMobile(window.innerWidth < 768)
}
checkMobile()
window.addEventListener("resize", checkMobile)
return () => window.removeEventListener("resize", checkMobile)
}, [resetDrawioReady])
}, [])
const toggleChatPanel = () => {
const panel = chatPanelRef.current
@@ -193,7 +184,11 @@ export default function Home() {
noExitBtn: true,
dark:
darkMode || drawioUi === "dark",
lang: currentLang,
// draw.io names Traditional Chinese "zh-tw"
lang:
currentLang === "zh-Hant"
? "zh-tw"
: currentLang,
// Enable offline mode in Electron to disable external service calls
...(isElectron && {
offline: true,