import { useEffect, useRef, useState } from 'react' import './LoadingChunks.css' export interface ChunkDebug { x: number // like -32 z: number // like -32 lines: string[] sidebarLines: string[] state: 'server-waiting' | 'order-queued' | 'client-waiting' | 'client-processing' | 'done-empty' | 'done' } interface ProcessedChunk extends ChunkDebug { relX: number relZ: number displayLines: string[] } const stateColors: Record = { 'server-waiting': 'gray', 'order-queued': 'darkorange', 'client-waiting': 'yellow', 'client-processing': 'yellow', 'done-empty': 'darkgreen', 'done': 'limegreen', } export default ({ chunks, playerChunk, maxDistance, tileSize = 16, fontSize = 5, }: { chunks: ChunkDebug[] playerChunk: { x: number, z: number } maxDistance: number, tileSize?: number fontSize?: number }) => { const [selectedChunk, setSelectedChunk] = useState(null) const [showSidebar, setShowSidebar] = useState(false) // Calculate grid dimensions based on maxDistance const gridSize = maxDistance * 2 + 1 const centerIndex = maxDistance // Process chunks to get only the last one for each position and within maxDistance const processedChunks = chunks.reduce>((acc, chunk) => { const relX = Math.floor((chunk.x - playerChunk.x) / 16) const relZ = Math.floor((chunk.z - playerChunk.z) / 16) // Skip chunks outside maxDistance if (Math.abs(relX) > maxDistance || Math.abs(relZ) > maxDistance) return acc const key = `${chunk.x},${chunk.z}` acc[key] = { ...chunk, relX, relZ, displayLines: [`${relX},${relZ} (${chunk.x},${chunk.z})`, ...chunk.lines] } return acc }, {}) return (
{Array.from({ length: gridSize * gridSize }).map((_, i) => { const relX = -maxDistance + (i % gridSize) const relZ = -maxDistance + Math.floor(i / gridSize) const x = playerChunk.x + relX * 16 const z = playerChunk.z + relZ * 16 const chunk = processedChunks[`${x},${z}`] return (
{ if (chunk) { setSelectedChunk(chunk) setShowSidebar(true) } }} style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', background: chunk ? stateColors[chunk.state] : 'black', color: 'white', fontSize: `${fontSize}px`, cursor: chunk ? 'pointer' : 'default', position: 'relative', width: `${tileSize}px`, height: `${tileSize}px`, // pre-wrap whiteSpace: 'pre', }} > {relX}, {relZ}{'\n'} {chunk?.lines.join('\n')}
) })}
{showSidebar && selectedChunk && (
{selectedChunk.displayLines.map((line, i) => (
{line}
))}
Sidebar Info:
{selectedChunk.sidebarLines.map((line, i) => (
{line}
))}
)}
) }