|
|
|
|
@ -28,13 +28,13 @@ function App() { |
|
|
|
|
const [cuelist, setCuelist] = useState([]); |
|
|
|
|
const [currentCue, setCurrentCue] = useState(null); |
|
|
|
|
const [fadeDuration, setFadeDuration] = useState(DefaultFadeDuration); // Default fade duration in seconds |
|
|
|
|
const [timestamp, setTimestamp] = useState(); |
|
|
|
|
const [clientStatus, setClientStatus] = useState({}); |
|
|
|
|
|
|
|
|
|
const refCue = useRef(null); |
|
|
|
|
// const refNextCue = useRef(null); |
|
|
|
|
const refLight = useRef(); |
|
|
|
|
const refDuration = useRef(); |
|
|
|
|
const refTotalTime=useRef(); |
|
|
|
|
const refTimer = useRef(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -102,7 +102,19 @@ function App() { |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function getTotalLeftTime(id){ |
|
|
|
|
const cue=cuelist.find(el=>el.id==id); |
|
|
|
|
const index=cuelist.indexOf(cue); |
|
|
|
|
if(index==-1) return; |
|
|
|
|
|
|
|
|
|
let sum=0; |
|
|
|
|
for(var i=index;i<cuelist.length;++i){ |
|
|
|
|
if(cuelist[i].duration) sum+=cuelist[i].duration; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return sum; |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function playCue({ id, name, description, type, auto, audioFile, ...props }) { |
|
|
|
|
@ -132,25 +144,54 @@ function App() { |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (refTimer.current) { |
|
|
|
|
clearTimeout(refTimer.current); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (props.duration) { |
|
|
|
|
if(refTimer.current) clearInterval(refTimer.current); |
|
|
|
|
let due= props.duration; |
|
|
|
|
|
|
|
|
|
console.log('Start timer:', due); |
|
|
|
|
const next=cuelist.find(c=>c.id==id+1); |
|
|
|
|
// calculate last time |
|
|
|
|
let totalLefTime=getTotalLeftTime(id); |
|
|
|
|
|
|
|
|
|
// Clear any existing timer |
|
|
|
|
|
|
|
|
|
// Store the end time of the timer |
|
|
|
|
const totalEndTime=new Date().getTime()+totalLefTime*1000; |
|
|
|
|
const endTime = new Date().getTime() + (props.duration * 1000); |
|
|
|
|
|
|
|
|
|
refTimer.current= setInterval(()=>{ |
|
|
|
|
due--; |
|
|
|
|
if(due<=0){ |
|
|
|
|
clearInterval(refTimer.current); |
|
|
|
|
// Function to update the timer |
|
|
|
|
const tick = () => { |
|
|
|
|
const now = new Date().getTime(); |
|
|
|
|
const timeLeft = endTime - now; |
|
|
|
|
const totalTimeLeft=totalEndTime-now; |
|
|
|
|
//console.log(totalTimeLeft); |
|
|
|
|
|
|
|
|
|
if (timeLeft <= 0) { |
|
|
|
|
// Timer has finished |
|
|
|
|
clearTimeout(refTimer.current); |
|
|
|
|
refTimer.current = null; |
|
|
|
|
|
|
|
|
|
if (auto) { |
|
|
|
|
console.log('Auto play next cue:', next); |
|
|
|
|
const next = cuelist.find(c => c.id === id + 1); |
|
|
|
|
playCue(next); |
|
|
|
|
} |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
refDuration.current.innerText= secondToTime(due); |
|
|
|
|
},1000); |
|
|
|
|
|
|
|
|
|
// Update the displayed duration |
|
|
|
|
refDuration.current.innerText = secondToTime(timeLeft / 1000); |
|
|
|
|
refTotalTime.current.innerText=`${secondToTime(totalTimeLeft/1000)} / ${secondToTime(totalLefTime)}`; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Call the next tick |
|
|
|
|
refTimer.current = setTimeout(tick, 100); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
// Start the timer |
|
|
|
|
console.log('Start timer:', props.duration); |
|
|
|
|
refTimer.current = setTimeout(tick, 100); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} |
|
|
|
|
@ -174,7 +215,7 @@ function App() { |
|
|
|
|
function secondToTime(seconds) { |
|
|
|
|
const minutes = Math.floor(seconds / 60); |
|
|
|
|
const secs = Math.floor(seconds % 60); |
|
|
|
|
return `${minutes}:${secs < 10 ? '0' : ''}${secs}`; |
|
|
|
|
return `${minutes.toString().padStart(2,'0')}:${secs < 10 ? '0' : ''}${secs}`; |
|
|
|
|
} |
|
|
|
|
function getAudioDuration() { |
|
|
|
|
|
|
|
|
|
@ -225,14 +266,11 @@ function App() { |
|
|
|
|
return ( |
|
|
|
|
<main className="overflow-y-auto flex flex-row gap-8 p-4 min-h-screen"> |
|
|
|
|
<section className="flex-1 flex flex-col gap-4"> |
|
|
|
|
<section className="flex flex-row justify-between items-center gap-2"> |
|
|
|
|
<div className="flex flex-row font-bold items-stretch justify-center w-1/3 bg-pink-300 gap-4 p-2"> |
|
|
|
|
<section className="grid grid-cols-4 items-center gap-2"> |
|
|
|
|
<div className="flex flex-row font-bold items-stretch justify-bewteen bg-pink-300 gap-4 p-2"> |
|
|
|
|
<div className="text-4xl">{currentCue ? `${currentCue.name}` : 'None'}</div> |
|
|
|
|
<div className="text-4xl" ref={refDuration}></div> |
|
|
|
|
</div> |
|
|
|
|
<p> |
|
|
|
|
{timestamp} |
|
|
|
|
</p> |
|
|
|
|
<button className="text-4xl self-stretch" onClick={stop}>stop all</button> |
|
|
|
|
<button className="text-4xl self-stretch" onClick={reset}>reset all</button> |
|
|
|
|
<Light ref={refLight} /> |
|
|
|
|
@ -282,6 +320,8 @@ function App() { |
|
|
|
|
))} |
|
|
|
|
</tbody> |
|
|
|
|
</table> |
|
|
|
|
<div className="text-6xl text-center font-bold bg-blue-500 text-white p-4" ref={refTotalTime}></div> |
|
|
|
|
|
|
|
|
|
</section> |
|
|
|
|
<table className="flex-1 text-sm"> |
|
|
|
|
<thead className="bg-blue-500"> |
|
|
|
|
|