From 4fb912bc430f52d79c4babd8ad2eb240a4b2bd99 Mon Sep 17 00:00:00 2001 From: PitresAli Date: Wed, 26 Aug 2026 01:00:34 +0200 Subject: [PATCH] fix: Replace requestAnimationFrame with setTimeout to prevent deadlocks during headless/background boot --- web/app.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/web/app.js b/web/app.js index 3324b95..27c14c2 100644 --- a/web/app.js +++ b/web/app.js @@ -29,8 +29,8 @@ $('#window-min').onclick=()=>api('minimize_window');$('#window-max').onclick=()= const modelInput=$('#model-input'),modelButton=$('#load-model'); modelButton.onclick=()=>{modelInput.value='';modelInput.click()}; function bytesToBase64(bytes){let value='';for(let i=0;isetTimeout(r,0))}await api('finish_model_save',token)} +async function loadCachedModel(info){const bytes=new Uint8Array(info.size),chunk=1048576;for(let offset=0;offsetsetTimeout(r,0))}return window.rovModel.loadBuffer(bytes.buffer,info.name)} modelInput.onchange=async()=>{const file=modelInput.files?.[0],old=modelButton.textContent;if(!file)return;try{if(!file.name.toLowerCase().endsWith('.stl'))throw new Error('Choose an STL mesh');if(file.size>30*1024*1024)throw new Error('The STL is larger than 30 MB; export a lighter mesh');modelButton.disabled=true;modelButton.textContent='Loading…';await new Promise(requestAnimationFrame);const buffer=await file.arrayBuffer(),result=window.rovModel.loadBuffer(buffer,file.name);modelButton.textContent='Replace STL';toast(`Loaded ${result.name} • ${result.triangles.toLocaleString()} triangles`);if(bridgeReady)cacheModel(file).then(()=>toast('STL saved for the next launch')).catch(error=>toast(`Model loaded, but could not be saved: ${error.message}`,true))}catch(error){toast(`STL import failed: ${error.message}`,true)}finally{modelButton.disabled=false;if(modelButton.textContent==='Loading…')modelButton.textContent=old}}; $('#refresh').onclick=async()=>populatePorts(await api('refresh_ports'));$('#connect').onclick=async()=>{try{if(connected)await api('disconnect');else await api('connect',$('#port').value,+$('#baud').value,+$('#rate').value)}catch(e){toast(e.message,true)}}; $('#manual').onclick=()=>api('command','manual').catch(e=>toast(e.message,true));$('#arm').onclick=()=>openModal('arm-dialog');$('#confirm-arm').onclick=()=>{api('command','arm').catch(e=>toast(e.message,true));$('#arm-dialog').close()};$('#disarm').onclick=()=>api('command','disarm').catch(e=>toast(e.message,true));$('#logs').onclick=()=>api('open_logs');