From f13b2dc8e573b908033e86dd4be1c5615c518f36 Mon Sep 17 00:00:00 2001 From: ULTRACOMBOS-DEV Date: Fri, 26 Sep 2025 14:00:08 +0800 Subject: [PATCH] update appscript api change setInterval to setTimeout --- vite/src-tauri/capabilities/default.json | 4 +- vite/src/comps/timer.jsx | 80 +++++++++++++++--------- vite/src/pages/flow_free.jsx | 45 ++++++++++--- vite/src/util/backend.js | 2 +- 4 files changed, 87 insertions(+), 44 deletions(-) diff --git a/vite/src-tauri/capabilities/default.json b/vite/src-tauri/capabilities/default.json index a9f8e6b..512d68f 100644 --- a/vite/src-tauri/capabilities/default.json +++ b/vite/src-tauri/capabilities/default.json @@ -23,9 +23,7 @@ { "url": "http://**/" },{ - "url":"https://script.google.com/macros/s/AKfycbxpXbWhMdd4nv0KHhSzeFTKIV0tqsh-HBKCdlaOT34sh2vl1H5aoa36QnimhQg8I2aKRw/exec" - },{ - "url":"https://script.google.com/macros/s/AKfycbx-Ytlql0yAdVsENNbcaCdXglerX7sNLpNggtusqp4TxebiA3C7V0xjGe4jaI4m1sVjWQ/exec" + "url":"https://script.google.com/macros/s/AKfycbyqLIX2USYfn2dp_1RQ5VdLywVNfUVgpGER9ZNsolXOfdPtJmuPAJCfjfA4aGxKHdBW0A/exec" } ] }, diff --git a/vite/src/comps/timer.jsx b/vite/src/comps/timer.jsx index 0f11ae0..6d90934 100644 --- a/vite/src/comps/timer.jsx +++ b/vite/src/comps/timer.jsx @@ -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"; -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 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) { - - console.log('restart countdown:', newTime, 'ms'); + console.log('restart countdown:', newTime, 'ms'); - if(refInterval.current) { - clearInterval(refInterval.current); + // Clear any existing timer. + if (refInterval.current) { + clearTimeout(refInterval.current); } - refTime.current = newTime || time; - refInterval.current=setInterval(() => { - if(refTime.current>0){ - refTime.current -= Update_Interval; - // console.log('Countdown:', refTime.current/1000); - }else{ + // Set the end time to ensure accuracy. + const endTime = new Date().getTime() + (newTime || time); + + // The main timer function that gets called every 'Update_Interval'. + const tick = () => { + const now = new Date().getTime(); + const timeLeft = endTime - now; + + // The timer has expired. + if (timeLeft <= 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(); - }else{ - if(callback) callback(); + } else { + if (callback) callback(); } - } - if(refDisplay.current) refDisplay.current.innerText = (refTime.current/1000).toFixed(0); - sendOscStatus(OSC_ADDRESS.CLIENT_DURATION, `${clientId}#${(refTime.current/1000).toFixed(0)}`); // send remaining time in seconds via OSC + // Final display update and OSC message. + if (refDisplay.current) refDisplay.current.innerText = '0'; + sendOscStatus(OSC_ADDRESS.CLIENT_DURATION, `${clientId}#0`); - }, Update_Interval); + return; + } + + // 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'); - if(refInterval.current) { - clearInterval(refInterval.current); + if (refInterval.current) { + clearTimeout(refInterval.current); refInterval.current = null; } - // refDisplay.current.innerText = ''; } - useEffect(()=>{ + useEffect(() => { - if(auto) + if (auto) restart(time); // return () => { @@ -64,12 +82,12 @@ export const Countdown=forwardRef(({time, callback, auto,clientId, ...props}, re useImperativeHandle(ref, () => ({ restart, - stop, - remainingTime: refTime.current, + stop, + remainingTime: refTime.current, })); return ( -
) diff --git a/vite/src/pages/flow_free.jsx b/vite/src/pages/flow_free.jsx index 13b4fd7..e4ea862 100644 --- a/vite/src/pages/flow_free.jsx +++ b/vite/src/pages/flow_free.jsx @@ -88,6 +88,8 @@ export function FreeFlow(){ const refFadeOutInterval=useRef(); const refVolDownInterval=useRef(); + const [lastOsc, setLastOsc]=useState(); + const { history, status, reset, sendMessage, setStatus, audioOutput, setAudioOutput, stop:stopChat, audioUrl }=useChat(); @@ -120,21 +122,23 @@ export function FreeFlow(){ const message=payload.args[0]; const params=message.split('#'); + if(params[0]!='all'){ + console.log('set lastOsc', {address, params}); + setLastOsc(()=>({address, params})); + return; + } + switch(address){ case OSC_ADDRESS.PLAY_CUE: - if(params[0]=='all' || params[0]==refData.current?.id) setNextCue(()=>params[1]); break; case OSC_ADDRESS.STOP_CUE: - if(params[0]=='all' || params[0]==refData.current?.id) - onStop(); + onStop(); break; case OSC_ADDRESS.RESET_CUE: - if(params[0]=='all' || params[0]==refData.current?.id){ - sendOsc(OSC_ADDRESS.STATUS, 'reset'); - onStop(); - resetData(); - } + sendOsc(OSC_ADDRESS.STATUS, 'reset'); + onStop(); + resetData(); break; } @@ -196,7 +200,7 @@ export function FreeFlow(){ clearInterval(refVolDownInterval.current); } - const dest=0.5; + const dest=0.3; let fadeOutInterval = setInterval(() => { if (refAudio.current.volume > dest) { refAudio.current.volume =Math.max(dest, refAudio.current.volume - 1.0/(AUDIO_FADE_TIME/100)); // Decrease volume gradually @@ -576,6 +580,29 @@ export function FreeFlow(){ writeSheet(); } + useEffect(()=>{ + + if(!lastOsc) return; + console.log('Process last OSC:', lastOsc); + + if(lastOsc.params[0]!=data.id) return; + + switch(lastOsc.address){ + case OSC_ADDRESS.PLAY_CUE: + setNextCue(()=>lastOsc.params[1]); + break; + case OSC_ADDRESS.STOP_CUE: + onStop(); + break; + case OSC_ADDRESS.RESET_CUE: + sendOsc(OSC_ADDRESS.STATUS, 'reset'); + onStop(); + resetData(); + break; + } + + },[lastOsc]); + useEffect(()=>{ diff --git a/vite/src/util/backend.js b/vite/src/util/backend.js index a424475..fdb320d 100644 --- a/vite/src/util/backend.js +++ b/vite/src/util/backend.js @@ -36,7 +36,7 @@ export async function updateUser(id, data){ } -const APPSCRIPT_URL='https://script.google.com/macros/s/AKfycbx-Ytlql0yAdVsENNbcaCdXglerX7sNLpNggtusqp4TxebiA3C7V0xjGe4jaI4m1sVjWQ/exec'; +const APPSCRIPT_URL='https://script.google.com/macros/s/AKfycbyqLIX2USYfn2dp_1RQ5VdLywVNfUVgpGER9ZNsolXOfdPtJmuPAJCfjfA4aGxKHdBW0A/exec'; // const APPSCRIPT_URL='https://script.google.com/macros/s/AKfycbxpXbWhMdd4nv0KHhSzeFTKIV0tqsh-HBKCdlaOT34sh2vl1H5aoa36QnimhQg8I2aKRw/exec'; export async function writeToGoogleSheet(date, session, userId, password){