Skip to content

Commit b034962

Browse files
committed
updated debug pages
1 parent bd17947 commit b034962

8 files changed

Lines changed: 878 additions & 183 deletions

File tree

client/src/client/services/debugging/DebugStatistic.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,5 @@ export const DebugStatistic = {
1010
CACHED_STREAMS: { name: 'Cached Streams', fill: false, advancesItself: false },
1111
PRELOADED_SOUNDS: { name: 'Preloaded Sounds', fill: false, advancesItself: false },
1212
MEDIA_LOAD_TIME: { name: 'Media Load Time (MS)', fill: false, advancesItself: false },
13+
MEMORY_USAGE_MB: { name: 'Memory Usage (MB)', fill: true, advancesItself: true },
1314
};
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import React from 'react';
2+
import PropTypes from 'prop-types';
3+
4+
export default function CompactDebugPanel(props) {
5+
const { data, title, color } = props;
6+
7+
if (!data || data.length === 0) {
8+
return (
9+
<div className="bg-black bg-opacity-30 rounded-lg p-3 border border-gray-600 border-opacity-30">
10+
<div className="flex items-center space-x-2 mb-2">
11+
<div className="w-2 h-2 bg-gray-500 rounded-full" />
12+
<span className="text-white font-medium text-sm">{title}</span>
13+
</div>
14+
<p className="text-gray-400 text-xs">No data</p>
15+
</div>
16+
);
17+
}
18+
19+
const highest = Math.max(...data);
20+
const lowest = Math.min(...data);
21+
const average = data.reduce((a, b) => a + b, 0) / data.length;
22+
const latest = data[data.length - 1];
23+
24+
// Create mini sparkline
25+
const sparklinePoints = data.slice(-120); // Last 120 points (show more history)
26+
const sparklineMax = Math.max(...sparklinePoints);
27+
const sparklineMin = Math.min(...sparklinePoints);
28+
const sparklineRange = sparklineMax - sparklineMin || 1;
29+
30+
const sparklinePath = sparklinePoints.map((value, index) => {
31+
const x = (index / Math.max(sparklinePoints.length - 1, 1)) * 90 + 5; // Keep 5% margin on sides
32+
const y = 90 - ((value - sparklineMin) / sparklineRange) * 80 + 5; // Keep 5% margin on top/bottom
33+
return `${index === 0 ? 'M' : 'L'} ${x} ${y}`;
34+
}).join(' ');
35+
36+
return (
37+
<div className="bg-black bg-opacity-30 rounded-lg p-3 border border-gray-600 border-opacity-30">
38+
{/* Header */}
39+
<div className="flex items-center justify-between mb-2">
40+
<div className="flex items-center space-x-2">
41+
<div className="w-2 h-2 rounded-full" style={{ backgroundColor: color }} />
42+
<span className="text-white font-medium text-sm">{title}</span>
43+
</div>
44+
<span className="text-gray-300 font-mono text-xs">
45+
{typeof latest === 'number' ? latest.toFixed(2) : latest}
46+
</span>
47+
</div>
48+
49+
{/* Mini Sparkline */}
50+
<div className="mb-3 overflow-hidden">
51+
<svg
52+
width="100%"
53+
height="64"
54+
viewBox="0 0 100 100"
55+
className="block w-full h-16"
56+
preserveAspectRatio="none"
57+
>
58+
<path
59+
d={sparklinePath}
60+
fill="none"
61+
stroke={color}
62+
strokeWidth="2"
63+
vectorEffect="non-scaling-stroke"
64+
/>
65+
</svg>
66+
</div>
67+
68+
{/* Stats Grid */}
69+
<div className="grid grid-cols-2 gap-2 text-xs">
70+
<div className="flex justify-between">
71+
<span className="text-gray-400">Max:</span>
72+
<span className="text-white font-mono">
73+
{typeof highest === 'number' ? highest.toFixed(2) : highest}
74+
</span>
75+
</div>
76+
<div className="flex justify-between">
77+
<span className="text-gray-400">Min:</span>
78+
<span className="text-white font-mono">
79+
{typeof lowest === 'number' ? lowest.toFixed(2) : lowest}
80+
</span>
81+
</div>
82+
<div className="flex justify-between">
83+
<span className="text-gray-400">Avg:</span>
84+
<span className="text-white font-mono">
85+
{typeof average === 'number' ? average.toFixed(2) : average}
86+
</span>
87+
</div>
88+
<div className="flex justify-between">
89+
<span className="text-gray-400">Pts:</span>
90+
<span className="text-white font-mono">{data.length}</span>
91+
</div>
92+
</div>
93+
</div>
94+
);
95+
}
96+
97+
CompactDebugPanel.propTypes = {
98+
title: PropTypes.string.isRequired,
99+
data: PropTypes.array.isRequired,
100+
color: PropTypes.string,
101+
};
102+
103+
CompactDebugPanel.defaultProps = {
104+
color: '#3B82F6',
105+
};
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import React from 'react';
2+
3+
export default function CompactLogViewer({ log }) {
4+
if (!log || log.length === 0) {
5+
return (
6+
<div className="bg-black bg-opacity-30 rounded-lg p-4 border border-gray-600 border-opacity-30">
7+
<div className="flex items-center space-x-2 mb-3">
8+
<div className="w-2 h-2 bg-yellow-400 rounded-full" />
9+
<span className="text-white font-medium text-sm">System Logs</span>
10+
</div>
11+
<div className="text-center py-4">
12+
<span className="text-gray-400 text-xs italic">No log entries</span>
13+
</div>
14+
</div>
15+
);
16+
}
17+
18+
// Get recent logs (last 50)
19+
const recentLogs = log.slice(-50);
20+
21+
const getLogLevelColor = (level) => {
22+
switch (level?.toLowerCase()) {
23+
case 'error':
24+
return 'text-red-400 bg-red-500 bg-opacity-10 border-red-500 border-opacity-30';
25+
case 'warn':
26+
case 'warning':
27+
return 'text-yellow-400 bg-yellow-500 bg-opacity-10 border-yellow-500 border-opacity-30';
28+
case 'info':
29+
return 'text-blue-400 bg-blue-500 bg-opacity-10 border-blue-500 border-opacity-30';
30+
case 'debug':
31+
return 'text-gray-400 bg-gray-500 bg-opacity-10 border-gray-500 border-opacity-30';
32+
default:
33+
return 'text-gray-300 bg-gray-600 bg-opacity-10 border-gray-600 border-opacity-30';
34+
}
35+
};
36+
37+
const formatTimestamp = (timestamp) => {
38+
if (!timestamp) return '';
39+
const date = new Date(timestamp);
40+
return date.toLocaleTimeString('en-US', {
41+
hour12: false,
42+
hour: '2-digit',
43+
minute: '2-digit',
44+
second: '2-digit',
45+
});
46+
};
47+
48+
return (
49+
<div className="bg-black bg-opacity-30 rounded-lg border border-gray-600 border-opacity-30">
50+
<div className="flex items-center justify-between p-4 border-b border-gray-600 border-opacity-30">
51+
<div className="flex items-center space-x-2">
52+
<div className="w-2 h-2 bg-yellow-400 rounded-full" />
53+
<span className="text-white font-medium text-sm">System Logs</span>
54+
</div>
55+
<div className="flex items-center space-x-2 text-xs">
56+
<span className="text-gray-400">Entries:</span>
57+
<span className="text-white font-mono">{log.length}</span>
58+
<span className="text-gray-400">Showing:</span>
59+
<span className="text-yellow-300 font-mono">{Math.min(50, log.length)}</span>
60+
</div>
61+
</div>
62+
63+
<div className="max-h-64 overflow-y-auto">
64+
<div className="p-2 space-y-1">
65+
{recentLogs.map((entry, index) => (
66+
<div key={index} className="flex items-start space-x-2 py-1 px-2 rounded hover:bg-black hover:bg-opacity-20 transition-colors">
67+
<span className="text-gray-500 font-mono text-xs leading-5 min-w-[4rem]">
68+
{formatTimestamp(entry.timestamp)}
69+
</span>
70+
<span className={`px-1.5 py-0.5 rounded text-xs font-mono leading-4 border ${getLogLevelColor(entry.level)} min-w-[3rem] text-center`}>
71+
{(entry.level || 'LOG').toUpperCase().slice(0, 4)}
72+
</span>
73+
<span className="text-gray-300 text-xs leading-5 flex-1 break-words">
74+
{entry.message || entry.text || String(entry)}
75+
</span>
76+
</div>
77+
))}
78+
</div>
79+
</div>
80+
</div>
81+
);
82+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React from 'react';
2+
import { Radar } from '../graph/Radar';
3+
4+
export default function CompactSpatialPanel({ playerLocation, peers, speakers }) {
5+
return (
6+
<div className="bg-black bg-opacity-30 rounded-lg p-4 border border-gray-600 border-opacity-30">
7+
<div className="flex items-center justify-between mb-3">
8+
<div className="flex items-center space-x-2">
9+
<div className="w-2 h-2 bg-purple-400 rounded-full" />
10+
<span className="text-white font-medium text-sm">Spatial</span>
11+
</div>
12+
<div className="flex items-center space-x-2 text-xs">
13+
<span className="text-gray-400">Entities:</span>
14+
<span className="text-green-300 font-mono">{peers.length}</span>
15+
<span className="text-gray-400">Speakers:</span>
16+
<span className="text-blue-300 font-mono">{speakers.length}</span>
17+
</div>
18+
</div>
19+
20+
{/* Compact Radar */}
21+
<div className="mb-3" style={{ height: '120px' }}>
22+
<Radar
23+
player={playerLocation}
24+
entities={peers}
25+
speakers={speakers}
26+
/>
27+
</div>
28+
29+
{/* Compact Position Info */}
30+
<div className="grid grid-cols-2 gap-2 text-xs">
31+
<div className="space-y-1">
32+
<div className="flex justify-between">
33+
<span className="text-gray-400">X:</span>
34+
<span className="text-white font-mono">{playerLocation.x.toFixed(1)}</span>
35+
</div>
36+
<div className="flex justify-between">
37+
<span className="text-gray-400">Y:</span>
38+
<span className="text-white font-mono">{playerLocation.y.toFixed(1)}</span>
39+
</div>
40+
</div>
41+
<div className="space-y-1">
42+
<div className="flex justify-between">
43+
<span className="text-gray-400">Z:</span>
44+
<span className="text-white font-mono">{playerLocation.z.toFixed(1)}</span>
45+
</div>
46+
<div className="flex justify-between">
47+
<span className="text-gray-400">Yaw:</span>
48+
<span className="text-white font-mono">
49+
{playerLocation.yaw ? `${playerLocation.yaw.toFixed(0)}°` : '--'}
50+
</span>
51+
</div>
52+
</div>
53+
</div>
54+
55+
{peers.length === 0 && (
56+
<div className="mt-2 text-center">
57+
<span className="text-gray-400 text-xs italic">No peers in range</span>
58+
</div>
59+
)}
60+
</div>
61+
);
62+
}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from 'react';
2+
import { VERSION } from '../../build';
3+
import { getGlobalState } from '../../state/store';
4+
5+
export default function CompactSystemInfo() {
6+
const state = getGlobalState();
7+
8+
return (
9+
<div className="bg-black bg-opacity-30 rounded-lg p-4 border border-gray-600 border-opacity-30">
10+
<div className="grid grid-cols-2 gap-3 text-xs">
11+
<div className="space-y-2">
12+
<div className="flex justify-between">
13+
<span className="text-gray-400">Build:</span>
14+
<span className="text-blue-300 font-mono">{VERSION.build}</span>
15+
</div>
16+
<div className="flex justify-between">
17+
<span className="text-gray-400">Tag:</span>
18+
<span className="text-blue-300 font-mono">{VERSION.tag}</span>
19+
</div>
20+
<div className="flex justify-between">
21+
<span className="text-gray-400">Player:</span>
22+
<span className="text-green-300 font-medium truncate max-w-[8rem]">
23+
{state.currentUser?.userName || 'Unknown'}
24+
</span>
25+
</div>
26+
</div>
27+
<div className="space-y-2">
28+
<div className="flex justify-between">
29+
<span className="text-gray-400">Date:</span>
30+
<span className="text-blue-300 font-mono text-right">{VERSION.date}</span>
31+
</div>
32+
</div>
33+
</div>
34+
35+
<div className="mt-3 pt-3 border-t border-gray-600 border-opacity-30">
36+
<div className="text-xs text-gray-400">
37+
Toggle debug with
38+
{' '}
39+
<kbd className="px-1 py-0.5 bg-gray-700 rounded text-blue-300 font-mono text-xs">d</kbd>
40+
</div>
41+
</div>
42+
</div>
43+
);
44+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
3+
export default function CompactTransceiversPanel({ transceiverNames }) {
4+
return (
5+
<div className="bg-black bg-opacity-30 rounded-lg p-4 border border-gray-600 border-opacity-30">
6+
<div className="flex items-center justify-between mb-3">
7+
<div className="flex items-center space-x-2">
8+
<div className="w-2 h-2 bg-green-400 rounded-full" />
9+
<span className="text-white font-medium text-sm">Transceivers</span>
10+
</div>
11+
<span className="text-gray-300 font-mono text-xs">
12+
{transceiverNames.length}
13+
{' '}
14+
active
15+
</span>
16+
</div>
17+
18+
{transceiverNames.length > 0 ? (
19+
<div className="space-y-1 max-h-32 overflow-y-auto">
20+
{transceiverNames.map((name, index) => (
21+
<div key={`${name}-${index}`} className="flex items-center space-x-2 py-1">
22+
<div className="w-1.5 h-1.5 bg-green-400 rounded-full animate-pulse" />
23+
<span className="text-green-300 font-mono text-xs truncate flex-1">
24+
{name}
25+
</span>
26+
<div className="flex items-center space-x-1">
27+
<div className="w-1 h-3 bg-green-400 rounded" />
28+
<div className="w-1 h-2 bg-green-400 rounded opacity-75" />
29+
<div className="w-1 h-4 bg-green-400 rounded" />
30+
</div>
31+
</div>
32+
))}
33+
</div>
34+
) : (
35+
<div className="text-center py-2">
36+
<div className="inline-flex items-center space-x-2 text-gray-400 text-xs">
37+
<svg className="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
38+
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M18.364 5.636l-3.536 3.536m0 5.656l3.536 3.536M9.172 9.172L5.636 5.636m3.536 9.192L5.636 18.364M12 12h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z" />
39+
</svg>
40+
<span>No active transceivers</span>
41+
</div>
42+
</div>
43+
)}
44+
</div>
45+
);
46+
}

0 commit comments

Comments
 (0)