|
|
|
@ -1,59 +1,77 @@ |
|
|
|
import { useEffect, useState, useRef, forwardRef, useImperativeHandle, } from "react" |
|
|
|
import { useEffect, useState, useRef, forwardRef, useImperativeHandle, } from "react" |
|
|
|
import { OSC_ADDRESS, sendOscStatus } from "../util/osc"; |
|
|
|
import { OSC_ADDRESS, sendOscStatus } from "../util/osc"; |
|
|
|
|
|
|
|
|
|
|
|
const Update_Interval = 1000; // 1 second |
|
|
|
const Update_Interval = 100; // 1 second |
|
|
|
|
|
|
|
|
|
|
|
export const Countdown=forwardRef(({time, callback, auto,clientId, ...props}, ref)=>{ |
|
|
|
export const Countdown = forwardRef(({ time, callback, auto, clientId, ...props }, ref) => { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const refTime = useRef(time); |
|
|
|
const refTime = useRef(time); |
|
|
|
const refInterval = useRef(null); |
|
|
|
const refInterval = useRef(null); |
|
|
|
const refDisplay=useRef(); |
|
|
|
const refDisplay = useRef(); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// A simple function to recursively call itself until the timer expires. |
|
|
|
function restart(newTime, callback_func) { |
|
|
|
function restart(newTime, callback_func) { |
|
|
|
|
|
|
|
|
|
|
|
console.log('restart countdown:', newTime, 'ms'); |
|
|
|
console.log('restart countdown:', newTime, 'ms'); |
|
|
|
|
|
|
|
|
|
|
|
if(refInterval.current) { |
|
|
|
// Clear any existing timer. |
|
|
|
clearInterval(refInterval.current); |
|
|
|
if (refInterval.current) { |
|
|
|
|
|
|
|
clearTimeout(refInterval.current); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
refTime.current = newTime || time; |
|
|
|
// Set the end time to ensure accuracy. |
|
|
|
refInterval.current=setInterval(() => { |
|
|
|
const endTime = new Date().getTime() + (newTime || time); |
|
|
|
if(refTime.current>0){ |
|
|
|
|
|
|
|
refTime.current -= Update_Interval; |
|
|
|
// The main timer function that gets called every 'Update_Interval'. |
|
|
|
// console.log('Countdown:', refTime.current/1000); |
|
|
|
const tick = () => { |
|
|
|
}else{ |
|
|
|
const now = new Date().getTime(); |
|
|
|
|
|
|
|
const timeLeft = endTime - now; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// The timer has expired. |
|
|
|
|
|
|
|
if (timeLeft <= 0) { |
|
|
|
refTime.current = 0; |
|
|
|
refTime.current = 0; |
|
|
|
clearInterval(refInterval.current); |
|
|
|
clearTimeout(refInterval.current); |
|
|
|
|
|
|
|
refInterval.current = null; |
|
|
|
|
|
|
|
|
|
|
|
if(typeof callback_func === 'function'){ |
|
|
|
if (typeof callback_func === 'function') { |
|
|
|
callback_func(); |
|
|
|
callback_func(); |
|
|
|
}else{ |
|
|
|
} else { |
|
|
|
if(callback) callback(); |
|
|
|
if (callback) callback(); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if(refDisplay.current) refDisplay.current.innerText = (refTime.current/1000).toFixed(0); |
|
|
|
// Final display update and OSC message. |
|
|
|
sendOscStatus(OSC_ADDRESS.CLIENT_DURATION, `${clientId}#${(refTime.current/1000).toFixed(0)}`); // send remaining time in seconds via OSC |
|
|
|
if (refDisplay.current) refDisplay.current.innerText = '0'; |
|
|
|
|
|
|
|
sendOscStatus(OSC_ADDRESS.CLIENT_DURATION, `${clientId}#0`); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
}, Update_Interval); |
|
|
|
// Update the display and send the OSC status. |
|
|
|
|
|
|
|
refTime.current = timeLeft; |
|
|
|
|
|
|
|
if (refDisplay.current) refDisplay.current.innerText = (refTime.current / 1000).toFixed(0); |
|
|
|
|
|
|
|
sendOscStatus(OSC_ADDRESS.CLIENT_DURATION, `${clientId}#${(refTime.current / 1000).toFixed(0)}`); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Schedule the next tick. |
|
|
|
|
|
|
|
refInterval.current = setTimeout(tick, Update_Interval); |
|
|
|
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Start the timer. |
|
|
|
|
|
|
|
refInterval.current = setTimeout(tick, Update_Interval); |
|
|
|
} |
|
|
|
} |
|
|
|
function stop(){ |
|
|
|
|
|
|
|
|
|
|
|
// The stop function is also updated to use clearTimeout. |
|
|
|
|
|
|
|
function stop() { |
|
|
|
console.log('stop countdown'); |
|
|
|
console.log('stop countdown'); |
|
|
|
if(refInterval.current) { |
|
|
|
if (refInterval.current) { |
|
|
|
clearInterval(refInterval.current); |
|
|
|
clearTimeout(refInterval.current); |
|
|
|
refInterval.current = null; |
|
|
|
refInterval.current = null; |
|
|
|
} |
|
|
|
} |
|
|
|
// refDisplay.current.innerText = ''; |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
useEffect(()=>{ |
|
|
|
useEffect(() => { |
|
|
|
|
|
|
|
|
|
|
|
if(auto) |
|
|
|
if (auto) |
|
|
|
restart(time); |
|
|
|
restart(time); |
|
|
|
|
|
|
|
|
|
|
|
// return () => { |
|
|
|
// return () => { |
|
|
|
|