fix: hide Draw.io loading flash with placeholder (#481)

* fix: hide Draw.io loading flash with placeholder

* style: auto-format with Biome

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
This commit is contained in:
Dayuan Jiang
2026-01-01 15:20:00 +09:00
committed by GitHub
parent 493ee168b1
commit 77a2f6f6fa
2 changed files with 39 additions and 23 deletions

View File

@@ -35,6 +35,7 @@ export default function Home() {
const [drawioUi, setDrawioUi] = useState<"min" | "sketch">("min") const [drawioUi, setDrawioUi] = useState<"min" | "sketch">("min")
const [darkMode, setDarkMode] = useState(false) const [darkMode, setDarkMode] = useState(false)
const [isLoaded, setIsLoaded] = useState(false) const [isLoaded, setIsLoaded] = useState(false)
const [isDrawioReady, setIsDrawioReady] = useState(false)
const [closeProtection, setCloseProtection] = useState(false) const [closeProtection, setCloseProtection] = useState(false)
const chatPanelRef = useRef<ImperativePanelHandle>(null) const chatPanelRef = useRef<ImperativePanelHandle>(null)
@@ -104,12 +105,18 @@ export default function Home() {
setIsLoaded(true) setIsLoaded(true)
}, [pathname, router]) }, [pathname, router])
const handleDrawioLoad = useCallback(() => {
setIsDrawioReady(true)
onDrawioLoad()
}, [onDrawioLoad])
const handleDarkModeChange = async () => { const handleDarkModeChange = async () => {
await saveDiagramToStorage() await saveDiagramToStorage()
const newValue = !darkMode const newValue = !darkMode
setDarkMode(newValue) setDarkMode(newValue)
localStorage.setItem("next-ai-draw-io-dark-mode", String(newValue)) localStorage.setItem("next-ai-draw-io-dark-mode", String(newValue))
document.documentElement.classList.toggle("dark", newValue) document.documentElement.classList.toggle("dark", newValue)
setIsDrawioReady(false)
resetDrawioReady() resetDrawioReady()
} }
@@ -118,6 +125,7 @@ export default function Home() {
const newUi = drawioUi === "min" ? "sketch" : "min" const newUi = drawioUi === "min" ? "sketch" : "min"
localStorage.setItem("drawio-theme", newUi) localStorage.setItem("drawio-theme", newUi)
setDrawioUi(newUi) setDrawioUi(newUi)
setIsDrawioReady(false)
resetDrawioReady() resetDrawioReady()
} }
@@ -131,6 +139,7 @@ export default function Home() {
newIsMobile !== isMobileRef.current newIsMobile !== isMobileRef.current
) { ) {
saveDiagramToStorage().catch(() => {}) saveDiagramToStorage().catch(() => {})
setIsDrawioReady(false)
resetDrawioReady() resetDrawioReady()
} }
isMobileRef.current = newIsMobile isMobileRef.current = newIsMobile
@@ -206,28 +215,35 @@ export default function Home() {
mouseOverDrawioRef.current = false mouseOverDrawioRef.current = false
}} }}
> >
<div className="h-full rounded-xl overflow-hidden shadow-soft-lg border border-border/30"> <div className="h-full rounded-xl overflow-hidden shadow-soft-lg border border-border/30 relative">
{isLoaded ? ( {isLoaded && (
<DrawIoEmbed <div
key={`${drawioUi}-${darkMode}-${currentLang}`} className={`h-full w-full ${isDrawioReady ? "" : "invisible absolute inset-0"}`}
ref={drawioRef} >
onExport={handleDiagramExport} <DrawIoEmbed
onLoad={onDrawioLoad} key={`${drawioUi}-${darkMode}-${currentLang}`}
onSave={handleDrawioSave} ref={drawioRef}
baseUrl={drawioBaseUrl} onExport={handleDiagramExport}
urlParameters={{ onLoad={handleDrawioLoad}
ui: drawioUi, onSave={handleDrawioSave}
spin: true, baseUrl={drawioBaseUrl}
libraries: false, urlParameters={{
saveAndExit: false, ui: drawioUi,
noExitBtn: true, spin: false,
dark: darkMode, libraries: false,
lang: currentLang, saveAndExit: false,
}} noExitBtn: true,
/> dark: darkMode,
) : ( lang: currentLang,
<div className="h-full w-full flex items-center justify-center bg-background"> }}
<div className="animate-spin h-8 w-8 border-4 border-primary border-t-transparent rounded-full" /> />
</div>
)}
{(!isLoaded || !isDrawioReady) && (
<div className="h-full w-full bg-background flex items-center justify-center">
<span className="text-muted-foreground">
Draw.io panel is loading...
</span>
</div> </div>
)} )}
</div> </div>

View File

@@ -32,7 +32,7 @@ const DRAWIO_ORIGIN = getOrigin(DRAWIO_BASE_URL)
// Normalize URL for iframe src - ensure no double slashes // Normalize URL for iframe src - ensure no double slashes
function normalizeUrl(url: string): string { function normalizeUrl(url: string): string {
// Remove trailing slash to avoid double slashes // Remove trailing slash to avoid double slashes
return url.replace(/\/$/, '') return url.replace(/\/$/, "")
} }
interface SessionState { interface SessionState {