-
-
Notifications
You must be signed in to change notification settings - Fork 358
Expand file tree
/
Copy pathShakeToReportBug.ts
More file actions
87 lines (75 loc) · 2.78 KB
/
ShakeToReportBug.ts
File metadata and controls
87 lines (75 loc) · 2.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
import { debug } from '@sentry/core';
import type { EmitterSubscription, NativeModule } from 'react-native';
import { NativeEventEmitter } from 'react-native';
import { isWeb } from '../utils/environment';
import { getRNSentryModule } from '../wrapper';
export const OnShakeEventName = 'rn_sentry_on_shake';
let _shakeSubscription: EmitterSubscription | null = null;
/**
* Creates a NativeEventEmitter for the given module.
* Can be overridden in tests via the `createEmitter` parameter.
*/
type EmitterFactory = (nativeModule: NativeModule) => NativeEventEmitter;
const defaultEmitterFactory: EmitterFactory = nativeModule => new NativeEventEmitter(nativeModule);
/**
* Starts listening for device shake events and invokes the provided callback when a shake is detected.
*
* This starts native shake detection:
* - iOS: Uses UIKit's motion event detection (no permissions required)
* - Android: Uses the accelerometer sensor (no permissions required)
*/
export function startShakeListener(onShake: () => void, createEmitter: EmitterFactory = defaultEmitterFactory): boolean {
if (_shakeSubscription) {
return false;
}
if (isWeb()) {
debug.warn('Shake detection is not supported on Web.');
return false;
}
const nativeModule = getRNSentryModule() as NativeModule | undefined;
if (!nativeModule) {
debug.warn('Native module is not available. Shake detection will not work.');
return false;
}
try {
const emitter = createEmitter(nativeModule);
_shakeSubscription = emitter.addListener(OnShakeEventName, () => {
onShake();
});
// Explicitly enable native shake detection. On iOS with New Architecture (TurboModules),
// NativeEventEmitter.addListener does not dispatch to native addListener:, so the
// native shake listener would never start without this explicit call.
const module = nativeModule as { enableShakeDetection?: () => void };
if (module.enableShakeDetection) {
module.enableShakeDetection();
} else {
debug.warn('enableShakeDetection is not available on the native module.');
}
return true;
} catch (e) {
debug.warn('Failed to start shake listener:', e);
if (_shakeSubscription) {
_shakeSubscription.remove();
_shakeSubscription = null;
}
return false;
}
}
/**
* Stops listening for device shake events.
*/
export function stopShakeListener(): void {
if (_shakeSubscription) {
_shakeSubscription.remove();
_shakeSubscription = null;
const nativeModule = getRNSentryModule() as { disableShakeDetection?: () => void } | undefined;
nativeModule?.disableShakeDetection?.();
}
}
/**
* Returns whether the shake listener is currently active.
* Exported for testing purposes.
*/
export function isShakeListenerActive(): boolean {
return _shakeSubscription !== null;
}