@@ -62,7 +62,9 @@ interface CacheEntry {
6262 payload : MiniPayload ;
6363}
6464
65- const HOVER_DELAY_MS = 110 ;
65+ const HOVER_DELAY_MS = 150 ;
66+ const HOVER_INTENT_POLL_MS = 150 ;
67+ const HOVER_INTENT_SENSITIVITY = 7 ;
6668const HIDE_DELAY_MS = 130 ;
6769const CACHE_TTL_MS = 8000 ;
6870
@@ -194,6 +196,7 @@ class UserMiniWidget {
194196 init ( ) {
195197 document . body . addEventListener ( 'mouseover' , this . onBodyMouseOver ) ;
196198 document . body . addEventListener ( 'mouseout' , this . onBodyMouseOut ) ;
199+ document . body . addEventListener ( 'mousemove' , this . onBodyMouseMove ) ;
197200 window . addEventListener ( 'scroll' , this . onWindowChange , true ) ;
198201 window . addEventListener ( 'resize' , this . onWindowChange ) ;
199202 void this . loadBlockedUsers ( ) ;
@@ -223,6 +226,11 @@ class UserMiniWidget {
223226 this . scheduleShow ( anchor , profileId ) ;
224227 } ;
225228
229+ private onBodyMouseMove = ( event : MouseEvent ) => {
230+ this . lastMouseX = event . clientX ;
231+ this . lastMouseY = event . clientY ;
232+ } ;
233+
226234 private onBodyMouseOut = ( event : MouseEvent ) => {
227235 const target = event . target as HTMLElement | null ;
228236 if ( ! target ) return ;
@@ -232,6 +240,7 @@ class UserMiniWidget {
232240 const related = event . relatedTarget as HTMLElement | null ;
233241 if ( related && ( this . root . contains ( related ) || fromLink . contains ( related ) ) ) return ;
234242
243+ this . clearHoverTimer ( ) ;
235244 this . scheduleHide ( ) ;
236245 } ;
237246
@@ -260,12 +269,29 @@ class UserMiniWidget {
260269
261270 private scheduleShow ( anchor : HTMLElement , profileId : string ) {
262271 this . clearHoverTimer ( ) ;
272+ const startX = this . lastMouseX ;
273+ const startY = this . lastMouseY ;
263274 this . hoverTimer = window . setTimeout ( ( ) => {
264275 this . hoverTimer = undefined ;
265- void this . show ( anchor , profileId ) ;
276+ this . checkHoverIntent ( anchor , profileId , startX , startY ) ;
266277 } , HOVER_DELAY_MS ) ;
267278 }
268279
280+ private checkHoverIntent ( anchor : HTMLElement , profileId : string , prevX : number , prevY : number ) {
281+ if ( this . anchor !== anchor || this . anchorUser !== profileId ) return ;
282+
283+ const movement = Math . abs ( this . lastMouseX - prevX ) + Math . abs ( this . lastMouseY - prevY ) ;
284+ if ( movement <= HOVER_INTENT_SENSITIVITY ) {
285+ void this . show ( anchor , profileId ) ;
286+ return ;
287+ }
288+
289+ this . hoverTimer = window . setTimeout ( ( ) => {
290+ this . hoverTimer = undefined ;
291+ this . checkHoverIntent ( anchor , profileId , this . lastMouseX , this . lastMouseY ) ;
292+ } , HOVER_INTENT_POLL_MS ) ;
293+ }
294+
269295 private scheduleHide ( ) {
270296 this . clearHideTimer ( ) ;
271297 this . hideTimer = window . setTimeout ( ( ) => {
0 commit comments