Skip to content

Instantly share code, notes, and snippets.

@yosephbernandus
Created September 26, 2024 13:41
Show Gist options
  • Select an option

  • Save yosephbernandus/8cc1b5b19bebf1875d48773316f94313 to your computer and use it in GitHub Desktop.

Select an option

Save yosephbernandus/8cc1b5b19bebf1875d48773316f94313 to your computer and use it in GitHub Desktop.
Test Convert
import React, { useEffect, useState, useRef } from 'react';
import './style.css'; // Assuming your CSS is in the same directory
function ProgressBar() {
const [progressLabel, setProgressLabel] = useState("Loading...");
const [progressPercentage, setProgressPercentage] = useState(0);
const [progress, setProgress] = useState(0);
const [kneItems, setKneItems] = useState(Array(25).fill(false));
const progressBarRef = useRef(null);
const progressContainerRef = useRef(null);
const intervalRef = useRef(null);
useEffect(() => {
const handleMessage = (event) => {
if (event.data.action === 'progress') {
updateProgress(event.data);
} else if (event.data.action === 'cancel') {
cancelProgress();
}
};
window.addEventListener('message', handleMessage);
return () => {
window.removeEventListener('message', handleMessage);
};
}, []);
const updateProgress = (data) => {
progressContainerRef.current.style.transition = 'opacity 0.3s ease-in';
progressContainerRef.current.style.opacity = '100';
setProgressLabel(data.label);
progressContainerRef.current.style.display = 'block';
let startTime = Date.now();
let duration = parseInt(data.duration, 10);
updateBar(25, data.duration);
const animateProgress = () => {
let timeElapsed = Date.now() - startTime;
let progress = timeElapsed / duration;
if (progress > 1) progress = 1;
let percentage = Math.round(progress * 100);
setProgress(percentage);
if (progress < 1) {
requestAnimationFrame(animateProgress);
} else {
onComplete();
}
};
requestAnimationFrame(animateProgress);
};
const cancelProgress = () => {
setProgressLabel('CANCELLED');
setProgress(100);
progressContainerRef.current.style.transition = 'opacity 0.3s ease-out';
progressContainerRef.current.style.opacity = '0';
setTimeout(() => {
resetProgress();
}, 1000);
};
const onComplete = () => {
setTimeout(() => {
resetProgress();
}, 100);
};
const resetProgress = () => {
setProgress(0);
setKneItems(Array(25).fill(false));
progressContainerRef.current.style.transition = 'opacity 0.3s ease-out';
progressContainerRef.current.style.opacity = '0';
progressContainerRef.current.style.display = 'none';
};
const updateBar = (kne, duration) => {
setKneItems(Array(25).fill(false));
let i = 0;
clearInterval(intervalRef.current);
intervalRef.current = setInterval(() => {
if (i >= kne) {
clearInterval(intervalRef.current);
} else {
setKneItems((prevItems) =>
prevItems.map((item, index) => (index <= i ? true : item))
);
let percentage = Math.round((i / kne) * 100);
setProgressPercentage(percentage);
i++;
}
}, duration / kne);
};
return (
<div className="progress-container" ref={progressContainerRef}>
<div className="progress-labels">
<div id="progress-label">{progressLabel}</div>
<div id="progress-percentage">{progressPercentage}%</div>
</div>
<div className="progress-bar-container">
<div id="progress-bar" style={{ width: `${progress}%` }}></div>
<div id="blackBar" className="responsive-bar"></div>
<div id="kneBar" className="container responsive-container">
{kneItems.map((filled, index) => (
<div
key={index}
className={`item ${filled ? 'filled' : ''}`}
></div>
))}
</div>
</div>
</div>
);
}
export default ProgressBar;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment