@@ -7,12 +7,10 @@ import { getClickTargetNode } from './util/domUtils';
7
7
8
8
type ClickBreadcrumb = Breadcrumb & {
9
9
timestamp : number ;
10
- data : { nodeId : number } ;
11
10
} ;
12
11
13
12
interface Click {
14
13
timestamp : number ;
15
- nodeId : number ;
16
14
mutationAfter ?: number ;
17
15
scrollAfter ?: number ;
18
16
clickBreadcrumb : ClickBreadcrumb ;
@@ -121,7 +119,7 @@ export class ClickDetector implements ReplayClickDetector {
121
119
return ;
122
120
}
123
121
124
- const click = this . _getClick ( breadcrumb ) ;
122
+ const click = this . _getClick ( node ) ;
125
123
126
124
if ( click ) {
127
125
// 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 {
130
128
131
129
const newClick : Click = {
132
130
timestamp : breadcrumb . timestamp ,
133
- nodeId : breadcrumb . data . nodeId ,
134
131
clickBreadcrumb : breadcrumb ,
135
- clickCount : 1 ,
132
+ // Set this to 0 so we know it originates from the click breadcrumb
133
+ clickCount : 0 ,
136
134
node,
137
135
} ;
138
136
this . _clicks . push ( newClick ) ;
@@ -145,27 +143,22 @@ export class ClickDetector implements ReplayClickDetector {
145
143
146
144
/** Count multiple clicks on elements. */
147
145
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 ) ;
150
147
151
148
if ( ! click ) {
152
149
return ;
153
150
}
154
151
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 ++ ;
159
153
}
160
154
161
155
/** 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 {
164
157
const now = nowInSeconds ( ) ;
165
158
166
159
// Find any click on the same element in the last second
167
160
// 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 ) ;
169
162
}
170
163
171
164
/** Check the clicks that happened. */
@@ -182,6 +175,13 @@ export class ClickDetector implements ReplayClickDetector {
182
175
click . scrollAfter = click . timestamp <= this . _lastScroll ? this . _lastScroll - click . timestamp : undefined ;
183
176
}
184
177
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
+
185
185
if ( click . timestamp + this . _timeout <= now ) {
186
186
timedOutClicks . push ( click ) ;
187
187
}
@@ -230,7 +230,9 @@ export class ClickDetector implements ReplayClickDetector {
230
230
route : replay . getCurrentRoute ( ) ,
231
231
timeAfterClickMs,
232
232
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 ,
234
236
} ,
235
237
} ;
236
238
0 commit comments