From 66e175e86313feeb4c0dcf1061d87f6f1c6c8f2c Mon Sep 17 00:00:00 2001 From: dadaloop82 Date: Tue, 17 Mar 2026 14:15:16 +0000 Subject: [PATCH] 20260317d: Auto-dismiss move modal after 15s with progress bar countdown --- assets/css/style.css | 6 ++++++ assets/js/app.js | 45 +++++++++++++++++++++++++++++++++++++------ data/dispensa.db | Bin 188416 -> 196608 bytes index.html | 4 ++-- 4 files changed, 47 insertions(+), 8 deletions(-) diff --git a/assets/css/style.css b/assets/css/style.css index 129a1fd..c7a3da2 100644 --- a/assets/css/style.css +++ b/assets/css/style.css @@ -751,6 +751,12 @@ body { border: 2px solid var(--border); } +.move-countdown-btn { + position: relative; + overflow: hidden; + transition: none; +} + .btn-accent { background: var(--accent); color: white; diff --git a/assets/js/app.js b/assets/js/app.js index 1db105c..b728150 100644 --- a/assets/js/app.js +++ b/assets/js/app.js @@ -3570,27 +3570,58 @@ function closeLowStockPrompt() { if (cb) cb(); } +let _moveModalTimer = null; +let _moveModalRAF = null; + +function clearMoveModalTimer() { + if (_moveModalTimer) { clearTimeout(_moveModalTimer); _moveModalTimer = null; } + if (_moveModalRAF) { cancelAnimationFrame(_moveModalRAF); _moveModalRAF = null; } +} + +function startMoveModalCountdown(btnId, onExpire) { + clearMoveModalTimer(); + const duration = 15000; + const start = performance.now(); + const btn = document.getElementById(btnId); + if (!btn) return; + function tick() { + const elapsed = performance.now() - start; + const pct = Math.max(0, 100 - (elapsed / duration) * 100); + btn.style.background = `linear-gradient(to right, var(--bg-tertiary) ${pct}%, transparent ${pct}%)`; + if (elapsed < duration) { + _moveModalRAF = requestAnimationFrame(tick); + } + } + _moveModalRAF = requestAnimationFrame(tick); + _moveModalTimer = setTimeout(() => { + clearMoveModalTimer(); + onExpire(); + }, duration); +} + function showMoveAfterUseModal(product, fromLoc, remaining, openedId) { const otherLocs = Object.entries(LOCATIONS).filter(([k]) => k !== fromLoc); const locButtons = otherLocs.map(([k, v]) => - `` + `` ).join(''); document.getElementById('modal-content').innerHTML = `

Vuoi spostare ${openedId ? 'la confezione aperta' : 'il resto'} di ${escapeHtml(product.name)} in un'altra posizione?

${locButtons}
- +
`; document.getElementById('modal-overlay').style.display = 'flex'; + startMoveModalCountdown('btn-move-stay', () => { closeModal(); showPage('dashboard'); }); } async function confirmMoveAfterUse(productId, fromLoc, toLoc, openedId) { + clearMoveModalTimer(); closeModal(); showLoading(true); try { @@ -5260,24 +5291,26 @@ async function submitRecipeUse(useAll) { function showRecipeMoveModal(productId, fromLoc, remaining, openedId) { const otherLocs = Object.entries(LOCATIONS).filter(([k]) => k !== fromLoc); const locButtons = otherLocs.map(([k, v]) => - `` + `` ).join(''); document.getElementById('modal-content').innerHTML = `

Vuoi spostare ${openedId ? 'la confezione aperta' : 'il resto'} in un'altra posizione?

${locButtons}
- +
`; document.getElementById('modal-overlay').style.display = 'flex'; + startMoveModalCountdown('btn-move-stay', () => { closeModal(); }); } async function confirmRecipeMove(productId, fromLoc, toLoc, openedId) { + clearMoveModalTimer(); closeModal(); try { if (openedId) { diff --git a/data/dispensa.db b/data/dispensa.db index 73236350249ab2cb93cfbc1d31c96715860c89d6..437bb98f734b444750d3e1328cf4f219280b1d60 100644 GIT binary patch delta 2352 zcmb7GZ){sv756=M9LL4INt{2+y0kZjq-k+7JGSfOl{9TrROs3%X}5~CAKIJe7jwh& zd(QK7P_u=^P$s5HZKtQ|ibA1?0j2BKOdc}bCPvXD1ZdNyO4X1yb?ui)6G#n$@qrKH zJjabQ;0u3#X+(XowpHu$`o zh^46_uNB(MZ;tJ5ZoM5m;GzGbp9B}^J^FF*Qt*J&oNq60o7hHt!LJ1;%ZDfb7HIc- z33xqs+#%=raCNv{K5^`4?c^z^A^)QDO8&93fA($&=w;{QZ~exP!SQikT0H7*So$(- zP@IEHk2v37GRywb?x6FfGokX4Xa5W>ZMgL_zw+prnXfdZSv;x4hLuEl`PRiQ@>==P zd#C-x@7(;PFIZiR$Cc!8+568^0eRz7GS)uc+vFkLq$iOGY|V&5UNZ_DoOeF$qiax! z5aFKm`38~+FL+1b@30Iy*#g^PJ9(Zw@06O3oxeq%^?Bd$JdKlYS3V--J>o-h`*6Cu z;`I^o)I&k~woCV6S2Vgp|3W{acj*W8J$jSAUG8aqnZjU;ym^+yAKXC09$fz&y+zN{ ztF%M~-9?YkFzv^E|Jc~x=IiMsL$RS91F^(FJe@IhRcn>~KPKNjzl)%6(qGY^ zQ%S!^Pth5A9FLAtIdhF{B&`)3E?n}Sh2cu$1auKU%)lfJmrG5pA79`&S5AGc=!9Z$i^jj#_wD39q?^ICeL`A`%66FAz{)T zN_fqp?Uy%BLtCyEELJ*+i=9o~n-aNi@`A11Pt4w;ZFAfFEWav^Sn0(7bHpWBSw0OD z$Aclv3V~%0EF-fs0HK-Z_H-;>IMmwc>FIps@kBjXRp}=qwy=28Nr?~ zvqj5h`>{k!rm?-EpqjQVm}(kqkHrmDa5l~@p3`)l+dLAD*9T#O!*=oo z5|@{*g96EvTzM7RNm9lY=nE%PF_y&>Q%E4=N+NVw@C`vHXI%xlmhAN@6SlO1w0 z01FiQFiJ+`jbFkD z8F6N>J}6@!Ky%<&QB}W=q~*1KGA8qvVV5@^PszzY!OrIRfADdhcqi5pS%^LvF;ILY zxVLEG$%`W}=8Y#~@+a5fyB+&9Ho;9@u!BXB6{ym*$m&Ao73l089*C#bpFdicb)8Tv z4S3tbSK#xIPP&+V&gK`|P_lckLI(~LJE6}XkHuI{m$N>+Fjj7SAT}(wzX09gH5^pI zy_(=cj$eTx$=-tV@{3m?C|_@YEy1;Ym;#LFjSZ%qcdzuwK0i?T(sk&nD(ilhd-_SA zJmZJ9>g=a}c(@@kFqDi)HcC1=j!e1EF?DWfENhvC0=^nt4sL|5mO+d%!SNFtQrIEW zu;uX|!KTHW&~y!z5&D`{&|W;l(B_(Wu5?+&R~(Hpe7z3)eVX%xm-W8dlUGdu%mahO<1k(6h*>fZ!%W zPq68tX$h^MYW3(zg?-hivdi;~TYgb22Vo+%%NkElxsIq-s&2CRnzshoo@`bWjjX#V ztE+W_nXR>Ai`GM<1a5h)ajN33E5JcEUNlt~in|n%Yz{k`$*}5~DlC<=)Ii!T1z4>ul5SeM2*yX7HrKXI~2ALyPoAjyX|ha$aOar zwTz)En7~>KtRrx_vWqbNaf4+v?4j5@v!-sM>(D=zhTTZa;f=93p<%L^1T%_G8Ep#zIkJy+{^FGmRt^2w=cpimuQzEdKr;u7klPzyRxO0#lyq~~zvU2(QHR#zq fCv2V*28z5;Z~E2$6KN$jQfWC!{z{#5P2qn7NNU?a delta 561 zcmZ9JPiPZC6vp?>ZkpX~(w8CyYb>UP)~F=xZvMJrTco0>lvt%md#I&NAi+v%E*6Y# zw20E8l_Bm)?4gPWwb4=5lZy1HAOu1WRiq$=;-QMvg9n`mz4&0@y?NjF<739MJl5OB zIls3<5QH#4|LRUK0UgiI4)!#CZj?knTu6^)^XWn}Tk7fc`Bu~s0e|DBTEq=pSLdlO z-@^8#_5eF`@`p_46h9jode8zz>dHSM_=rBwpJwvp7cUV6x_a;aN|3_CLOl{C9~9FN!reGsY^l zd#&(-^>0i!fQME$yVQ628rSB7aM98m(ev_rva{S(6VC&usi z4cBlLKjAV~S-bBQ+O^vd-mYR$;H!67!!ka`5@xX*PhpTtJZJ~+!wQ$=1nytODlXwm ze26yQz$wgeNk7`di_qj;T!h(qah6E$sA~WK diff --git a/index.html b/index.html index df50902..862941e 100644 --- a/index.html +++ b/index.html @@ -9,7 +9,7 @@ Dispensa Manager - + @@ -911,6 +911,6 @@ - +