diff --git a/static/js/sw.js b/static/js/sw.js index bb22f5b..8c93abc 100644 --- a/static/js/sw.js +++ b/static/js/sw.js @@ -2,7 +2,7 @@ * diora service worker — caches the app shell for offline use. */ -const CACHE = 'diora-v71'; +const CACHE = 'diora-v72'; const SHELL = [ '/static/css/app.css', '/static/js/app.js', diff --git a/static/podcasts/native-podcast.js b/static/podcasts/native-podcast.js index 27ca360..48023e6 100644 --- a/static/podcasts/native-podcast.js +++ b/static/podcasts/native-podcast.js @@ -1,4 +1,4 @@ -// Copied from diora-android abda34a 2026-10-03: web-native/static/native-podcast.js +// Copied from diora-android 370e653 2026-10-03: web-native/static/native-podcast.js // by tools/sync_podcast_ui.py. Do not edit here: change it in diora-android // and copy again. The browser host is static/js/podcasts-web.js. @@ -71,6 +71,8 @@ let preview = null; // {id, url, data | choices | error} while a feed is looked at before subscribing let previewSeq = 0; let refreshing = false; + let swipingSince = 0; // a row is being swiped (since then): render waits (rowGestures) + let renderAfterSwipe = false; let selected = null; // Set of episode ids while choosing several (queue or inbox) let locked = false; // queue locked: no dragging try { locked = localStorage.getItem('nui_pod_locked') === '1'; } catch (e) {} @@ -982,6 +984,9 @@ } function render() { + // A finger is swiping a row: redrawing now would pull the row away under it (and end + // the swipe). It redraws when the swipe ends — unless that never came (a lost pointer). + if (swipingSince && Date.now() - swipingSince < 8000) { renderAfterSwipe = true; return; } episodeScreenParts(); if (!root) return; const scroll = scrollTop(); @@ -1174,6 +1179,7 @@ function rowGestures(row, onLong, onSwipe, list) { let start = null; + let holding = false; // this row counts in swipingSince let timer = 0; let mode = ''; let dx = 0; @@ -1217,6 +1223,11 @@ delete other.dataset.act; }; const finish = done => { + if (holding) { + holding = false; + swipingSince = 0; + if (renderAfterSwipe) { renderAfterSwipe = false; setTimeout(render, done ? 200 : 220); } + } row.classList.remove('nui-pod-swiping'); const gone = bg; bg = null; @@ -1257,7 +1268,9 @@ if (Math.abs(mx) > 8 || Math.abs(my) > 8) { stopTimer(); start.moved = true; } if (onSwipe && start.touch && Math.abs(mx) > 12 && Math.abs(mx) > Math.abs(my) * 1.5) { mode = 'swipe'; - commitSwipe(); + // The swipe before stays undoable (its bar too) until this one is done (offerUndo). + holding = true; + swipingSince = Date.now(); try { row.setPointerCapture(ev.pointerId); } catch (e) {} bg = el('div', 'nui-pod-swipebg'); bg.append(el('span', 'nui-pod-swipe-l'), el('span', 'nui-pod-swipe-r'));