frontend: refactor of the new build viewer

This commit is contained in:
2026-02-28 13:18:02 +01:00
parent 3e9a8295b2
commit 20ccb20738
6 changed files with 581 additions and 372 deletions

View File

@@ -12,10 +12,13 @@ const emit = defineEmits<{
parentReady: []
}>()
const { data: items, pending: itemsLoading } = useFetch<Array<{ id: number; iconPath: string }>>('/api/cdragon/items', {
lazy: true, // Don't block rendering
server: false // Client-side only
})
const { data: items, pending: itemsLoading } = useFetch<Array<{ id: number; iconPath: string }>>(
'/api/cdragon/items',
{
lazy: true, // Don't block rendering
server: false // Client-side only
}
)
// Track image loading state
const imagesLoaded = ref(false)
@@ -47,31 +50,39 @@ const pendingChildMounts: Array<Element> = []
// Function to wait for an image to load
function waitForImageLoad(imgElement: HTMLImageElement): Promise<void> {
return new Promise((resolve) => {
return new Promise(resolve => {
if (imgElement.complete) {
requestAnimationFrame(() => resolve())
return
}
imgElement.addEventListener('load', () => {
requestAnimationFrame(() => resolve())
}, { once: true })
imgElement.addEventListener('error', () => {
requestAnimationFrame(() => resolve())
}, { once: true })
imgElement.addEventListener(
'load',
() => {
requestAnimationFrame(() => resolve())
},
{ once: true }
)
imgElement.addEventListener(
'error',
() => {
requestAnimationFrame(() => resolve())
},
{ once: true }
)
})
}
onMounted(async () => {
// Wait for next tick to ensure DOM is ready
await nextTick()
// Wait for items to be loaded
await new Promise<void>((resolve) => {
await new Promise<void>(resolve => {
if (!itemsLoading.value) {
resolve()
} else {
const unwatch = watch(itemsLoading, (loading) => {
const unwatch = watch(itemsLoading, loading => {
if (!loading) {
unwatch()
resolve()
@@ -79,20 +90,20 @@ onMounted(async () => {
})
}
})
if (start.value) {
const imgElement = start.value as HTMLImageElement
imageElement.value = imgElement
// Wait for own image to load
await waitForImageLoad(imgElement)
// Now that image is loaded and DOM is ready, draw arrows
imagesLoaded.value = true
// Notify children that parent is ready
emit('parentReady')
// Draw any pending arrows from children that mounted before we were ready
if (pendingChildMounts.length > 0) {
await nextTick()
@@ -101,7 +112,7 @@ onMounted(async () => {
}
pendingChildMounts.length = 0
}
// Use multiple requestAnimationFrame to ensure rendering is complete
requestAnimationFrame(() => {
requestAnimationFrame(() => {
@@ -121,7 +132,7 @@ onBeforeUpdate(() => {
onUpdated(async () => {
await nextTick()
if (start.value && imagesLoaded.value) {
// Redraw arrows after DOM update
requestAnimationFrame(() => {
@@ -291,4 +302,4 @@ function handleRefresh() {
margin-left: 20px;
}
}
</style>
</style>