Spaces:
Sleeping
Sleeping
File size: 3,922 Bytes
01d5a5d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
import { useEffect, useRef, useState } from 'react';
interface TrainingLogProps {
trainingDetails: {
message: string;
timestamp: string;
}[];
}
const TrainingLog: React.FC<TrainingLogProps> = ({ trainingDetails }: TrainingLogProps) => {
const consoleEndRef = useRef<HTMLDivElement>(null);
const [isUserScrolling, setIsUserScrolling] = useState(false);
const userScrollTimeout = useRef<NodeJS.Timeout | null>(null);
const [isAutoScrollEnabled, setIsAutoScrollEnabled] = useState(true);
// Smooth scroll console to bottom
const smoothScrollConsole = () => {
if (consoleEndRef.current && !isUserScrolling) {
const consoleContainer = consoleEndRef.current;
if (consoleContainer instanceof HTMLElement) {
consoleContainer.scrollTo({
top: consoleContainer.scrollHeight,
behavior: 'smooth'
});
}
}
};
useEffect(() => {
// Set up scroll event listener to detect user scrolling
const handleUserScroll = () => {
if (!consoleEndRef.current) return;
const consoleContainer = consoleEndRef.current.closest('.overflow-y-auto');
if (!(consoleContainer instanceof HTMLElement)) return;
// Check if scrolled away from bottom
const isScrolledToBottom =
Math.abs((consoleContainer.scrollHeight - consoleContainer.scrollTop) - consoleContainer.clientHeight) < 50;
// If scrolled away from bottom, consider it manual scrolling
if (!isScrolledToBottom) {
setIsUserScrolling(true);
// Clear any existing timeout
if (userScrollTimeout.current) {
clearTimeout(userScrollTimeout.current);
}
// Reset the flag after a delay
userScrollTimeout.current = setTimeout(() => {
setIsUserScrolling(false);
}, 5000); // 5 seconds delay before allowing auto-scroll again
} else {
// If at bottom, not considered manual scrolling
setIsUserScrolling(false);
if (userScrollTimeout.current) {
clearTimeout(userScrollTimeout.current);
userScrollTimeout.current = null;
}
}
};
// Find the console container and attach the scroll listener
if (consoleEndRef.current) {
const consoleContainer = consoleEndRef.current;
if (consoleContainer instanceof HTMLElement) {
consoleContainer.addEventListener('scroll', handleUserScroll);
// Cleanup function
return () => {
consoleContainer.removeEventListener('scroll', handleUserScroll);
if (userScrollTimeout.current) {
clearTimeout(userScrollTimeout.current);
}
};
}
}
}, []);
useEffect(() => {
if (trainingDetails.length > 0) {
smoothScrollConsole();
}
}, [trainingDetails, isAutoScrollEnabled]);
const toggleAutoScroll = () => {
setIsAutoScrollEnabled(!isAutoScrollEnabled);
if (!isAutoScrollEnabled) {
// If we're re-enabling auto-scroll, scroll to bottom immediately
setIsUserScrolling(false);
setTimeout(smoothScrollConsole, 50);
}
};
return (
<div className="mt-4">
<h4 className="text-sm font-medium text-gray-700 mb-2">Training Log</h4>
<div
ref={consoleEndRef}
className="bg-gray-900 rounded-lg p-4 h-[600px] overflow-y-auto font-mono text-xs"
>
<div className="space-y-1">
{trainingDetails.length > 0 ? (
trainingDetails.map((detail, index) => (
<div key={detail.timestamp + detail.message + index} className="text-gray-300">
{detail.message}
</div>
))
) : (
<div className="text-gray-300">
No training logs available. Start training to see logs here.
</div>
)}
</div>
</div>
</div>
);
};
export default TrainingLog;
|