Skip to content

Commit 5958ef5

Browse files
fix: prevent multiple refreshes on long scroll gestures
Replace isRefreshingRef with time-based cooldown (5 seconds) to prevent rapid-fire refreshes when user performs a long scroll gesture. The cooldown applies to all interaction methods (touch, mouse drag, and wheel scroll). Co-authored-by: Anthony <AnthonyRonning@users.noreply.github.com>
1 parent 8d7a797 commit 5958ef5

1 file changed

Lines changed: 27 additions & 13 deletions

File tree

‎frontend/src/components/ChatHistoryList.tsx‎

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export function ChatHistoryList({
9090
constisPulling=useRef(false);
9191
constpullDistanceRef=useRef(0);
9292
constwheelDeltaAccumulator=useRef(0);
93-
constisRefreshingRef=useRef(false);
93+
constlastRefreshTime=useRef(0);
9494

9595
// Fetch initial conversations from API using the OpenSecret SDK
9696
const{ isPending, error }=useQuery({
@@ -185,8 +185,6 @@ export function ChatHistoryList({
185185

186186
// Pull-to-refresh handler
187187
consthandleRefresh=useCallback(async()=>{
188-
// Set ref immediately to block rapid-fire events
189-
isRefreshingRef.current=true;
190188
setIsPullRefreshing(true);
191189
try{
192190
awaitpollForUpdates();
@@ -197,7 +195,8 @@ export function ChatHistoryList({
197195
setTimeout(()=>{
198196
setIsPullRefreshing(false);
199197
setPullDistance(0);
200-
isRefreshingRef.current=false;
198+
// Record the time when refresh completes for cooldown
199+
lastRefreshTime.current=Date.now();
201200
},300);
202201
}
203202
},[pollForUpdates]);
@@ -241,11 +240,15 @@ export function ChatHistoryList({
241240

242241
isPulling.current=false;
243242

244-
// Trigger refresh if pulled far enough (threshold: 60px)
245-
if(pullDistanceRef.current>60){
243+
// Check cooldown: enforce 5-second delay between refreshes
244+
consttimeSinceLastRefresh=Date.now()-lastRefreshTime.current;
245+
constcooldownPeriod=5000;// 5 seconds
246+
247+
// Trigger refresh if pulled far enough (threshold: 60px) and cooldown elapsed
248+
if(pullDistanceRef.current>60&&timeSinceLastRefresh>=cooldownPeriod){
246249
handleRefresh();
247250
}else{
248-
// Reset if not pulled far enough
251+
// Reset if not pulled far enough or still in cooldown
249252
setPullDistance(0);
250253
}
251254
};
@@ -282,11 +285,15 @@ export function ChatHistoryList({
282285

283286
isPulling.current=false;
284287

285-
// Trigger refresh if pulled far enough (threshold: 60px)
286-
if(pullDistanceRef.current>60){
288+
// Check cooldown: enforce 5-second delay between refreshes
289+
consttimeSinceLastRefresh=Date.now()-lastRefreshTime.current;
290+
constcooldownPeriod=5000;// 5 seconds
291+
292+
// Trigger refresh if pulled far enough (threshold: 60px) and cooldown elapsed
293+
if(pullDistanceRef.current>60&&timeSinceLastRefresh>=cooldownPeriod){
287294
handleRefresh();
288295
}else{
289-
// Reset if not pulled far enough
296+
// Reset if not pulled far enough or still in cooldown
290297
setPullDistance(0);
291298
}
292299
};
@@ -295,11 +302,15 @@ export function ChatHistoryList({
295302
constWHEEL_THRESHOLD=-50;// Require accumulated scroll before triggering
296303

297304
consthandleWheel=(e: WheelEvent)=>{
298-
if(!isDesktopPlatform||isRefreshingRef.current)return;
305+
if(!isDesktopPlatform||isPullRefreshing)return;
299306

300307
// Only handle if the event target is within our container
301308
if(!container.contains(e.targetasNode))return;
302309

310+
// Check cooldown: enforce 5-second delay between refreshes
311+
consttimeSinceLastRefresh=Date.now()-lastRefreshTime.current;
312+
constcooldownPeriod=5000;// 5 seconds
313+
303314
// Check if we're at the top and trying to scroll up
304315
if(container.scrollTop===0&&e.deltaY<0){
305316
// Prevent default to avoid browser overscroll bounce
@@ -313,8 +324,11 @@ export function ChatHistoryList({
313324
pullDistanceRef.current=visualDistance;
314325
setPullDistance(visualDistance);
315326

316-
// Trigger refresh if threshold is reached
317-
if(wheelDeltaAccumulator.current<=WHEEL_THRESHOLD){
327+
// Trigger refresh if threshold is reached and cooldown elapsed
328+
if(
329+
wheelDeltaAccumulator.current<=WHEEL_THRESHOLD&&
330+
timeSinceLastRefresh>=cooldownPeriod
331+
){
318332
wheelDeltaAccumulator.current=0;
319333
handleRefresh();
320334
}

0 commit comments

Comments
 (0)