@solucx/react-native-solucx-widget 0.2.5 → 2.0.7
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 +526 -182
- package/lib/SoluCXWidget.d.ts +50 -7
- package/lib/SoluCXWidget.d.ts.map +1 -1
- package/lib/SoluCXWidget.js +105 -101
- package/lib/SoluCXWidget.js.map +1 -1
- package/lib/SoluCXWidgetHost.d.ts +3 -0
- package/lib/SoluCXWidgetHost.d.ts.map +1 -0
- package/lib/SoluCXWidgetHost.js +34 -0
- package/lib/SoluCXWidgetHost.js.map +1 -0
- package/lib/SoluCXWidgetView.d.ts +12 -0
- package/lib/SoluCXWidgetView.d.ts.map +1 -0
- package/lib/SoluCXWidgetView.js +61 -0
- package/lib/SoluCXWidgetView.js.map +1 -0
- package/lib/components/CloseButton.d.ts +1 -1
- package/lib/components/CloseButton.d.ts.map +1 -1
- package/lib/components/CloseButton.js +4 -1
- package/lib/components/CloseButton.js.map +1 -1
- package/lib/components/InlineWidget.d.ts.map +1 -1
- package/lib/components/InlineWidget.js +2 -7
- package/lib/components/InlineWidget.js.map +1 -1
- package/lib/components/ModalWidget.d.ts +1 -1
- package/lib/components/ModalWidget.d.ts.map +1 -1
- package/lib/components/ModalWidget.js +3 -16
- package/lib/components/ModalWidget.js.map +1 -1
- package/lib/components/OverlayWidget.d.ts.map +1 -1
- package/lib/components/OverlayWidget.js +5 -15
- package/lib/components/OverlayWidget.js.map +1 -1
- package/lib/components/index.d.ts +5 -0
- package/lib/components/index.d.ts.map +1 -0
- package/lib/components/index.js +12 -0
- package/lib/components/index.js.map +1 -0
- package/lib/constants/Constants.d.ts +11 -0
- package/lib/constants/Constants.d.ts.map +1 -1
- package/lib/constants/Constants.js +16 -1
- package/lib/constants/Constants.js.map +1 -1
- package/lib/{interfaces → domain}/WidgetCallbacks.d.ts +2 -2
- package/lib/domain/WidgetCallbacks.d.ts.map +1 -0
- package/lib/domain/WidgetCallbacks.js.map +1 -0
- package/{src/interfaces/WidgetData.ts → lib/domain/WidgetData.d.ts} +5 -2
- package/lib/domain/WidgetData.d.ts.map +1 -0
- package/lib/{interfaces → domain}/WidgetData.js.map +1 -1
- package/lib/domain/WidgetDisplayResult.d.ts +6 -0
- package/lib/domain/WidgetDisplayResult.d.ts.map +1 -0
- package/lib/domain/WidgetDisplayResult.js +3 -0
- package/lib/domain/WidgetDisplayResult.js.map +1 -0
- package/lib/domain/WidgetOptions.d.ts +27 -0
- package/lib/domain/WidgetOptions.d.ts.map +1 -0
- package/lib/domain/WidgetOptions.js +30 -0
- package/lib/domain/WidgetOptions.js.map +1 -0
- package/lib/domain/WidgetResponse.d.ts +5 -0
- package/lib/domain/WidgetResponse.d.ts.map +1 -0
- package/lib/{interfaces/WidgetOptions.js → domain/WidgetResponse.js} +1 -1
- package/lib/domain/WidgetResponse.js.map +1 -0
- package/lib/domain/WidgetSamplerLog.d.ts +12 -0
- package/lib/domain/WidgetSamplerLog.d.ts.map +1 -0
- package/lib/domain/WidgetSamplerLog.js.map +1 -0
- package/lib/{interfaces → domain}/index.d.ts +1 -2
- package/lib/domain/index.d.ts.map +1 -0
- package/lib/{interfaces → domain}/index.js.map +1 -1
- package/lib/hooks/index.d.ts +2 -2
- package/lib/hooks/index.d.ts.map +1 -1
- package/lib/hooks/index.js +5 -5
- package/lib/hooks/index.js.map +1 -1
- package/lib/hooks/useClientVersionCollector.d.ts +3 -0
- package/lib/hooks/useClientVersionCollector.d.ts.map +1 -0
- package/lib/{services/ClientVersionCollector.js → hooks/useClientVersionCollector.js} +7 -2
- package/lib/hooks/useClientVersionCollector.js.map +1 -0
- package/lib/hooks/useHeightAnimation.d.ts +0 -1
- package/lib/hooks/useHeightAnimation.d.ts.map +1 -1
- package/lib/hooks/useHeightAnimation.js +4 -2
- package/lib/hooks/useHeightAnimation.js.map +1 -1
- package/lib/hooks/useWidget.d.ts +13 -0
- package/lib/hooks/useWidget.d.ts.map +1 -0
- package/lib/hooks/useWidget.js +44 -0
- package/lib/hooks/useWidget.js.map +1 -0
- package/lib/hooks/useWidgetBootstrap.d.ts +21 -0
- package/lib/hooks/useWidgetBootstrap.d.ts.map +1 -0
- package/lib/hooks/useWidgetBootstrap.js +87 -0
- package/lib/hooks/useWidgetBootstrap.js.map +1 -0
- package/lib/hooks/useWidgetServices.d.ts +19 -0
- package/lib/hooks/useWidgetServices.d.ts.map +1 -0
- package/lib/hooks/useWidgetServices.js +34 -0
- package/lib/hooks/useWidgetServices.js.map +1 -0
- package/lib/hooks/useWidgetUI.d.ts +9 -0
- package/lib/hooks/useWidgetUI.d.ts.map +1 -0
- package/lib/hooks/useWidgetUI.js +33 -0
- package/lib/hooks/useWidgetUI.js.map +1 -0
- package/lib/index.d.ts +10 -11
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +13 -38
- package/lib/index.js.map +1 -1
- package/lib/services/UserIdentificationService.d.ts +3 -0
- package/lib/services/UserIdentificationService.d.ts.map +1 -0
- package/lib/services/UserIdentificationService.js +17 -0
- package/lib/services/UserIdentificationService.js.map +1 -0
- package/lib/services/WidgetBootstrapService.d.ts +12 -0
- package/lib/services/WidgetBootstrapService.d.ts.map +1 -0
- package/lib/services/{widgetBootstrapService.js → WidgetBootstrapService.js} +36 -15
- package/lib/services/WidgetBootstrapService.js.map +1 -0
- package/lib/services/WidgetEventService.d.ts +8 -0
- package/lib/services/WidgetEventService.d.ts.map +1 -0
- package/lib/services/WidgetEventService.js +14 -0
- package/lib/services/WidgetEventService.js.map +1 -0
- package/lib/services/WidgetStateManager.d.ts +20 -0
- package/lib/services/WidgetStateManager.d.ts.map +1 -0
- package/lib/services/WidgetStateManager.js +93 -0
- package/lib/services/WidgetStateManager.js.map +1 -0
- package/lib/services/WidgetValidationService.d.ts +17 -0
- package/lib/services/WidgetValidationService.d.ts.map +1 -0
- package/lib/services/WidgetValidationService.js +132 -0
- package/lib/services/WidgetValidationService.js.map +1 -0
- package/lib/services/events/EventHandlerFactory.d.ts +18 -0
- package/lib/services/events/EventHandlerFactory.d.ts.map +1 -0
- package/lib/services/events/EventHandlerFactory.js +67 -0
- package/lib/services/events/EventHandlerFactory.js.map +1 -0
- package/lib/services/events/EventHandlers.d.ts +10 -0
- package/lib/services/events/EventHandlers.d.ts.map +1 -0
- package/lib/services/events/EventHandlers.js +72 -0
- package/lib/services/events/EventHandlers.js.map +1 -0
- package/lib/services/events/index.d.ts +3 -0
- package/lib/services/events/index.d.ts.map +1 -0
- package/lib/services/events/index.js +21 -0
- package/lib/services/events/index.js.map +1 -0
- package/lib/services/height/HeightStrategies.d.ts +3 -0
- package/lib/services/height/HeightStrategies.d.ts.map +1 -0
- package/lib/services/height/HeightStrategies.js +14 -0
- package/lib/services/height/HeightStrategies.js.map +1 -0
- package/lib/services/storage/AsyncStorageService.d.ts +13 -0
- package/lib/services/storage/AsyncStorageService.d.ts.map +1 -0
- package/lib/services/storage/AsyncStorageService.js +73 -0
- package/lib/services/storage/AsyncStorageService.js.map +1 -0
- package/lib/services/storage/IStorageService.d.ts +30 -0
- package/lib/services/storage/IStorageService.d.ts.map +1 -0
- package/lib/services/storage/IStorageService.js +3 -0
- package/lib/services/storage/IStorageService.js.map +1 -0
- package/lib/services/storage/StorageIdBuilder.d.ts +11 -0
- package/lib/services/storage/StorageIdBuilder.d.ts.map +1 -0
- package/lib/services/storage/StorageIdBuilder.js +17 -0
- package/lib/services/storage/StorageIdBuilder.js.map +1 -0
- package/lib/services/storage/index.d.ts +3 -0
- package/lib/services/storage/index.d.ts.map +1 -0
- package/lib/services/storage/index.js +6 -0
- package/lib/services/storage/index.js.map +1 -0
- package/lib/styles/widgetStyles.d.ts +1 -1
- package/lib/styles/widgetStyles.d.ts.map +1 -1
- package/package.json +8 -2
- package/src/SoluCXWidget.ts +144 -0
- package/src/SoluCXWidgetHost.tsx +44 -0
- package/src/SoluCXWidgetView.tsx +97 -0
- package/src/__tests__/ClientVersionCollector.test.ts +5 -5
- package/src/__tests__/OverlayWidget.rendering.test.tsx +12 -14
- package/src/__tests__/SoluCXWidget.rendering.test.tsx +103 -60
- package/src/__tests__/SoluCXWidget.test.ts +448 -0
- package/src/__tests__/WidgetValidationService.test.ts +408 -0
- package/src/__tests__/e2e/widget-lifecycle.test.tsx +14 -23
- package/src/__tests__/index.test.tsx +39 -0
- package/src/__tests__/integration/webview-communication-simple.test.tsx +8 -6
- package/src/__tests__/integration/webview-communication.test.tsx +127 -130
- package/src/__tests__/normalizeWidgetOptions.test.ts +80 -0
- package/src/__tests__/useWidgetBootstrap.test.ts +634 -0
- package/src/__tests__/useWidgetState.test.ts +56 -13
- package/src/__tests__/widgetBootstrapService.test.ts +15 -17
- package/src/components/CloseButton.tsx +6 -2
- package/src/components/InlineWidget.tsx +4 -9
- package/src/components/ModalWidget.tsx +15 -45
- package/src/components/OverlayWidget.tsx +5 -15
- package/src/components/index.ts +4 -0
- package/src/constants/Constants.ts +15 -0
- package/src/{interfaces → domain}/WidgetCallbacks.ts +2 -2
- package/{lib/interfaces/WidgetData.d.ts → src/domain/WidgetData.ts} +3 -2
- package/src/domain/WidgetDisplayResult.ts +16 -0
- package/src/domain/WidgetOptions.ts +53 -0
- package/src/domain/WidgetResponse.ts +5 -0
- package/src/domain/WidgetSamplerLog.ts +11 -0
- package/src/{interfaces → domain}/index.ts +1 -2
- package/src/hooks/index.ts +2 -2
- package/src/{services/ClientVersionCollector.ts → hooks/useClientVersionCollector.ts} +6 -0
- package/src/hooks/useHeightAnimation.ts +6 -3
- package/src/hooks/useWidget.ts +46 -0
- package/src/hooks/useWidgetBootstrap.ts +117 -0
- package/src/hooks/useWidgetServices.ts +44 -0
- package/src/hooks/useWidgetUI.ts +38 -0
- package/src/index.ts +16 -11
- package/src/services/UserIdentificationService.ts +14 -0
- package/src/services/{widgetBootstrapService.ts → WidgetBootstrapService.ts} +43 -19
- package/src/services/WidgetEventService.ts +15 -0
- package/src/services/WidgetStateManager.ts +115 -0
- package/src/services/WidgetValidationService.ts +149 -0
- package/src/services/events/EventHandlerFactory.ts +70 -0
- package/src/services/events/EventHandlers.ts +67 -0
- package/src/services/events/index.ts +2 -0
- package/src/services/height/HeightStrategies.ts +15 -0
- package/src/services/storage/AsyncStorageService.ts +74 -0
- package/src/services/storage/IStorageService.ts +32 -0
- package/src/services/storage/StorageIdBuilder.ts +15 -0
- package/src/services/storage/index.ts +2 -0
- package/src/styles/widgetStyles.ts +1 -1
- package/README.intern.md +0 -490
- package/lib/constants/webViewConstants.d.ts +0 -12
- package/lib/constants/webViewConstants.d.ts.map +0 -1
- package/lib/constants/webViewConstants.js +0 -19
- package/lib/constants/webViewConstants.js.map +0 -1
- package/lib/hooks/useWidgetHeight.d.ts +0 -13
- package/lib/hooks/useWidgetHeight.d.ts.map +0 -1
- package/lib/hooks/useWidgetHeight.js +0 -21
- package/lib/hooks/useWidgetHeight.js.map +0 -1
- package/lib/hooks/useWidgetState.d.ts +0 -15
- package/lib/hooks/useWidgetState.d.ts.map +0 -1
- package/lib/hooks/useWidgetState.js +0 -79
- package/lib/hooks/useWidgetState.js.map +0 -1
- package/lib/interfaces/WidgetCallbacks.d.ts.map +0 -1
- package/lib/interfaces/WidgetCallbacks.js.map +0 -1
- package/lib/interfaces/WidgetData.d.ts.map +0 -1
- package/lib/interfaces/WidgetOptions.d.ts +0 -9
- package/lib/interfaces/WidgetOptions.d.ts.map +0 -1
- package/lib/interfaces/WidgetOptions.js.map +0 -1
- package/lib/interfaces/WidgetResponse.d.ts +0 -10
- package/lib/interfaces/WidgetResponse.d.ts.map +0 -1
- package/lib/interfaces/WidgetResponse.js +0 -12
- package/lib/interfaces/WidgetResponse.js.map +0 -1
- package/lib/interfaces/WidgetSamplerLog.d.ts +0 -7
- package/lib/interfaces/WidgetSamplerLog.d.ts.map +0 -1
- package/lib/interfaces/WidgetSamplerLog.js.map +0 -1
- package/lib/interfaces/index.d.ts.map +0 -1
- package/lib/services/ClientVersionCollector.d.ts +0 -2
- package/lib/services/ClientVersionCollector.d.ts.map +0 -1
- package/lib/services/ClientVersionCollector.js.map +0 -1
- package/lib/services/storage.d.ts +0 -8
- package/lib/services/storage.d.ts.map +0 -1
- package/lib/services/storage.js +0 -23
- package/lib/services/storage.js.map +0 -1
- package/lib/services/widgetBootstrapService.d.ts +0 -6
- package/lib/services/widgetBootstrapService.d.ts.map +0 -1
- package/lib/services/widgetBootstrapService.js.map +0 -1
- package/lib/services/widgetEventService.d.ts +0 -19
- package/lib/services/widgetEventService.d.ts.map +0 -1
- package/lib/services/widgetEventService.js +0 -79
- package/lib/services/widgetEventService.js.map +0 -1
- package/lib/services/widgetValidationService.d.ts +0 -18
- package/lib/services/widgetValidationService.d.ts.map +0 -1
- package/lib/services/widgetValidationService.js +0 -71
- package/lib/services/widgetValidationService.js.map +0 -1
- package/src/SoluCXWidget.tsx +0 -179
- package/src/constants/webViewConstants.ts +0 -15
- package/src/hooks/useWidgetHeight.ts +0 -38
- package/src/hooks/useWidgetState.ts +0 -101
- package/src/interfaces/WidgetOptions.ts +0 -8
- package/src/interfaces/WidgetResponse.ts +0 -15
- package/src/interfaces/WidgetSamplerLog.ts +0 -6
- package/src/services/storage.ts +0 -21
- package/src/services/widgetEventService.ts +0 -110
- package/src/services/widgetValidationService.ts +0 -102
- /package/lib/{interfaces → domain}/WidgetCallbacks.js +0 -0
- /package/lib/{interfaces → domain}/WidgetData.js +0 -0
- /package/lib/{interfaces → domain}/WidgetSamplerLog.js +0 -0
- /package/lib/{interfaces → domain}/index.js +0 -0
|
@@ -1,19 +1,23 @@
|
|
|
1
|
-
import { WidgetEventService } from '../services/
|
|
2
|
-
import type { WidgetCallbacks } from '../
|
|
1
|
+
import { WidgetEventService } from '../services/WidgetEventService';
|
|
2
|
+
import type { WidgetCallbacks } from '../domain';
|
|
3
|
+
import type { WidgetStateManager } from '../services/WidgetStateManager';
|
|
3
4
|
|
|
4
5
|
describe('WidgetEventService', () => {
|
|
5
|
-
let
|
|
6
|
+
let mockHide: jest.Mock;
|
|
6
7
|
let mockResize: jest.Mock;
|
|
7
8
|
let mockUserId: string;
|
|
9
|
+
let mockTransactionId: string;
|
|
8
10
|
let mockCallbacks: WidgetCallbacks;
|
|
11
|
+
let mockStateManager: jest.Mocked<WidgetStateManager>;
|
|
9
12
|
let service: WidgetEventService;
|
|
10
13
|
|
|
11
14
|
beforeEach(() => {
|
|
12
15
|
jest.clearAllMocks();
|
|
13
16
|
|
|
14
|
-
|
|
17
|
+
mockHide = jest.fn();
|
|
15
18
|
mockResize = jest.fn();
|
|
16
19
|
mockUserId = 'test-user-123';
|
|
20
|
+
mockTransactionId = 'txn-456';
|
|
17
21
|
mockCallbacks = {
|
|
18
22
|
onClosed: jest.fn(),
|
|
19
23
|
onError: jest.fn(),
|
|
@@ -24,11 +28,26 @@ describe('WidgetEventService', () => {
|
|
|
24
28
|
onResize: jest.fn(),
|
|
25
29
|
};
|
|
26
30
|
|
|
31
|
+
mockStateManager = {
|
|
32
|
+
getLogs: jest.fn(),
|
|
33
|
+
saveLogs: jest.fn(),
|
|
34
|
+
incrementAttempt: jest.fn(),
|
|
35
|
+
resetAttempts: jest.fn(),
|
|
36
|
+
markTransactionAnswered: jest.fn(),
|
|
37
|
+
hasAnsweredTransaction: jest.fn(),
|
|
38
|
+
clearLogs: jest.fn(),
|
|
39
|
+
hasLogs: jest.fn(),
|
|
40
|
+
updateTimestamp: jest.fn(),
|
|
41
|
+
overrideTimestamp: jest.fn(),
|
|
42
|
+
} as unknown as jest.Mocked<WidgetStateManager>;
|
|
43
|
+
|
|
27
44
|
service = new WidgetEventService(
|
|
28
|
-
|
|
45
|
+
mockHide,
|
|
29
46
|
mockResize,
|
|
30
47
|
mockUserId,
|
|
48
|
+
mockTransactionId,
|
|
31
49
|
mockCallbacks,
|
|
50
|
+
mockStateManager,
|
|
32
51
|
);
|
|
33
52
|
});
|
|
34
53
|
|
|
@@ -40,7 +59,7 @@ describe('WidgetEventService', () => {
|
|
|
40
59
|
it('should handle FORM_CLOSE event correctly', async () => {
|
|
41
60
|
const result = await service.handleMessage('FORM_CLOSE', true);
|
|
42
61
|
|
|
43
|
-
expect(
|
|
62
|
+
expect(mockHide).toHaveBeenCalledTimes(1);
|
|
44
63
|
expect(mockCallbacks.onClosed).toHaveBeenCalledTimes(1);
|
|
45
64
|
expect(result).toEqual({ status: 'success' });
|
|
46
65
|
});
|
|
@@ -56,11 +75,19 @@ describe('WidgetEventService', () => {
|
|
|
56
75
|
it('should handle FORM_ERROR event correctly', async () => {
|
|
57
76
|
const result = await service.handleMessage('FORM_ERROR-Something went wrong', true);
|
|
58
77
|
|
|
59
|
-
expect(
|
|
78
|
+
expect(mockHide).toHaveBeenCalledTimes(1);
|
|
60
79
|
expect(mockCallbacks.onError).toHaveBeenCalledWith('Something went wrong');
|
|
61
80
|
expect(result).toEqual({ status: 'error', message: 'Something went wrong' });
|
|
62
81
|
});
|
|
63
82
|
|
|
83
|
+
it('should preserve hyphenated FORM_ERROR payloads', async () => {
|
|
84
|
+
const result = await service.handleMessage('FORM_ERROR-timeout-api-gateway', true);
|
|
85
|
+
|
|
86
|
+
expect(mockHide).toHaveBeenCalledTimes(1);
|
|
87
|
+
expect(mockCallbacks.onError).toHaveBeenCalledWith('timeout-api-gateway');
|
|
88
|
+
expect(result).toEqual({ status: 'error', message: 'timeout-api-gateway' });
|
|
89
|
+
});
|
|
90
|
+
|
|
64
91
|
it('should handle FORM_PAGECHANGED event correctly', async () => {
|
|
65
92
|
const result = await service.handleMessage('FORM_PAGECHANGED-page2', true);
|
|
66
93
|
|
|
@@ -71,6 +98,7 @@ describe('WidgetEventService', () => {
|
|
|
71
98
|
it('should handle QUESTION_ANSWERED event correctly', async () => {
|
|
72
99
|
const result = await service.handleMessage('QUESTION_ANSWERED', true);
|
|
73
100
|
|
|
101
|
+
expect(mockStateManager.resetAttempts).toHaveBeenCalledTimes(1);
|
|
74
102
|
expect(mockCallbacks.onQuestionAnswered).toHaveBeenCalledTimes(1);
|
|
75
103
|
expect(result).toEqual({ status: 'success' });
|
|
76
104
|
});
|
|
@@ -78,6 +106,9 @@ describe('WidgetEventService', () => {
|
|
|
78
106
|
it('should handle FORM_COMPLETED event correctly', async () => {
|
|
79
107
|
const result = await service.handleMessage('FORM_COMPLETED', true);
|
|
80
108
|
|
|
109
|
+
expect(mockStateManager.resetAttempts).toHaveBeenCalledTimes(1);
|
|
110
|
+
expect(mockStateManager.markTransactionAnswered).toHaveBeenCalledWith('txn-456');
|
|
111
|
+
expect(mockStateManager.updateTimestamp).toHaveBeenCalledWith('lastSubmit');
|
|
81
112
|
expect(mockCallbacks.onCompleted).toHaveBeenCalledWith('test-user-123');
|
|
82
113
|
expect(result).toEqual({ status: 'success' });
|
|
83
114
|
});
|
|
@@ -85,10 +116,19 @@ describe('WidgetEventService', () => {
|
|
|
85
116
|
it('should handle FORM_PARTIALCOMPLETED event correctly', async () => {
|
|
86
117
|
const result = await service.handleMessage('FORM_PARTIALCOMPLETED', true);
|
|
87
118
|
|
|
119
|
+
expect(mockStateManager.resetAttempts).toHaveBeenCalledTimes(1);
|
|
120
|
+
expect(mockStateManager.markTransactionAnswered).toHaveBeenCalledWith('txn-456');
|
|
121
|
+
expect(mockStateManager.updateTimestamp).toHaveBeenCalledWith('lastPartialSubmit');
|
|
88
122
|
expect(mockCallbacks.onPartialCompleted).toHaveBeenCalledWith('test-user-123');
|
|
89
123
|
expect(result).toEqual({ status: 'success' });
|
|
90
124
|
});
|
|
91
125
|
|
|
126
|
+
it('should not mark a transaction as answered on QUESTION_ANSWERED', async () => {
|
|
127
|
+
await service.handleMessage('QUESTION_ANSWERED', true);
|
|
128
|
+
|
|
129
|
+
expect(mockStateManager.markTransactionAnswered).not.toHaveBeenCalled();
|
|
130
|
+
});
|
|
131
|
+
|
|
92
132
|
it('should return error for unknown events', async () => {
|
|
93
133
|
const result = await service.handleMessage('UNKNOWN_EVENT', true);
|
|
94
134
|
|
|
@@ -104,7 +144,7 @@ describe('WidgetEventService', () => {
|
|
|
104
144
|
it('should adapt closeSoluCXWidget to FORM_CLOSE', async () => {
|
|
105
145
|
const result = await service.handleMessage('closeSoluCXWidget', false);
|
|
106
146
|
|
|
107
|
-
expect(
|
|
147
|
+
expect(mockHide).toHaveBeenCalledTimes(1);
|
|
108
148
|
expect(mockCallbacks.onClosed).toHaveBeenCalledTimes(1);
|
|
109
149
|
expect(result).toEqual({ status: 'success' });
|
|
110
150
|
});
|
|
@@ -126,7 +166,7 @@ describe('WidgetEventService', () => {
|
|
|
126
166
|
it('should adapt dismissSoluCXWidget to FORM_CLOSE', async () => {
|
|
127
167
|
const result = await service.handleMessage('dismissSoluCXWidget', false);
|
|
128
168
|
|
|
129
|
-
expect(
|
|
169
|
+
expect(mockHide).toHaveBeenCalledTimes(1);
|
|
130
170
|
expect(mockCallbacks.onClosed).toHaveBeenCalledTimes(1);
|
|
131
171
|
expect(result).toEqual({ status: 'success' });
|
|
132
172
|
});
|
|
@@ -134,7 +174,7 @@ describe('WidgetEventService', () => {
|
|
|
134
174
|
it('should adapt errorSoluCXWidget to FORM_ERROR', async () => {
|
|
135
175
|
const result = await service.handleMessage('errorSoluCXWidget-Network error', false);
|
|
136
176
|
|
|
137
|
-
expect(
|
|
177
|
+
expect(mockHide).toHaveBeenCalledTimes(1);
|
|
138
178
|
expect(mockCallbacks.onError).toHaveBeenCalledWith('Network error');
|
|
139
179
|
expect(result).toEqual({ status: 'error', message: 'Network error' });
|
|
140
180
|
});
|
|
@@ -156,7 +196,7 @@ describe('WidgetEventService', () => {
|
|
|
156
196
|
it('should not call any callback when event is unknown', async () => {
|
|
157
197
|
await service.handleMessage('SOME_RANDOM_EVENT', true);
|
|
158
198
|
|
|
159
|
-
expect(
|
|
199
|
+
expect(mockHide).not.toHaveBeenCalled();
|
|
160
200
|
expect(mockResize).not.toHaveBeenCalled();
|
|
161
201
|
expect(mockCallbacks.onClosed).not.toHaveBeenCalled();
|
|
162
202
|
expect(mockCallbacks.onError).not.toHaveBeenCalled();
|
|
@@ -168,14 +208,17 @@ describe('WidgetEventService', () => {
|
|
|
168
208
|
|
|
169
209
|
it('should work without callbacks when none are provided', async () => {
|
|
170
210
|
const serviceWithoutCallbacks = new WidgetEventService(
|
|
171
|
-
|
|
211
|
+
mockHide,
|
|
172
212
|
mockResize,
|
|
173
213
|
mockUserId,
|
|
214
|
+
mockTransactionId,
|
|
215
|
+
undefined,
|
|
216
|
+
mockStateManager,
|
|
174
217
|
);
|
|
175
218
|
|
|
176
219
|
const result = await serviceWithoutCallbacks.handleMessage('FORM_CLOSE', true);
|
|
177
220
|
|
|
178
|
-
expect(
|
|
221
|
+
expect(mockHide).toHaveBeenCalledTimes(1);
|
|
179
222
|
expect(result).toEqual({ status: 'success' });
|
|
180
223
|
});
|
|
181
224
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { requestWidgetUrl, buildRequestParams } from '../services/
|
|
2
|
-
import { WidgetData } from '../
|
|
1
|
+
import { requestWidgetUrl, buildRequestParams } from '../services/WidgetBootstrapService';
|
|
2
|
+
import { WidgetData } from '../domain';
|
|
3
3
|
|
|
4
4
|
// Mock das dependências
|
|
5
5
|
jest.mock('../constants/Constants', () => ({
|
|
@@ -7,7 +7,7 @@ jest.mock('../constants/Constants', () => ({
|
|
|
7
7
|
SDK_VERSION: '0.1.16',
|
|
8
8
|
}));
|
|
9
9
|
|
|
10
|
-
jest.mock('../
|
|
10
|
+
jest.mock('../hooks/useClientVersionCollector', () => ({
|
|
11
11
|
getClientVersion: jest.fn(() => '1.0.0'),
|
|
12
12
|
}));
|
|
13
13
|
|
|
@@ -23,7 +23,7 @@ jest.mock('../hooks/useDeviceInfoCollector', () => ({
|
|
|
23
23
|
// Mock global do fetch
|
|
24
24
|
const originalFetch = global.fetch;
|
|
25
25
|
|
|
26
|
-
describe('
|
|
26
|
+
describe('WidgetBootstrapService', () => {
|
|
27
27
|
beforeEach(() => {
|
|
28
28
|
jest.clearAllMocks();
|
|
29
29
|
global.fetch = jest.fn();
|
|
@@ -46,8 +46,8 @@ describe('widgetBootstrapService', () => {
|
|
|
46
46
|
expect(params.get('customer_id')).toBe('cust-123');
|
|
47
47
|
expect(params.get('email')).toBe('test@example.com');
|
|
48
48
|
expect(params.get('journey')).toBe('checkout');
|
|
49
|
-
expect(params.get('transactionId')).
|
|
50
|
-
expect(params.get('attemptId')).
|
|
49
|
+
expect(params.get('transactionId')).toBeNull();
|
|
50
|
+
expect(params.get('attemptId')).toBeNull();
|
|
51
51
|
});
|
|
52
52
|
|
|
53
53
|
it('should skip undefined and null values', () => {
|
|
@@ -153,7 +153,7 @@ describe('widgetBootstrapService', () => {
|
|
|
153
153
|
'user-id'
|
|
154
154
|
);
|
|
155
155
|
|
|
156
|
-
expect(result).
|
|
156
|
+
expect(result).toEqual({ url: 'https://widget.url/test' });
|
|
157
157
|
});
|
|
158
158
|
|
|
159
159
|
it('should throw error when response is not ok', async () => {
|
|
@@ -190,28 +190,26 @@ describe('widgetBootstrapService', () => {
|
|
|
190
190
|
).rejects.toThrow('Fetch is not available');
|
|
191
191
|
});
|
|
192
192
|
|
|
193
|
-
it('should
|
|
193
|
+
it('should return payload without url when response does not contain url', async () => {
|
|
194
194
|
const mockResponse = {
|
|
195
195
|
ok: true,
|
|
196
|
-
json: jest.fn().mockResolvedValue({}),
|
|
196
|
+
json: jest.fn().mockResolvedValue({ available: false, reason: 'No survey available' }),
|
|
197
197
|
};
|
|
198
198
|
(global.fetch as jest.Mock).mockResolvedValue(mockResponse);
|
|
199
199
|
|
|
200
|
-
await
|
|
201
|
-
|
|
202
|
-
).rejects.toThrow('Failed to get the widget api response.');
|
|
200
|
+
const result = await requestWidgetUrl('api-key', { customer_id: 'cust' }, 'user-id');
|
|
201
|
+
expect(result).toEqual({ available: false, reason: 'No survey available' });
|
|
203
202
|
});
|
|
204
203
|
|
|
205
|
-
it('should
|
|
204
|
+
it('should return payload when url is null', async () => {
|
|
206
205
|
const mockResponse = {
|
|
207
206
|
ok: true,
|
|
208
|
-
json: jest.fn().mockResolvedValue({ url: null }),
|
|
207
|
+
json: jest.fn().mockResolvedValue({ available: true, url: null }),
|
|
209
208
|
};
|
|
210
209
|
(global.fetch as jest.Mock).mockResolvedValue(mockResponse);
|
|
211
210
|
|
|
212
|
-
await
|
|
213
|
-
|
|
214
|
-
).rejects.toThrow('Failed to get the widget api response.');
|
|
211
|
+
const result = await requestWidgetUrl('api-key', { customer_id: 'cust' }, 'user-id');
|
|
212
|
+
expect(result).toEqual({ available: true, url: null });
|
|
215
213
|
});
|
|
216
214
|
});
|
|
217
215
|
});
|
|
@@ -2,15 +2,19 @@ import React from 'react';
|
|
|
2
2
|
import { TouchableOpacity, Text, StyleSheet } from 'react-native';
|
|
3
3
|
|
|
4
4
|
interface CloseButtonProps {
|
|
5
|
-
onPress
|
|
5
|
+
onPress?: () => void;
|
|
6
6
|
visible?: boolean;
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export const CloseButton: React.FC<CloseButtonProps> = ({ onPress, visible = true }) => {
|
|
10
10
|
if (!visible) return null;
|
|
11
11
|
|
|
12
|
+
const handlePress = () => {
|
|
13
|
+
onPress?.();
|
|
14
|
+
};
|
|
15
|
+
|
|
12
16
|
return (
|
|
13
|
-
<TouchableOpacity style={styles.closeButton} onPress={
|
|
17
|
+
<TouchableOpacity style={styles.closeButton} onPress={handlePress}>
|
|
14
18
|
<Text style={styles.closeButtonText}>✕</Text>
|
|
15
19
|
</TouchableOpacity>
|
|
16
20
|
);
|
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import { View } from 'react-native';
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, Animated } from 'react-native';
|
|
3
3
|
import { styles, getWidgetVisibility } from '../styles/widgetStyles';
|
|
4
4
|
import { CloseButton } from './CloseButton';
|
|
5
|
-
import { Animated } from 'react-native';
|
|
6
5
|
import { useHeightAnimation } from '../hooks/useHeightAnimation';
|
|
7
6
|
|
|
8
7
|
interface InlineWidgetProps {
|
|
@@ -18,18 +17,14 @@ export const InlineWidget: React.FC<InlineWidgetProps> = ({
|
|
|
18
17
|
children,
|
|
19
18
|
onClose,
|
|
20
19
|
}) => {
|
|
21
|
-
const { animatedHeightStyle
|
|
22
|
-
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
updateHeight(height);
|
|
25
|
-
}, [height, updateHeight]);
|
|
20
|
+
const { animatedHeightStyle } = useHeightAnimation(height);
|
|
26
21
|
|
|
27
22
|
return (
|
|
28
23
|
<View style={[styles.inlineWrapper, getWidgetVisibility(visible)]}>
|
|
29
24
|
<Animated.View
|
|
30
25
|
style={[styles.inline, animatedHeightStyle, getWidgetVisibility(visible)]}>
|
|
31
26
|
{children}
|
|
32
|
-
<CloseButton visible={visible} onPress={onClose
|
|
27
|
+
<CloseButton visible={visible} onPress={onClose} />
|
|
33
28
|
</Animated.View>
|
|
34
29
|
</View>
|
|
35
30
|
);
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import React
|
|
2
|
-
import { Modal, View, Animated } from
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { useHeightAnimation } from '../hooks/useHeightAnimation';
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { Modal, View, Animated } from "react-native";
|
|
3
|
+
import { styles, getWidgetVisibility } from "../styles/widgetStyles";
|
|
4
|
+
import { CloseButton } from "./CloseButton";
|
|
5
|
+
import { useHeightAnimation } from "../hooks/useHeightAnimation";
|
|
7
6
|
|
|
8
7
|
interface ModalWidgetProps {
|
|
9
8
|
visible: boolean;
|
|
@@ -12,46 +11,17 @@ interface ModalWidgetProps {
|
|
|
12
11
|
onClose?: () => void;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
export const ModalWidget: React.FC<ModalWidgetProps> = ({
|
|
16
|
-
|
|
17
|
-
height,
|
|
18
|
-
children,
|
|
19
|
-
onClose,
|
|
20
|
-
}) => {
|
|
21
|
-
const { animatedHeightStyle, updateHeight } = useHeightAnimation(height);
|
|
22
|
-
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
updateHeight(height);
|
|
25
|
-
}, [height, updateHeight]);
|
|
14
|
+
export const ModalWidget: React.FC<ModalWidgetProps> = ({ visible, height, children, onClose }) => {
|
|
15
|
+
const { animatedHeightStyle } = useHeightAnimation(height);
|
|
26
16
|
|
|
27
17
|
return (
|
|
28
|
-
<
|
|
29
|
-
<
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
>
|
|
35
|
-
|
|
36
|
-
<Animated.View
|
|
37
|
-
style={[
|
|
38
|
-
styles.modalContent,
|
|
39
|
-
getWidgetVisibility(visible),
|
|
40
|
-
animatedHeightStyle,
|
|
41
|
-
]}
|
|
42
|
-
>
|
|
43
|
-
{children}
|
|
44
|
-
<CloseButton
|
|
45
|
-
visible={visible}
|
|
46
|
-
onPress={() => {
|
|
47
|
-
if (onClose) {
|
|
48
|
-
onClose();
|
|
49
|
-
}
|
|
50
|
-
}}
|
|
51
|
-
/>
|
|
52
|
-
</Animated.View>
|
|
53
|
-
</View>
|
|
54
|
-
</Modal>
|
|
55
|
-
</SafeAreaView>
|
|
18
|
+
<Modal transparent visible={visible} animationType="slide" hardwareAccelerated>
|
|
19
|
+
<View style={[styles.modalOverlay, getWidgetVisibility(visible)]}>
|
|
20
|
+
<Animated.View style={[styles.modalContent, getWidgetVisibility(visible), animatedHeightStyle]}>
|
|
21
|
+
{children}
|
|
22
|
+
<CloseButton visible={visible} onPress={onClose} />
|
|
23
|
+
</Animated.View>
|
|
24
|
+
</View>
|
|
25
|
+
</Modal>
|
|
56
26
|
);
|
|
57
27
|
};
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import React
|
|
1
|
+
import React from 'react';
|
|
2
2
|
import { View, type ViewStyle, Animated } from 'react-native';
|
|
3
3
|
import { initialWindowMetrics } from 'react-native-safe-area-context';
|
|
4
4
|
import { getWidgetStyles, getWidgetVisibility } from '../styles/widgetStyles';
|
|
5
|
-
import { FIXED_Z_INDEX } from '../constants/
|
|
5
|
+
import { FIXED_Z_INDEX } from '../constants/Constants';
|
|
6
6
|
import { CloseButton } from './CloseButton';
|
|
7
7
|
import { useHeightAnimation } from '../hooks/useHeightAnimation';
|
|
8
8
|
|
|
@@ -25,13 +25,8 @@ export const OverlayWidget: React.FC<OverlayWidgetProps> = ({
|
|
|
25
25
|
}) => {
|
|
26
26
|
const insets =
|
|
27
27
|
initialWindowMetrics?.insets ?? { top: 0, bottom: 0, left: 0, right: 0 };
|
|
28
|
-
const [isWidgetVisible, setIsWidgetVisible] = useState<boolean>(true);
|
|
29
28
|
|
|
30
|
-
const { animatedHeightStyle
|
|
31
|
-
|
|
32
|
-
useEffect(() => {
|
|
33
|
-
updateHeight(height);
|
|
34
|
-
}, [height, updateHeight]);
|
|
29
|
+
const { animatedHeightStyle } = useHeightAnimation(height);
|
|
35
30
|
|
|
36
31
|
const containerStyle: ViewStyle = {
|
|
37
32
|
position: 'absolute',
|
|
@@ -61,7 +56,7 @@ export const OverlayWidget: React.FC<OverlayWidgetProps> = ({
|
|
|
61
56
|
|
|
62
57
|
return (
|
|
63
58
|
<>
|
|
64
|
-
{
|
|
59
|
+
{visible && (
|
|
65
60
|
<View style={[containerStyle, getWidgetVisibility(visible)]}>
|
|
66
61
|
<Animated.View
|
|
67
62
|
style={[
|
|
@@ -73,12 +68,7 @@ export const OverlayWidget: React.FC<OverlayWidgetProps> = ({
|
|
|
73
68
|
{children}
|
|
74
69
|
<CloseButton
|
|
75
70
|
visible={visible}
|
|
76
|
-
onPress={
|
|
77
|
-
setIsWidgetVisible(false);
|
|
78
|
-
if (onClose) {
|
|
79
|
-
onClose();
|
|
80
|
-
}
|
|
81
|
-
}}
|
|
71
|
+
onPress={onClose}
|
|
82
72
|
/>
|
|
83
73
|
</Animated.View>
|
|
84
74
|
</View>
|
|
@@ -2,3 +2,18 @@ import packageJson from "../../package.json";
|
|
|
2
2
|
|
|
3
3
|
export const SDK_VERSION = packageJson.version;
|
|
4
4
|
export const SDK_NAME = "rn-widget-sdk";
|
|
5
|
+
export const BASE_URL = 'https://survey-link.solucx.com.br/link';
|
|
6
|
+
export const WIDGET_API_BASE_URL = 'https://widget-api.solucx.com.br';
|
|
7
|
+
export const STORAGE_KEY = '@solucxWidgetLog';
|
|
8
|
+
export const DEFAULT_CHANNEL_NUMBER = 1;
|
|
9
|
+
export const DEFAULT_CHANNEL = 'widget';
|
|
10
|
+
export const DEFAULT_WIDTH = 380;
|
|
11
|
+
export const MIN_HEIGHT = 200;
|
|
12
|
+
export const FIXED_Z_INDEX = 9999;
|
|
13
|
+
export const MODAL_Z_INDEX = 10000;
|
|
14
|
+
export const DESIGN_HEIGHT = 700;
|
|
15
|
+
export const WEB_VIEW_MESSAGE_LISTENER = `
|
|
16
|
+
window.addEventListener('message', function(event) {
|
|
17
|
+
window.ReactNativeWebView.postMessage(event.data);
|
|
18
|
+
});
|
|
19
|
+
`;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { BlockReason } from "
|
|
1
|
+
import type { BlockReason } from "./WidgetDisplayResult";
|
|
2
2
|
|
|
3
3
|
export interface WidgetCallbacks {
|
|
4
4
|
onPreOpen?: (userId: string) => void;
|
|
5
5
|
onOpened?: (userId: string) => void;
|
|
6
|
-
|
|
6
|
+
onBlocked?: (blockReason: BlockReason | string | undefined) => void;
|
|
7
7
|
onClosed?: () => void;
|
|
8
8
|
onError?: (message: string) => void;
|
|
9
9
|
onPageChanged?: (page: string) => void;
|
|
@@ -16,6 +16,7 @@ export interface WidgetData {
|
|
|
16
16
|
amount?: number;
|
|
17
17
|
score?: number;
|
|
18
18
|
journey?: string;
|
|
19
|
-
|
|
19
|
+
user_id?: string;
|
|
20
|
+
cpf?: string;
|
|
21
|
+
[key: `param_${string}`]: string | number | undefined;
|
|
20
22
|
}
|
|
21
|
-
//# sourceMappingURL=WidgetData.d.ts.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type BlockReason =
|
|
2
|
+
| "BLOCKED_BY_DISABLED"
|
|
3
|
+
| "BLOCKED_BY_SAMPLING"
|
|
4
|
+
| "BLOCKED_BY_TRANSACTION_ALREADY_ANSWERED"
|
|
5
|
+
| "BLOCKED_BY_MAX_ATTEMPTS"
|
|
6
|
+
| "BLOCKED_BY_WIDGET_DISPLAY_ATTEMPT_INTERVAL"
|
|
7
|
+
| "BLOCKED_BY_WIDGET_FIRST_ACCESS_INTERVAL"
|
|
8
|
+
| "BLOCKED_BY_WIDGET_DISPLAY_INTERVAL"
|
|
9
|
+
| "BLOCKED_BY_WIDGET_DISMISS_INTERVAL"
|
|
10
|
+
| "BLOCKED_BY_WIDGET_SUBMIT_INTERVAL"
|
|
11
|
+
| "BLOCKED_BY_WIDGET_PARTIAL_SUBMIT_INTERVAL";
|
|
12
|
+
|
|
13
|
+
export interface WidgetDisplayResult {
|
|
14
|
+
canDisplay: boolean;
|
|
15
|
+
blockReason?: BlockReason;
|
|
16
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface WidgetRetryOptions {
|
|
2
|
+
attempts?: number;
|
|
3
|
+
interval?: number;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export interface WidgetOptions {
|
|
7
|
+
enabled?: boolean;
|
|
8
|
+
samplingPercentage?: number;
|
|
9
|
+
type?: string;
|
|
10
|
+
height?: number;
|
|
11
|
+
maxAttemptsAfterDismiss?: number;
|
|
12
|
+
waitDaysAfterWidgetDisplayAttempt?: number;
|
|
13
|
+
waitDaysAfterWidgetFirstAccess?: number;
|
|
14
|
+
waitDaysAfterWidgetDisplay?: number;
|
|
15
|
+
waitDaysAfterWidgetDismiss?: number;
|
|
16
|
+
waitDaysAfterWidgetSubmit?: number;
|
|
17
|
+
waitDaysAfterWidgetPartialSubmit?: number;
|
|
18
|
+
|
|
19
|
+
/** @deprecated Use maxAttemptsAfterDismiss and waitDaysAfterWidgetDismiss instead */
|
|
20
|
+
retry?: WidgetRetryOptions;
|
|
21
|
+
/** @deprecated Use waitDaysAfterWidgetSubmit and waitDaysAfterWidgetPartialSubmit instead */
|
|
22
|
+
waitDelayAfterRating?: number;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Normalizes legacy option fields (retry, waitDelayAfterRating) into the
|
|
27
|
+
* canonical internal fields. Canonical fields take precedence over legacy ones.
|
|
28
|
+
*/
|
|
29
|
+
export function normalizeWidgetOptions(options: WidgetOptions): WidgetOptions {
|
|
30
|
+
if (!options) return options;
|
|
31
|
+
|
|
32
|
+
const normalized: WidgetOptions = { ...options };
|
|
33
|
+
|
|
34
|
+
if (options.retry) {
|
|
35
|
+
if (options.retry.attempts !== undefined && normalized.maxAttemptsAfterDismiss === undefined) {
|
|
36
|
+
normalized.maxAttemptsAfterDismiss = options.retry.attempts;
|
|
37
|
+
}
|
|
38
|
+
if (options.retry.interval !== undefined && normalized.waitDaysAfterWidgetDismiss === undefined) {
|
|
39
|
+
normalized.waitDaysAfterWidgetDismiss = options.retry.interval;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (options.waitDelayAfterRating !== undefined) {
|
|
44
|
+
if (normalized.waitDaysAfterWidgetSubmit === undefined) {
|
|
45
|
+
normalized.waitDaysAfterWidgetSubmit = options.waitDelayAfterRating;
|
|
46
|
+
}
|
|
47
|
+
if (normalized.waitDaysAfterWidgetPartialSubmit === undefined) {
|
|
48
|
+
normalized.waitDaysAfterWidgetPartialSubmit = options.waitDelayAfterRating;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return normalized;
|
|
53
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export interface WidgetSamplerLog {
|
|
2
|
+
attempts: number;
|
|
3
|
+
answeredTransactionIds?: string[];
|
|
4
|
+
lastExperienceId?: string;
|
|
5
|
+
lastDisplayAttempt?: number;
|
|
6
|
+
lastFirstAccess?: number;
|
|
7
|
+
lastDisplay?: number;
|
|
8
|
+
lastDismiss?: number;
|
|
9
|
+
lastSubmit?: number;
|
|
10
|
+
lastPartialSubmit?: number;
|
|
11
|
+
}
|
|
@@ -20,6 +20,5 @@ export type { WidgetResponse } from './WidgetResponse';
|
|
|
20
20
|
export type { WidgetData } from './WidgetData';
|
|
21
21
|
export type { WidgetOptions } from './WidgetOptions';
|
|
22
22
|
export type { WidgetSamplerLog } from './WidgetSamplerLog';
|
|
23
|
-
export type { WidgetError } from './WidgetResponse';
|
|
24
23
|
export type { WidgetCallbacks } from './WidgetCallbacks';
|
|
25
|
-
export type { WidgetDisplayResult } from '
|
|
24
|
+
export type { BlockReason, WidgetDisplayResult } from './WidgetDisplayResult';
|
package/src/hooks/index.ts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export {
|
|
2
|
-
export {
|
|
1
|
+
export { useWidgetBootstrap } from './useWidgetBootstrap';
|
|
2
|
+
export { useWidgetServices } from './useWidgetServices';
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
|
|
1
3
|
export const getClientVersion = (): string => {
|
|
2
4
|
try {
|
|
3
5
|
const DeviceInfo = require("react-native-device-info");
|
|
@@ -13,3 +15,7 @@ export const getClientVersion = (): string => {
|
|
|
13
15
|
|
|
14
16
|
return "unknown";
|
|
15
17
|
};
|
|
18
|
+
|
|
19
|
+
export const useClientVersion = (): string => {
|
|
20
|
+
return useMemo(() => getClientVersion(), []);
|
|
21
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { useRef, useCallback } from 'react';
|
|
1
|
+
import { useRef, useCallback, useEffect } from 'react';
|
|
3
2
|
import { Animated } from 'react-native';
|
|
4
3
|
|
|
5
4
|
export function useHeightAnimation(initialHeight = 0, duration = 300) {
|
|
@@ -16,7 +15,11 @@ export function useHeightAnimation(initialHeight = 0, duration = 300) {
|
|
|
16
15
|
[height, duration],
|
|
17
16
|
);
|
|
18
17
|
|
|
18
|
+
useEffect(() => {
|
|
19
|
+
updateHeight(initialHeight);
|
|
20
|
+
}, [initialHeight, updateHeight]);
|
|
21
|
+
|
|
19
22
|
const animatedHeightStyle = { height };
|
|
20
23
|
|
|
21
|
-
return { animatedHeightStyle,
|
|
24
|
+
return { animatedHeightStyle, height };
|
|
22
25
|
}
|