@@ -7,12 +7,10 @@ import { getClickTargetNode } from './util/domUtils';
77
88type ClickBreadcrumb = Breadcrumb & {
99 timestamp : number ;
10- data : { nodeId : number } ;
1110} ;
1211
1312interface Click {
1413 timestamp : number ;
15- nodeId : number ;
1614 mutationAfter ?: number ;
1715 scrollAfter ?: number ;
1816 clickBreadcrumb : ClickBreadcrumb ;
@@ -121,7 +119,7 @@ export class ClickDetector implements ReplayClickDetector {
121119 return ;
122120 }
123121
124- const click = this . _getClick ( breadcrumb ) ;
122+ const click = this . _getClick ( node ) ;
125123
126124 if ( click ) {
127125 // this means a click on the same element was captured in the last 1s, so we consider this a multi click
@@ -130,9 +128,9 @@ export class ClickDetector implements ReplayClickDetector {
130128
131129 const newClick : Click = {
132130 timestamp : breadcrumb . timestamp ,
133- nodeId : breadcrumb . data . nodeId ,
134131 clickBreadcrumb : breadcrumb ,
135- clickCount : 1 ,
132+ // Set this to 0 so we know it originates from the click breadcrumb
133+ clickCount : 0 ,
136134 node,
137135 } ;
138136 this . _clicks . push ( newClick ) ;
@@ -145,27 +143,22 @@ export class ClickDetector implements ReplayClickDetector {
145143
146144 /** Count multiple clicks on elements. */
147145 private _handleMultiClick ( node : HTMLElement ) : void {
148- const now = nowInSeconds ( ) ;
149- const click = this . _clicks . find ( click => click . node === node && now - click . timestamp < this . _multiClickTimeout ) ;
146+ const click = this . _getClick ( node ) ;
150147
151148 if ( ! click ) {
152149 return ;
153150 }
154151
155- // ignore VERY close timestamps - otherwise we record the initial timestamp twice!
156- if ( click && Math . abs ( click . timestamp - nowInSeconds ( ) ) > 0.01 ) {
157- click . clickCount ++ ;
158- }
152+ click . clickCount ++ ;
159153 }
160154
161155 /** Try to get an existing click on the given element. */
162- private _getClick ( breadcrumb : ClickBreadcrumb ) : Click | undefined {
163- const { nodeId } = breadcrumb . data ;
156+ private _getClick ( node : HTMLElement ) : Click | undefined {
164157 const now = nowInSeconds ( ) ;
165158
166159 // Find any click on the same element in the last second
167160 // If one exists, we consider this click as a double/triple/etc click
168- return this . _clicks . find ( click => click . nodeId === nodeId && now - click . timestamp < this . _multiClickTimeout ) ;
161+ return this . _clicks . find ( click => click . node === node && now - click . timestamp < this . _multiClickTimeout ) ;
169162 }
170163
171164 /** Check the clicks that happened. */
@@ -182,6 +175,13 @@ export class ClickDetector implements ReplayClickDetector {
182175 click . scrollAfter = click . timestamp <= this . _lastScroll ? this . _lastScroll - click . timestamp : undefined ;
183176 }
184177
178+ // If an action happens within the multi click threshold, we can skip waiting and handle the click right away
179+ const actionTime = click . scrollAfter || click . mutationAfter || 0 ;
180+ if ( actionTime && actionTime <= this . _multiClickTimeout ) {
181+ timedOutClicks . push ( click ) ;
182+ return ;
183+ }
184+
185185 if ( click . timestamp + this . _timeout <= now ) {
186186 timedOutClicks . push ( click ) ;
187187 }
@@ -230,7 +230,9 @@ export class ClickDetector implements ReplayClickDetector {
230230 route : replay . getCurrentRoute ( ) ,
231231 timeAfterClickMs,
232232 endReason,
233- clickCount,
233+ // If clickCount === 0, it means multiClick was not correctly captured here
234+ // - we still want to send 1 in this case
235+ clickCount : clickCount || 1 ,
234236 } ,
235237 } ;
236238
0 commit comments