@dynatrace/react-native-plugin 2.331.1 → 2.335.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +136 -177
- package/android/build.gradle +1 -1
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceRNBridgeImpl.kt +7 -1
- package/android/src/main/java/com/dynatrace/android/agent/DynatraceUtils.kt +1 -0
- package/android/src/new/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +1 -0
- package/android/src/old/java/com/dynatrace/android/agent/DynatraceRNBridge.kt +2 -1
- package/files/plugin-runtime.gradle +27 -13
- package/files/plugin.gradle +1 -1
- package/instrumentation/BabelPluginDynatrace.js +1 -0
- package/instrumentation/DynatraceInstrumentation.js +1 -1
- package/instrumentation/jsx/CreateElement.js +106 -6
- package/instrumentation/jsx/JsxDevRuntime.js +2 -6
- package/instrumentation/jsx/JsxRuntime.js +6 -10
- package/instrumentation/libs/UserInteraction.js +114 -0
- package/instrumentation/libs/community/gesture-handler/Touchables.InstrInfo.js +2 -0
- package/instrumentation/libs/community/gesture-handler/Touchables.js +3 -1
- package/instrumentation/libs/community/gesture-handler/index.js +3 -1
- package/instrumentation/libs/withOnPressMonitoring.js +55 -3
- package/ios/DynatraceRNBridge.mm +8 -1
- package/lib/core/Application.js +2 -0
- package/lib/core/Dynatrace.js +2 -1
- package/lib/core/UserPrivacyOptions.js +8 -1
- package/lib/core/configuration/ConfigurationHandler.js +21 -0
- package/lib/dynatrace-reporter.js +0 -14
- package/lib/dynatrace-transformer.js +10 -13
- package/lib/features/ui-interaction/Config.js +42 -0
- package/lib/features/ui-interaction/IUserInteractionEvent.js +16 -0
- package/lib/features/ui-interaction/Plugin.Fragment.Test.js +170 -0
- package/lib/features/ui-interaction/Plugin.js +289 -0
- package/lib/features/ui-interaction/RootDetection.js +51 -0
- package/lib/features/ui-interaction/RootWrapper.js +236 -0
- package/lib/features/ui-interaction/Run.js +38 -0
- package/lib/features/ui-interaction/Runtime.js +827 -0
- package/lib/features/ui-interaction/TouchMetaResolver.js +492 -0
- package/lib/features/ui-interaction/Types.js +14 -0
- package/lib/next/Dynatrace.js +1 -1
- package/lib/next/configuration/INativeRuntimeConfiguration.js +1 -0
- package/lib/next/configuration/RuntimeConfigurationObserver.js +47 -12
- package/lib/next/events/EventPipeline.js +9 -0
- package/package.json +19 -13
- package/react-native-dynatrace.podspec +1 -1
- package/scripts/Android.js +75 -62
- package/scripts/Config.js +12 -1
- package/scripts/core/InstrumentCall.js +1 -2
- package/scripts/core/LineOffsetAnalyzeCall.js +9 -15
- package/src/lib/core/interface/NativeDynatraceBridge.ts +1 -0
- package/types.d.ts +22 -9
- package/scripts/util/ReactOptions.js +0 -21
|
@@ -0,0 +1,827 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AnalyticsRoot = exports._an_flat = exports.buildUiEventShape = exports.compactify = void 0;
|
|
4
|
+
const React = require("react");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const react_native_1 = require("react-native");
|
|
7
|
+
const EventPipeline_1 = require("../../../lib/next/events/EventPipeline");
|
|
8
|
+
const EventTimestamp_1 = require("../../../lib/next/events/EventTimestamp");
|
|
9
|
+
const ConsoleLogger_1 = require("../../../lib/core/logging/ConsoleLogger");
|
|
10
|
+
const IUserInteractionEvent_1 = require("./IUserInteractionEvent");
|
|
11
|
+
const ConfigurationHandler_1 = require("../../../lib/core/configuration/ConfigurationHandler");
|
|
12
|
+
const RuntimeConfigurationObserver_1 = require("../../../lib/next/configuration/RuntimeConfigurationObserver");
|
|
13
|
+
const TouchMetaResolver_1 = require("./TouchMetaResolver");
|
|
14
|
+
class TimestampProvider {
|
|
15
|
+
constructor() {
|
|
16
|
+
this.getCurrentTimestamp = () => Date.now();
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
const logger = new ConsoleLogger_1.ConsoleLogger('DyntraceUserInteraction');
|
|
20
|
+
function isUiDebugEnabled() {
|
|
21
|
+
return (globalThis
|
|
22
|
+
.__DT_UII_DEBUG === true);
|
|
23
|
+
}
|
|
24
|
+
function uiDebugLog(message, data) {
|
|
25
|
+
if (!isUiDebugEnabled())
|
|
26
|
+
return;
|
|
27
|
+
if (data) {
|
|
28
|
+
console.log(`[DT UI DEBUG] ${message}`, data);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
console.log(`[DT UI DEBUG] ${message}`);
|
|
32
|
+
}
|
|
33
|
+
let LAST_EMIT_KEY = null;
|
|
34
|
+
let LAST_EMIT_TS = 0;
|
|
35
|
+
let LAST_PRESS_ID = null;
|
|
36
|
+
let LAST_PRESS_TS = 0;
|
|
37
|
+
function getDtLastTouch() {
|
|
38
|
+
var _a;
|
|
39
|
+
const g = globalThis;
|
|
40
|
+
(_a = g.__DT_LAST_TOUCH) !== null && _a !== void 0 ? _a : (g.__DT_LAST_TOUCH = { ts: 0, x: 0, y: 0 });
|
|
41
|
+
return g.__DT_LAST_TOUCH;
|
|
42
|
+
}
|
|
43
|
+
function flattenTextChildren(children) {
|
|
44
|
+
if (Array.isArray(children)) {
|
|
45
|
+
return children.map((child) => flattenTextChildren(child)).join('');
|
|
46
|
+
}
|
|
47
|
+
if (children === null || children === undefined || children === false)
|
|
48
|
+
return '';
|
|
49
|
+
return String(children);
|
|
50
|
+
}
|
|
51
|
+
function findRCTTextChild(fiber) {
|
|
52
|
+
let node = fiber === null || fiber === void 0 ? void 0 : fiber.child;
|
|
53
|
+
while (node) {
|
|
54
|
+
if (node.type === 'RCTText') {
|
|
55
|
+
return node;
|
|
56
|
+
}
|
|
57
|
+
const found = findRCTTextChild(node);
|
|
58
|
+
if (found)
|
|
59
|
+
return found;
|
|
60
|
+
node = node.sibling;
|
|
61
|
+
}
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
function getAnyParentMasked(fiber) {
|
|
65
|
+
var _a;
|
|
66
|
+
let cursor = fiber;
|
|
67
|
+
while (cursor) {
|
|
68
|
+
if ((_a = cursor.memoizedProps) === null || _a === void 0 ? void 0 : _a.dtMask)
|
|
69
|
+
return true;
|
|
70
|
+
cursor = cursor.return;
|
|
71
|
+
}
|
|
72
|
+
return false;
|
|
73
|
+
}
|
|
74
|
+
function getHostComponentInfoFromEvent(event, cfg) {
|
|
75
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
76
|
+
let fiber = (_a = event === null || event === void 0 ? void 0 : event._targetInst) !== null && _a !== void 0 ? _a : (_b = event === null || event === void 0 ? void 0 : event.nativeEvent) === null || _b === void 0 ? void 0 : _b._targetInst;
|
|
77
|
+
if (!fiber)
|
|
78
|
+
return undefined;
|
|
79
|
+
const meta = (0, TouchMetaResolver_1.getTouchElementMeta)(event);
|
|
80
|
+
const resolvedPath = (_d = (_c = meta.press) === null || _c === void 0 ? void 0 : _c.appCodeTagPath) !== null && _d !== void 0 ? _d : meta.touch.appCodeTagPath;
|
|
81
|
+
if (!resolvedPath || resolvedPath === 'unknown')
|
|
82
|
+
return undefined;
|
|
83
|
+
const anyParentMasked = getAnyParentMasked(fiber);
|
|
84
|
+
const components = [lastSegment(resolvedPath) || 'Anonymous'];
|
|
85
|
+
const targetIsContainerHost = fiber.type === 'RCTView' ||
|
|
86
|
+
fiber.type === 'View' ||
|
|
87
|
+
fiber.type === 'RCTScrollView' ||
|
|
88
|
+
fiber.type === 'ScrollView';
|
|
89
|
+
if (!targetIsContainerHost && fiber.type !== 'RCTText') {
|
|
90
|
+
fiber = (_e = findRCTTextChild(fiber)) !== null && _e !== void 0 ? _e : fiber;
|
|
91
|
+
}
|
|
92
|
+
const textValue = flattenTextChildren((_f = fiber === null || fiber === void 0 ? void 0 : fiber.memoizedProps) === null || _f === void 0 ? void 0 : _f.children).trim();
|
|
93
|
+
const textMaskedByRule = textValue.length > 0 && ((_h = (_g = cfg === null || cfg === void 0 ? void 0 : cfg.mask) === null || _g === void 0 ? void 0 : _g.text) === null || _h === void 0 ? void 0 : _h.call(_g, textValue)) === true;
|
|
94
|
+
const testId = (_j = fiber === null || fiber === void 0 ? void 0 : fiber.memoizedProps) === null || _j === void 0 ? void 0 : _j.testID;
|
|
95
|
+
const testIdMaskedByRule = typeof testId === 'string' && !!((_l = (_k = cfg === null || cfg === void 0 ? void 0 : cfg.mask) === null || _k === void 0 ? void 0 : _k.testID) === null || _l === void 0 ? void 0 : _l.call(_k, testId));
|
|
96
|
+
const isMasked = anyParentMasked || textMaskedByRule || testIdMaskedByRule;
|
|
97
|
+
if (fiber.type === 'RCTText' && textValue.length > 0) {
|
|
98
|
+
if (isMasked) {
|
|
99
|
+
return {
|
|
100
|
+
id: resolvedPath,
|
|
101
|
+
components,
|
|
102
|
+
detectedName: maskLabel(textValue, cfg),
|
|
103
|
+
nameOrigin: 'masked',
|
|
104
|
+
isMasked: true,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return {
|
|
108
|
+
id: resolvedPath,
|
|
109
|
+
components,
|
|
110
|
+
detectedName: textValue,
|
|
111
|
+
nameOrigin: 'text',
|
|
112
|
+
isMasked: false,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
const detectedName = (_p = (_o = (_m = meta.press) === null || _m === void 0 ? void 0 : _m.elementName) !== null && _o !== void 0 ? _o : meta.touch.elementName) !== null && _p !== void 0 ? _p : 'Anonymous';
|
|
116
|
+
return {
|
|
117
|
+
id: resolvedPath,
|
|
118
|
+
components,
|
|
119
|
+
detectedName,
|
|
120
|
+
nameOrigin: 'component',
|
|
121
|
+
isMasked,
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
function readGlobalPrefix() {
|
|
125
|
+
const globalRuntime = globalThis;
|
|
126
|
+
const globalPrefix = globalRuntime === null || globalRuntime === void 0 ? void 0 : globalRuntime.__AN_PREFIX;
|
|
127
|
+
if (Array.isArray(globalPrefix))
|
|
128
|
+
return globalPrefix;
|
|
129
|
+
if (typeof globalPrefix === 'function') {
|
|
130
|
+
try {
|
|
131
|
+
const resolvedPrefix = globalPrefix();
|
|
132
|
+
if (Array.isArray(resolvedPrefix))
|
|
133
|
+
return resolvedPrefix;
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
const errorMsg = e instanceof Error ? e.stack || e.message : String(e);
|
|
137
|
+
logger.debug(`Failed to resolve global prefix: ${errorMsg}`);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
return [];
|
|
141
|
+
}
|
|
142
|
+
function maskLabel(_s, cfg) {
|
|
143
|
+
var _a, _b;
|
|
144
|
+
return (_b = (_a = cfg === null || cfg === void 0 ? void 0 : cfg.mask) === null || _a === void 0 ? void 0 : _a.replaceWith) !== null && _b !== void 0 ? _b : '***';
|
|
145
|
+
}
|
|
146
|
+
function compactify(cfg, obj) {
|
|
147
|
+
var _a;
|
|
148
|
+
if (!((_a = cfg === null || cfg === void 0 ? void 0 : cfg.touch) === null || _a === void 0 ? void 0 : _a.compact))
|
|
149
|
+
return obj;
|
|
150
|
+
const mapKey = (k) => {
|
|
151
|
+
var _a;
|
|
152
|
+
const keyMap = {
|
|
153
|
+
path: 'p',
|
|
154
|
+
element: 'el',
|
|
155
|
+
isMasked: 'msk',
|
|
156
|
+
position: 'pos',
|
|
157
|
+
meta: 'm',
|
|
158
|
+
sessionId: 'sid',
|
|
159
|
+
touch: 't',
|
|
160
|
+
reason: 'r',
|
|
161
|
+
};
|
|
162
|
+
return (_a = keyMap[k]) !== null && _a !== void 0 ? _a : k;
|
|
163
|
+
};
|
|
164
|
+
const normalizeCompactObject = (compactObject) => {
|
|
165
|
+
var _a, _b;
|
|
166
|
+
if ((_a = compactObject.pos) === null || _a === void 0 ? void 0 : _a.type) {
|
|
167
|
+
compactObject.pos = {
|
|
168
|
+
x: compactObject.pos.x,
|
|
169
|
+
y: compactObject.pos.y,
|
|
170
|
+
t: compactObject.pos.type,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
if ((_b = compactObject.m) === null || _b === void 0 ? void 0 : _b.phase) {
|
|
174
|
+
compactObject.ph = compactObject.m.phase;
|
|
175
|
+
compactObject.ts = compactObject.m.ts;
|
|
176
|
+
delete compactObject.m;
|
|
177
|
+
}
|
|
178
|
+
if (compactObject.t) {
|
|
179
|
+
if (compactObject.t.path !== undefined) {
|
|
180
|
+
compactObject.tp = compactObject.t.path;
|
|
181
|
+
}
|
|
182
|
+
if (compactObject.t.delayMs !== undefined) {
|
|
183
|
+
compactObject.td = compactObject.t.delayMs;
|
|
184
|
+
}
|
|
185
|
+
delete compactObject.t;
|
|
186
|
+
}
|
|
187
|
+
return compactObject;
|
|
188
|
+
};
|
|
189
|
+
const walk = (value) => {
|
|
190
|
+
if (Array.isArray(value))
|
|
191
|
+
return value.map(walk);
|
|
192
|
+
if (!value || typeof value !== 'object')
|
|
193
|
+
return value;
|
|
194
|
+
const compactObject = {};
|
|
195
|
+
for (const key of Object.keys(value)) {
|
|
196
|
+
compactObject[mapKey(key)] = walk(value[key]);
|
|
197
|
+
}
|
|
198
|
+
return normalizeCompactObject(compactObject);
|
|
199
|
+
};
|
|
200
|
+
return walk(obj);
|
|
201
|
+
}
|
|
202
|
+
exports.compactify = compactify;
|
|
203
|
+
function findHostInfoHit(event, cfg) {
|
|
204
|
+
const hostInfo = getHostComponentInfoFromEvent(event, cfg);
|
|
205
|
+
if (!hostInfo)
|
|
206
|
+
return null;
|
|
207
|
+
return {
|
|
208
|
+
path: hostInfo.id,
|
|
209
|
+
element: hostInfo.detectedName,
|
|
210
|
+
isMasked: hostInfo.isMasked,
|
|
211
|
+
name_origin: hostInfo.nameOrigin,
|
|
212
|
+
__dtMatch: 'scan',
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function makeSid() {
|
|
216
|
+
const t = Date.now().toString(36);
|
|
217
|
+
const r = Math.random().toString(36).slice(2, 6);
|
|
218
|
+
return `tch_${t}_${r}`;
|
|
219
|
+
}
|
|
220
|
+
function makePos(ne, cap) {
|
|
221
|
+
if (!ne)
|
|
222
|
+
return undefined;
|
|
223
|
+
if (cap === 'page')
|
|
224
|
+
return {
|
|
225
|
+
x: Number(ne.pageX),
|
|
226
|
+
y: Number(ne.pageY),
|
|
227
|
+
type: 'page',
|
|
228
|
+
};
|
|
229
|
+
if (cap === 'local')
|
|
230
|
+
return {
|
|
231
|
+
x: Number(ne.locationX),
|
|
232
|
+
y: Number(ne.locationY),
|
|
233
|
+
type: 'local',
|
|
234
|
+
};
|
|
235
|
+
if (cap === 'both')
|
|
236
|
+
return {
|
|
237
|
+
x: Number(ne.pageX),
|
|
238
|
+
y: Number(ne.pageY),
|
|
239
|
+
type: 'both',
|
|
240
|
+
};
|
|
241
|
+
return undefined;
|
|
242
|
+
}
|
|
243
|
+
function lastSegment(path) {
|
|
244
|
+
if (!path)
|
|
245
|
+
return '';
|
|
246
|
+
const arrow = path.lastIndexOf('->');
|
|
247
|
+
const slash = path.lastIndexOf('/');
|
|
248
|
+
const i = Math.max(arrow, slash);
|
|
249
|
+
if (i < 0)
|
|
250
|
+
return path;
|
|
251
|
+
const step = i === arrow ? 2 : 1;
|
|
252
|
+
return path.slice(i + step);
|
|
253
|
+
}
|
|
254
|
+
function parseComponent(seg) {
|
|
255
|
+
if (!seg)
|
|
256
|
+
return 'Anonymous';
|
|
257
|
+
const base = seg.split(':', 1)[0];
|
|
258
|
+
const withoutPathId = base.split('#', 1)[0];
|
|
259
|
+
const m = /^([^(]+)(?:\(.*\))?$/.exec(withoutPathId);
|
|
260
|
+
return (m ? m[1] : base) || 'Anonymous';
|
|
261
|
+
}
|
|
262
|
+
function __dt_set_scope_path(path) {
|
|
263
|
+
const g = globalThis;
|
|
264
|
+
g.__DT_UII_SCOPE_PATH = path;
|
|
265
|
+
}
|
|
266
|
+
function __dt_get_scope_path() {
|
|
267
|
+
const g = globalThis;
|
|
268
|
+
const p = g.__DT_UII_SCOPE_PATH;
|
|
269
|
+
return typeof p === 'string' && p.length > 0 ? p : 'App';
|
|
270
|
+
}
|
|
271
|
+
function liftStaticTextHitPath(path) {
|
|
272
|
+
if (!path)
|
|
273
|
+
return path;
|
|
274
|
+
const rx = /\/Text:[^/]+\/Text\([^)]*\)$/;
|
|
275
|
+
if (!rx.test(path))
|
|
276
|
+
return path;
|
|
277
|
+
return path.replace(rx, '');
|
|
278
|
+
}
|
|
279
|
+
function buildUiEventShape(input) {
|
|
280
|
+
var _a;
|
|
281
|
+
const id = input.pressPath || input.touchPath || '';
|
|
282
|
+
const seg = lastSegment(id);
|
|
283
|
+
const comp = parseComponent(seg);
|
|
284
|
+
const detected_name = input.pressElementName || input.touchElementName || comp;
|
|
285
|
+
const base = {
|
|
286
|
+
ui_element: {
|
|
287
|
+
detected_name,
|
|
288
|
+
components: [comp],
|
|
289
|
+
id,
|
|
290
|
+
masked: !!input.touchMasked,
|
|
291
|
+
reason: (_a = input.reason) !== null && _a !== void 0 ? _a : null,
|
|
292
|
+
meta: input.meta,
|
|
293
|
+
name_origin: input.name_origin ||
|
|
294
|
+
(input.touchMasked ? 'masked' : 'component'),
|
|
295
|
+
},
|
|
296
|
+
positions: input.pos ? [{ x: input.pos.x, y: input.pos.y }] : [],
|
|
297
|
+
sessionId: input.sessionId,
|
|
298
|
+
};
|
|
299
|
+
if (input.pressPath) {
|
|
300
|
+
const pressSeg = lastSegment(input.pressPath);
|
|
301
|
+
const pressComp = parseComponent(pressSeg);
|
|
302
|
+
const pressName = input.pressElementName || pressComp;
|
|
303
|
+
base.ui_element.responder = {
|
|
304
|
+
detected_name: pressName,
|
|
305
|
+
components: [pressComp],
|
|
306
|
+
id: input.pressPath,
|
|
307
|
+
name_origin: 'component',
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
return base;
|
|
311
|
+
}
|
|
312
|
+
exports.buildUiEventShape = buildUiEventShape;
|
|
313
|
+
function _an_interaction_type(e) {
|
|
314
|
+
var _a, _b;
|
|
315
|
+
const p = (_b = (_a = e === null || e === void 0 ? void 0 : e.ui_element) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.phase;
|
|
316
|
+
if (!p)
|
|
317
|
+
return null;
|
|
318
|
+
return 'touch';
|
|
319
|
+
}
|
|
320
|
+
function _an_flat(e) {
|
|
321
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r;
|
|
322
|
+
const uiComponents = (_a = e === null || e === void 0 ? void 0 : e.ui_element) === null || _a === void 0 ? void 0 : _a.components;
|
|
323
|
+
let normalizedUiComponents = [];
|
|
324
|
+
if (Array.isArray(uiComponents)) {
|
|
325
|
+
normalizedUiComponents = uiComponents.filter((x) => typeof x === 'string' && x.length > 0);
|
|
326
|
+
}
|
|
327
|
+
else if (uiComponents) {
|
|
328
|
+
normalizedUiComponents =
|
|
329
|
+
typeof uiComponents === 'string' ? [uiComponents] : [];
|
|
330
|
+
}
|
|
331
|
+
const out = {
|
|
332
|
+
[IUserInteractionEvent_1.UserInteractionEventKey.EventHasUserInteraction]: true,
|
|
333
|
+
[IUserInteractionEvent_1.UserInteractionEventKey.UiElementDetectedName]: (_c = (_b = e === null || e === void 0 ? void 0 : e.ui_element) === null || _b === void 0 ? void 0 : _b.detected_name) !== null && _c !== void 0 ? _c : null,
|
|
334
|
+
[IUserInteractionEvent_1.UserInteractionEventKey.UiElementComponents]: normalizedUiComponents,
|
|
335
|
+
[IUserInteractionEvent_1.UserInteractionEventKey.UiElementId]: (_e = (_d = e === null || e === void 0 ? void 0 : e.ui_element) === null || _d === void 0 ? void 0 : _d.id) !== null && _e !== void 0 ? _e : null,
|
|
336
|
+
[IUserInteractionEvent_1.UserInteractionEventKey.InteractionType]: _an_interaction_type(e),
|
|
337
|
+
positions: Array.isArray(e === null || e === void 0 ? void 0 : e.positions)
|
|
338
|
+
? e.positions.map((pos) => ({
|
|
339
|
+
x: Math.trunc(pos.x),
|
|
340
|
+
y: Math.trunc(pos.y),
|
|
341
|
+
}))
|
|
342
|
+
: [],
|
|
343
|
+
};
|
|
344
|
+
const uiComponent = (_f = e === null || e === void 0 ? void 0 : e.ui_element) === null || _f === void 0 ? void 0 : _f.component;
|
|
345
|
+
const uiComponentList = uiComponent === null || uiComponent === undefined
|
|
346
|
+
? null
|
|
347
|
+
: [uiComponent];
|
|
348
|
+
const compsRaw = (_h = (_g = e === null || e === void 0 ? void 0 : e.ui_element) === null || _g === void 0 ? void 0 : _g.components) !== null && _h !== void 0 ? _h : uiComponentList;
|
|
349
|
+
out[IUserInteractionEvent_1.UserInteractionEventKey.UiElementComponents] = Array.isArray(compsRaw)
|
|
350
|
+
? compsRaw.filter((x) => typeof x === 'string' && x.length > 0)
|
|
351
|
+
: [];
|
|
352
|
+
out[IUserInteractionEvent_1.UserInteractionEventKey.UiElementNameOrigin] =
|
|
353
|
+
(_k = (_j = e === null || e === void 0 ? void 0 : e.ui_element) === null || _j === void 0 ? void 0 : _j.name_origin) !== null && _k !== void 0 ? _k : null;
|
|
354
|
+
const responder = (_m = (_l = e === null || e === void 0 ? void 0 : e.ui_element) === null || _l === void 0 ? void 0 : _l.responder) !== null && _m !== void 0 ? _m : null;
|
|
355
|
+
if (responder) {
|
|
356
|
+
out[IUserInteractionEvent_1.UserInteractionEventKey.UiElementResponderDetectedName] =
|
|
357
|
+
(_o = responder.detected_name) !== null && _o !== void 0 ? _o : null;
|
|
358
|
+
const responderComponent = responder.component;
|
|
359
|
+
const responderComponentList = responderComponent === null || responderComponent === undefined
|
|
360
|
+
? null
|
|
361
|
+
: [responderComponent];
|
|
362
|
+
const rCompsRaw = (_p = responder.components) !== null && _p !== void 0 ? _p : responderComponentList;
|
|
363
|
+
out[IUserInteractionEvent_1.UserInteractionEventKey.UiElementResponderComponents] =
|
|
364
|
+
Array.isArray(rCompsRaw)
|
|
365
|
+
? rCompsRaw.filter((x) => typeof x === 'string' && x.length > 0)
|
|
366
|
+
: [];
|
|
367
|
+
out[IUserInteractionEvent_1.UserInteractionEventKey.UiElementResponderId] =
|
|
368
|
+
(_q = responder.id) !== null && _q !== void 0 ? _q : null;
|
|
369
|
+
out[IUserInteractionEvent_1.UserInteractionEventKey.UiElementResponderOriginName] =
|
|
370
|
+
(_r = responder.name_origin) !== null && _r !== void 0 ? _r : null;
|
|
371
|
+
}
|
|
372
|
+
return out;
|
|
373
|
+
}
|
|
374
|
+
exports._an_flat = _an_flat;
|
|
375
|
+
function useTouchManager(cfg, log) {
|
|
376
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
|
|
377
|
+
const mode = (_b = (_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.mode) !== null && _b !== void 0 ? _b : 'grouped';
|
|
378
|
+
const sidRef = React.useRef(null);
|
|
379
|
+
const startXRef = React.useRef(null);
|
|
380
|
+
const startYRef = React.useRef(null);
|
|
381
|
+
const movedRef = React.useRef(false);
|
|
382
|
+
const startTsRef = React.useRef(null);
|
|
383
|
+
const startPathRef = React.useRef(null);
|
|
384
|
+
const threshold = Math.max(1, (_e = (_d = (_c = cfg.touch) === null || _c === void 0 ? void 0 : _c.scroll) === null || _d === void 0 ? void 0 : _d.moveThresholdPx) !== null && _e !== void 0 ? _e : 12);
|
|
385
|
+
const touchRef = React.useRef(null);
|
|
386
|
+
const pressRef = React.useRef(null);
|
|
387
|
+
const timerRef = React.useRef(null);
|
|
388
|
+
const flushedRef = React.useRef(false);
|
|
389
|
+
const clearAll = () => {
|
|
390
|
+
if (timerRef.current) {
|
|
391
|
+
clearTimeout(timerRef.current);
|
|
392
|
+
timerRef.current = null;
|
|
393
|
+
}
|
|
394
|
+
touchRef.current = null;
|
|
395
|
+
pressRef.current = null;
|
|
396
|
+
sidRef.current = null;
|
|
397
|
+
startXRef.current = null;
|
|
398
|
+
startYRef.current = null;
|
|
399
|
+
startTsRef.current = null;
|
|
400
|
+
movedRef.current = false;
|
|
401
|
+
startPathRef.current = null;
|
|
402
|
+
flushedRef.current = false;
|
|
403
|
+
};
|
|
404
|
+
const doFlush = () => {
|
|
405
|
+
if (flushedRef.current) {
|
|
406
|
+
clearAll();
|
|
407
|
+
return;
|
|
408
|
+
}
|
|
409
|
+
const t = touchRef.current;
|
|
410
|
+
const p = pressRef.current;
|
|
411
|
+
let out = null;
|
|
412
|
+
if (t && p) {
|
|
413
|
+
const pos = p.pos || t.pos;
|
|
414
|
+
out = buildUiEventShape({
|
|
415
|
+
touchPath: t.path,
|
|
416
|
+
touchElementName: t.elementName || undefined,
|
|
417
|
+
touchMasked: t.masked,
|
|
418
|
+
pressPath: p.path,
|
|
419
|
+
pressElementName: p.elementName,
|
|
420
|
+
meta: { phase: 'press', ts: Date.now() },
|
|
421
|
+
pos: pos ? { x: pos.x, y: pos.y } : undefined,
|
|
422
|
+
reason: t.reason,
|
|
423
|
+
sessionId: sidRef.current || undefined,
|
|
424
|
+
name_origin: t.name_origin,
|
|
425
|
+
});
|
|
426
|
+
}
|
|
427
|
+
else if (p) {
|
|
428
|
+
out = buildUiEventShape({
|
|
429
|
+
pressPath: p.path,
|
|
430
|
+
pressElementName: p.elementName,
|
|
431
|
+
meta: { phase: 'press', ts: Date.now() },
|
|
432
|
+
pos: p.pos ? { x: p.pos.x, y: p.pos.y } : undefined,
|
|
433
|
+
sessionId: sidRef.current || undefined,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
else if (t) {
|
|
437
|
+
out = buildUiEventShape({
|
|
438
|
+
touchPath: t.path,
|
|
439
|
+
touchElementName: t.elementName || undefined,
|
|
440
|
+
touchMasked: t.masked,
|
|
441
|
+
meta: { phase: 'touch', ts: Date.now() },
|
|
442
|
+
pos: t.pos ? { x: t.pos.x, y: t.pos.y } : undefined,
|
|
443
|
+
reason: t.reason,
|
|
444
|
+
sessionId: sidRef.current || undefined,
|
|
445
|
+
name_origin: t.name_origin,
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
if (out)
|
|
449
|
+
log(compactify(cfg, out));
|
|
450
|
+
flushedRef.current = true;
|
|
451
|
+
clearAll();
|
|
452
|
+
};
|
|
453
|
+
const scheduleFlush = (delay) => {
|
|
454
|
+
if (timerRef.current) {
|
|
455
|
+
clearTimeout(timerRef.current);
|
|
456
|
+
timerRef.current = null;
|
|
457
|
+
}
|
|
458
|
+
timerRef.current = setTimeout(() => doFlush(), delay);
|
|
459
|
+
};
|
|
460
|
+
const resolveTouchHit = (_nativeTarget, event) => {
|
|
461
|
+
const hostHit = findHostInfoHit(event, cfg);
|
|
462
|
+
if (hostHit) {
|
|
463
|
+
uiDebugLog('resolveTouchHit: host hit found', {
|
|
464
|
+
path: hostHit.path,
|
|
465
|
+
element: hostHit.element,
|
|
466
|
+
match: hostHit.__dtMatch,
|
|
467
|
+
});
|
|
468
|
+
return hostHit;
|
|
469
|
+
}
|
|
470
|
+
uiDebugLog('resolveTouchHit: no hit found');
|
|
471
|
+
return null;
|
|
472
|
+
};
|
|
473
|
+
const maybeLiftTouchHit = (hit) => {
|
|
474
|
+
var _a;
|
|
475
|
+
if (!hit || hit.__dtMatch === 'exact') {
|
|
476
|
+
return {
|
|
477
|
+
usePath: (_a = hit === null || hit === void 0 ? void 0 : hit.path) !== null && _a !== void 0 ? _a : null,
|
|
478
|
+
useElement: hit === null || hit === void 0 ? void 0 : hit.element,
|
|
479
|
+
nameOrigin: hit === null || hit === void 0 ? void 0 : hit.name_origin,
|
|
480
|
+
};
|
|
481
|
+
}
|
|
482
|
+
const lifted = liftStaticTextHitPath(hit.path);
|
|
483
|
+
if (lifted && lifted !== hit.path) {
|
|
484
|
+
return {
|
|
485
|
+
usePath: lifted,
|
|
486
|
+
useElement: undefined,
|
|
487
|
+
nameOrigin: 'component',
|
|
488
|
+
};
|
|
489
|
+
}
|
|
490
|
+
return {
|
|
491
|
+
usePath: hit.path,
|
|
492
|
+
useElement: hit.element,
|
|
493
|
+
nameOrigin: hit.name_origin,
|
|
494
|
+
};
|
|
495
|
+
};
|
|
496
|
+
const phaseReason = (phase) => phase === 'cancel' && movedRef.current ? 'moved' : undefined;
|
|
497
|
+
const flushOrSchedule = () => {
|
|
498
|
+
var _a, _b;
|
|
499
|
+
if (pressRef.current)
|
|
500
|
+
doFlush();
|
|
501
|
+
else
|
|
502
|
+
scheduleFlush((_b = (_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.linkWindowMs) !== null && _b !== void 0 ? _b : 250);
|
|
503
|
+
};
|
|
504
|
+
const handleStreamEnd = (event, phase) => {
|
|
505
|
+
var _a, _b;
|
|
506
|
+
const ne = event === null || event === void 0 ? void 0 : event.nativeEvent;
|
|
507
|
+
const hit = resolveTouchHit(ne === null || ne === void 0 ? void 0 : ne.target, event);
|
|
508
|
+
if (!(hit === null || hit === void 0 ? void 0 : hit.path))
|
|
509
|
+
return;
|
|
510
|
+
const lifted = maybeLiftTouchHit(hit);
|
|
511
|
+
const pos = makePos(ne, (_b = (_a = cfg.click) === null || _a === void 0 ? void 0 : _a.capturePosition) !== null && _b !== void 0 ? _b : 'none');
|
|
512
|
+
const out = buildUiEventShape({
|
|
513
|
+
touchPath: lifted.usePath || hit.path,
|
|
514
|
+
touchElementName: lifted.useElement,
|
|
515
|
+
touchMasked: !!hit.isMasked,
|
|
516
|
+
meta: {
|
|
517
|
+
phase: phase === 'cancel' ? 'touch-cancel' : 'touch',
|
|
518
|
+
ts: Date.now(),
|
|
519
|
+
},
|
|
520
|
+
pos: pos ? { x: pos.x, y: pos.y } : undefined,
|
|
521
|
+
reason: phaseReason(phase),
|
|
522
|
+
sessionId: sidRef.current || undefined,
|
|
523
|
+
name_origin: lifted.nameOrigin,
|
|
524
|
+
});
|
|
525
|
+
log(compactify(cfg, out));
|
|
526
|
+
clearAll();
|
|
527
|
+
};
|
|
528
|
+
const onStart = React.useCallback((e) => {
|
|
529
|
+
var _a, _b, _c, _d, _e;
|
|
530
|
+
if (!((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled))
|
|
531
|
+
return;
|
|
532
|
+
const ne = e === null || e === void 0 ? void 0 : e.nativeEvent;
|
|
533
|
+
const hit = resolveTouchHit(ne === null || ne === void 0 ? void 0 : ne.target, e);
|
|
534
|
+
uiDebugLog('onStart', {
|
|
535
|
+
hasHit: !!(hit === null || hit === void 0 ? void 0 : hit.path),
|
|
536
|
+
targetType: typeof (ne === null || ne === void 0 ? void 0 : ne.target),
|
|
537
|
+
pageX: Number(ne === null || ne === void 0 ? void 0 : ne.pageX) || 0,
|
|
538
|
+
pageY: Number(ne === null || ne === void 0 ? void 0 : ne.pageY) || 0,
|
|
539
|
+
mode,
|
|
540
|
+
});
|
|
541
|
+
if (!(hit === null || hit === void 0 ? void 0 : hit.path)) {
|
|
542
|
+
clearAll();
|
|
543
|
+
sidRef.current = makeSid();
|
|
544
|
+
startTsRef.current = Date.now();
|
|
545
|
+
startXRef.current = Number(ne === null || ne === void 0 ? void 0 : ne.pageX) || 0;
|
|
546
|
+
startYRef.current = Number(ne === null || ne === void 0 ? void 0 : ne.pageY) || 0;
|
|
547
|
+
movedRef.current = false;
|
|
548
|
+
startPathRef.current = __dt_get_scope_path();
|
|
549
|
+
if (mode === 'stream') {
|
|
550
|
+
const pos = makePos(ne, (_c = (_b = cfg.click) === null || _b === void 0 ? void 0 : _b.capturePosition) !== null && _c !== void 0 ? _c : 'none');
|
|
551
|
+
const out = buildUiEventShape({
|
|
552
|
+
touchPath: startPathRef.current,
|
|
553
|
+
meta: { phase: 'touch-start', ts: Date.now() },
|
|
554
|
+
pos: pos ? { x: pos.x, y: pos.y } : undefined,
|
|
555
|
+
sessionId: sidRef.current || undefined,
|
|
556
|
+
});
|
|
557
|
+
log(compactify(cfg, out));
|
|
558
|
+
}
|
|
559
|
+
return;
|
|
560
|
+
}
|
|
561
|
+
clearAll();
|
|
562
|
+
startPathRef.current = hit.path;
|
|
563
|
+
sidRef.current = makeSid();
|
|
564
|
+
startTsRef.current = Date.now();
|
|
565
|
+
startXRef.current = Number(ne === null || ne === void 0 ? void 0 : ne.pageX) || 0;
|
|
566
|
+
startYRef.current = Number(ne === null || ne === void 0 ? void 0 : ne.pageY) || 0;
|
|
567
|
+
movedRef.current = false;
|
|
568
|
+
if (mode === 'stream') {
|
|
569
|
+
const pos = makePos(ne, (_e = (_d = cfg.click) === null || _d === void 0 ? void 0 : _d.capturePosition) !== null && _e !== void 0 ? _e : 'none');
|
|
570
|
+
const out = buildUiEventShape({
|
|
571
|
+
touchPath: hit.path,
|
|
572
|
+
touchElementName: hit.element || undefined,
|
|
573
|
+
touchMasked: !!hit.isMasked,
|
|
574
|
+
meta: { phase: 'touch-start', ts: Date.now() },
|
|
575
|
+
pos: pos ? { x: pos.x, y: pos.y } : undefined,
|
|
576
|
+
sessionId: sidRef.current || undefined,
|
|
577
|
+
name_origin: hit.name_origin,
|
|
578
|
+
});
|
|
579
|
+
log(compactify(cfg, out));
|
|
580
|
+
}
|
|
581
|
+
}, [(_f = cfg.touch) === null || _f === void 0 ? void 0 : _f.enabled, (_g = cfg.click) === null || _g === void 0 ? void 0 : _g.capturePosition, mode]);
|
|
582
|
+
const onMove = React.useCallback((e) => {
|
|
583
|
+
var _a, _b, _c;
|
|
584
|
+
if (!((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled))
|
|
585
|
+
return;
|
|
586
|
+
if (movedRef.current)
|
|
587
|
+
return;
|
|
588
|
+
const ne = e === null || e === void 0 ? void 0 : e.nativeEvent;
|
|
589
|
+
const x = Number(ne === null || ne === void 0 ? void 0 : ne.pageX) || 0;
|
|
590
|
+
const y = Number(ne === null || ne === void 0 ? void 0 : ne.pageY) || 0;
|
|
591
|
+
const sx = (_b = startXRef.current) !== null && _b !== void 0 ? _b : x;
|
|
592
|
+
const sy = (_c = startYRef.current) !== null && _c !== void 0 ? _c : y;
|
|
593
|
+
const dx = x - sx;
|
|
594
|
+
const dy = y - sy;
|
|
595
|
+
if (dx * dx + dy * dy >= threshold * threshold)
|
|
596
|
+
movedRef.current = true;
|
|
597
|
+
}, [(_h = cfg.touch) === null || _h === void 0 ? void 0 : _h.enabled, threshold]);
|
|
598
|
+
const onEnd = React.useCallback((e, phase) => {
|
|
599
|
+
var _a, _b, _c;
|
|
600
|
+
if (!((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled))
|
|
601
|
+
return;
|
|
602
|
+
const ne = e === null || e === void 0 ? void 0 : e.nativeEvent;
|
|
603
|
+
if (mode === 'stream') {
|
|
604
|
+
handleStreamEnd(e, phase);
|
|
605
|
+
return;
|
|
606
|
+
}
|
|
607
|
+
const pos = makePos(ne, (_c = (_b = cfg.click) === null || _b === void 0 ? void 0 : _b.capturePosition) !== null && _c !== void 0 ? _c : 'none');
|
|
608
|
+
const hitRaw = resolveTouchHit(ne === null || ne === void 0 ? void 0 : ne.target, e);
|
|
609
|
+
const now = Date.now();
|
|
610
|
+
const lifted = maybeLiftTouchHit(hitRaw);
|
|
611
|
+
const usePath = lifted.usePath;
|
|
612
|
+
const useEl = lifted.useElement || '';
|
|
613
|
+
uiDebugLog('onEnd', {
|
|
614
|
+
phase,
|
|
615
|
+
hasHit: !!(hitRaw === null || hitRaw === void 0 ? void 0 : hitRaw.path),
|
|
616
|
+
usePath: usePath || null,
|
|
617
|
+
useElement: useEl || null,
|
|
618
|
+
mode,
|
|
619
|
+
});
|
|
620
|
+
if (!usePath) {
|
|
621
|
+
const scopePath = startPathRef.current || __dt_get_scope_path();
|
|
622
|
+
touchRef.current = {
|
|
623
|
+
path: scopePath,
|
|
624
|
+
elementName: '',
|
|
625
|
+
masked: false,
|
|
626
|
+
name_origin: 'component',
|
|
627
|
+
pos: pos ? { x: pos.x, y: pos.y } : undefined,
|
|
628
|
+
reason: 'unmapped',
|
|
629
|
+
ts: now,
|
|
630
|
+
};
|
|
631
|
+
flushOrSchedule();
|
|
632
|
+
return;
|
|
633
|
+
}
|
|
634
|
+
touchRef.current = {
|
|
635
|
+
path: usePath,
|
|
636
|
+
elementName: useEl,
|
|
637
|
+
masked: !!(hitRaw === null || hitRaw === void 0 ? void 0 : hitRaw.isMasked),
|
|
638
|
+
name_origin: lifted.nameOrigin,
|
|
639
|
+
pos: pos ? { x: pos.x, y: pos.y } : undefined,
|
|
640
|
+
reason: phaseReason(phase),
|
|
641
|
+
ts: now,
|
|
642
|
+
};
|
|
643
|
+
flushOrSchedule();
|
|
644
|
+
}, [
|
|
645
|
+
(_j = cfg.touch) === null || _j === void 0 ? void 0 : _j.enabled,
|
|
646
|
+
(_k = cfg.click) === null || _k === void 0 ? void 0 : _k.capturePosition,
|
|
647
|
+
(_l = cfg.touch) === null || _l === void 0 ? void 0 : _l.linkWindowMs,
|
|
648
|
+
mode,
|
|
649
|
+
]);
|
|
650
|
+
const registerPress = React.useCallback((info) => {
|
|
651
|
+
var _a, _b, _c;
|
|
652
|
+
if (!((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled))
|
|
653
|
+
return;
|
|
654
|
+
const now = Date.now();
|
|
655
|
+
uiDebugLog('registerPress', {
|
|
656
|
+
path: info.path,
|
|
657
|
+
elementName: info.elementName,
|
|
658
|
+
hasPos: !!info.pos,
|
|
659
|
+
mode,
|
|
660
|
+
});
|
|
661
|
+
if (mode === 'stream') {
|
|
662
|
+
const out = buildUiEventShape({
|
|
663
|
+
pressPath: info.path,
|
|
664
|
+
pressElementName: info.elementName,
|
|
665
|
+
meta: { phase: 'press', ts: now },
|
|
666
|
+
name_origin: 'component',
|
|
667
|
+
pos: info.pos
|
|
668
|
+
? { x: info.pos.x, y: info.pos.y }
|
|
669
|
+
: undefined,
|
|
670
|
+
sessionId: sidRef.current || undefined,
|
|
671
|
+
});
|
|
672
|
+
log(compactify(cfg, out));
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
pressRef.current = {
|
|
676
|
+
path: info.path,
|
|
677
|
+
elementName: info.elementName,
|
|
678
|
+
pos: info.pos ? { x: info.pos.x, y: info.pos.y } : undefined,
|
|
679
|
+
ts: now,
|
|
680
|
+
};
|
|
681
|
+
if (touchRef.current)
|
|
682
|
+
doFlush();
|
|
683
|
+
else
|
|
684
|
+
scheduleFlush((_c = (_b = cfg.touch) === null || _b === void 0 ? void 0 : _b.linkWindowMs) !== null && _c !== void 0 ? _c : 250);
|
|
685
|
+
}, [(_m = cfg.touch) === null || _m === void 0 ? void 0 : _m.enabled, (_o = cfg.touch) === null || _o === void 0 ? void 0 : _o.linkWindowMs, mode]);
|
|
686
|
+
return {
|
|
687
|
+
onStart,
|
|
688
|
+
onMove,
|
|
689
|
+
onEnd,
|
|
690
|
+
getSessionId: React.useCallback(() => sidRef.current, []),
|
|
691
|
+
getTouchPath: React.useCallback(() => { var _a, _b; return (_b = (_a = touchRef.current) === null || _a === void 0 ? void 0 : _a.path) !== null && _b !== void 0 ? _b : null; }, []),
|
|
692
|
+
getStartTs: React.useCallback(() => startTsRef.current, []),
|
|
693
|
+
getStartPath: React.useCallback(() => startPathRef.current, []),
|
|
694
|
+
registerPress,
|
|
695
|
+
};
|
|
696
|
+
}
|
|
697
|
+
function TouchCapture({ children, cfg, mgr, }) {
|
|
698
|
+
var _a, _b;
|
|
699
|
+
const last = getDtLastTouch();
|
|
700
|
+
const onStart = React.useCallback((e) => {
|
|
701
|
+
var _a, _b;
|
|
702
|
+
last.ts = Date.now();
|
|
703
|
+
last.x = Number((_a = e === null || e === void 0 ? void 0 : e.nativeEvent) === null || _a === void 0 ? void 0 : _a.pageX) || 0;
|
|
704
|
+
last.y = Number((_b = e === null || e === void 0 ? void 0 : e.nativeEvent) === null || _b === void 0 ? void 0 : _b.pageY) || 0;
|
|
705
|
+
return mgr === null || mgr === void 0 ? void 0 : mgr.onStart(e);
|
|
706
|
+
}, [mgr]);
|
|
707
|
+
const onMove = React.useCallback((e) => mgr === null || mgr === void 0 ? void 0 : mgr.onMove(e), [mgr]);
|
|
708
|
+
const onEnd = React.useCallback((e) => {
|
|
709
|
+
return mgr === null || mgr === void 0 ? void 0 : mgr.onEnd(e, 'end');
|
|
710
|
+
}, [mgr]);
|
|
711
|
+
const onCancel = React.useCallback((e) => {
|
|
712
|
+
return mgr === null || mgr === void 0 ? void 0 : mgr.onEnd(e, 'cancel');
|
|
713
|
+
}, [mgr]);
|
|
714
|
+
if (!ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled() ||
|
|
715
|
+
!((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled) ||
|
|
716
|
+
!mgr) {
|
|
717
|
+
uiDebugLog('TouchCapture bypassed', {
|
|
718
|
+
uiEnabled: ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled(),
|
|
719
|
+
touchEnabled: !!((_b = cfg.touch) === null || _b === void 0 ? void 0 : _b.enabled),
|
|
720
|
+
hasManager: !!mgr,
|
|
721
|
+
});
|
|
722
|
+
return React.createElement(React.Fragment, null, children);
|
|
723
|
+
}
|
|
724
|
+
return (React.createElement(react_native_1.View, { pointerEvents: "box-none", collapsable: false, style: { flex: 1 }, onTouchStart: onStart, onTouchMove: onMove, onTouchEnd: onEnd, onTouchCancel: onCancel, onResponderRelease: onEnd, onResponderTerminate: onCancel }, children));
|
|
725
|
+
}
|
|
726
|
+
function AnalyticsRoot({ name = 'App', label, log, prefix, config, children, }) {
|
|
727
|
+
var _a, _b, _c, _d, _e;
|
|
728
|
+
const cfg = (0, react_1.useMemo)(() => config !== null && config !== void 0 ? config : {}, [config]);
|
|
729
|
+
const fileConfiguredUiEnabled = ((_a = cfg === null || cfg === void 0 ? void 0 : cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled) === true;
|
|
730
|
+
const baseLogger = log || ((e) => logger.debug('[DT UI]' + JSON.stringify(e)));
|
|
731
|
+
React.useEffect(() => {
|
|
732
|
+
ConfigurationHandler_1.ConfigurationHandler.setUserInteractionEnabledLastKnownGood(fileConfiguredUiEnabled);
|
|
733
|
+
uiDebugLog('AnalyticsRoot initialized fallback from config', {
|
|
734
|
+
fileConfiguredUiEnabled,
|
|
735
|
+
userInteractionEnabled: ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled(),
|
|
736
|
+
});
|
|
737
|
+
}, [fileConfiguredUiEnabled]);
|
|
738
|
+
const emit = React.useCallback((e) => {
|
|
739
|
+
var _a, _b, _c, _d;
|
|
740
|
+
const uiEnabled = ConfigurationHandler_1.ConfigurationHandler.isUserInteractionEnabled();
|
|
741
|
+
if (!uiEnabled) {
|
|
742
|
+
const isInitiated = RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.isInitiated();
|
|
743
|
+
const remoteCfg = isInitiated
|
|
744
|
+
? RuntimeConfigurationObserver_1.RuntimeConfigurationObserver.getCurrentRuntimeConfiguration()
|
|
745
|
+
: undefined;
|
|
746
|
+
uiDebugLog('emit skipped: user interaction disabled', {
|
|
747
|
+
isRuntimeConfigInitiated: isInitiated,
|
|
748
|
+
remoteValue: remoteCfg === null || remoteCfg === void 0 ? void 0 : remoteCfg.touch_interaction_enabled,
|
|
749
|
+
});
|
|
750
|
+
return;
|
|
751
|
+
}
|
|
752
|
+
const phase = ((_b = (_a = e === null || e === void 0 ? void 0 : e.ui_element) === null || _a === void 0 ? void 0 : _a.meta) === null || _b === void 0 ? void 0 : _b.phase) || '';
|
|
753
|
+
const id = ((_c = e === null || e === void 0 ? void 0 : e.ui_element) === null || _c === void 0 ? void 0 : _c.id) || '';
|
|
754
|
+
const now = Date.now();
|
|
755
|
+
if (phase === 'touch' &&
|
|
756
|
+
LAST_PRESS_ID &&
|
|
757
|
+
id &&
|
|
758
|
+
id === LAST_PRESS_ID &&
|
|
759
|
+
now - LAST_PRESS_TS < 300) {
|
|
760
|
+
uiDebugLog('emit skipped: touch dedup after press', {
|
|
761
|
+
id,
|
|
762
|
+
deltaMs: now - LAST_PRESS_TS,
|
|
763
|
+
});
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
const key = id && phase ? id + '|' + phase : '';
|
|
767
|
+
if (key && key === LAST_EMIT_KEY && now - LAST_EMIT_TS < 10) {
|
|
768
|
+
uiDebugLog('emit skipped: duplicate key window', {
|
|
769
|
+
key,
|
|
770
|
+
deltaMs: now - LAST_EMIT_TS,
|
|
771
|
+
});
|
|
772
|
+
return;
|
|
773
|
+
}
|
|
774
|
+
LAST_EMIT_KEY = key;
|
|
775
|
+
LAST_EMIT_TS = now;
|
|
776
|
+
if (phase === 'press' && id) {
|
|
777
|
+
LAST_PRESS_ID = id;
|
|
778
|
+
LAST_PRESS_TS = now;
|
|
779
|
+
}
|
|
780
|
+
const eventTimestamp = new EventTimestamp_1.EventTimestamp(new TimestampProvider());
|
|
781
|
+
const produceEvent = _an_flat(e);
|
|
782
|
+
const event = Object.assign(Object.assign({}, produceEvent), eventTimestamp.getEventTimeInfo());
|
|
783
|
+
EventPipeline_1.EventPipeline.insertEvent(event);
|
|
784
|
+
uiDebugLog('emit inserted event', {
|
|
785
|
+
phase,
|
|
786
|
+
id,
|
|
787
|
+
hasResponder: !!((_d = e === null || e === void 0 ? void 0 : e.ui_element) === null || _d === void 0 ? void 0 : _d.responder),
|
|
788
|
+
});
|
|
789
|
+
return baseLogger(produceEvent);
|
|
790
|
+
}, [baseLogger]);
|
|
791
|
+
const touch = useTouchManager(cfg, emit);
|
|
792
|
+
React.useEffect(() => {
|
|
793
|
+
var _a, _b, _c;
|
|
794
|
+
const g = globalThis;
|
|
795
|
+
g.__DT_UII_BRIDGE = {
|
|
796
|
+
registerPress: touch.registerPress,
|
|
797
|
+
getStartPath: touch.getStartPath,
|
|
798
|
+
};
|
|
799
|
+
uiDebugLog('AnalyticsRoot mounted: bridge registered', {
|
|
800
|
+
touchEnabled: !!((_a = cfg.touch) === null || _a === void 0 ? void 0 : _a.enabled),
|
|
801
|
+
mode: (_c = (_b = cfg.touch) === null || _b === void 0 ? void 0 : _b.mode) !== null && _c !== void 0 ? _c : 'grouped',
|
|
802
|
+
});
|
|
803
|
+
return () => {
|
|
804
|
+
var _a;
|
|
805
|
+
if (((_a = g.__DT_UII_BRIDGE) === null || _a === void 0 ? void 0 : _a.registerPress) === touch.registerPress) {
|
|
806
|
+
delete g.__DT_UII_BRIDGE;
|
|
807
|
+
uiDebugLog('AnalyticsRoot unmounted: bridge removed');
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
}, [touch, (_b = cfg.touch) === null || _b === void 0 ? void 0 : _b.enabled, (_c = cfg.touch) === null || _c === void 0 ? void 0 : _c.mode]);
|
|
811
|
+
const pref = Array.isArray(prefix) ? prefix : readGlobalPrefix();
|
|
812
|
+
const scopePath = React.useMemo(() => {
|
|
813
|
+
var _a, _b;
|
|
814
|
+
const names = [
|
|
815
|
+
...pref
|
|
816
|
+
.map((p) => p === null || p === void 0 ? void 0 : p.name)
|
|
817
|
+
.filter((n) => typeof n === 'string' && n.length > 0),
|
|
818
|
+
name,
|
|
819
|
+
];
|
|
820
|
+
return names.join((_b = (_a = config === null || config === void 0 ? void 0 : config.path) === null || _a === void 0 ? void 0 : _a.separator) !== null && _b !== void 0 ? _b : '/');
|
|
821
|
+
}, [pref, name, (_d = config === null || config === void 0 ? void 0 : config.path) === null || _d === void 0 ? void 0 : _d.separator]);
|
|
822
|
+
React.useEffect(() => {
|
|
823
|
+
__dt_set_scope_path(scopePath);
|
|
824
|
+
}, [scopePath]);
|
|
825
|
+
return ((_e = cfg === null || cfg === void 0 ? void 0 : cfg.touch) === null || _e === void 0 ? void 0 : _e.enabled) ? (React.createElement(TouchCapture, { cfg: cfg, mgr: touch }, children)) : (React.createElement(React.Fragment, null, children));
|
|
826
|
+
}
|
|
827
|
+
exports.AnalyticsRoot = AnalyticsRoot;
|