@solucx/react-native-solucx-widget 0.1.14 → 0.1.15
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.intern.md +513 -473
- package/README.md +285 -257
- package/package.json +23 -23
- package/src/SoluCXWidget.tsx +119 -119
- package/src/__tests__/urlUtils.test.ts +56 -56
- package/src/__tests__/useWidgetState.test.ts +188 -188
- package/src/components/CloseButton.tsx +36 -36
- package/src/components/InlineWidget.tsx +36 -32
- package/src/components/ModalWidget.tsx +59 -43
- package/src/components/OverlayWidget.tsx +88 -81
- package/src/constants/webViewConstants.ts +14 -14
- package/src/hooks/index.ts +2 -1
- package/src/hooks/useHeightAnimation.ts +22 -0
- package/src/hooks/useWidgetHeight.ts +38 -0
- package/src/hooks/useWidgetState.ts +101 -77
- package/src/index.ts +8 -8
- package/src/interfaces/WidgetData.ts +19 -19
- package/src/interfaces/WidgetOptions.ts +7 -7
- package/src/interfaces/WidgetResponse.ts +15 -15
- package/src/interfaces/WidgetSamplerLog.ts +5 -5
- package/src/interfaces/index.ts +23 -23
- package/src/services/storage.ts +20 -20
- package/src/services/widgetEventService.ts +111 -111
- package/src/services/widgetValidationService.ts +86 -86
- package/src/styles/widgetStyles.ts +58 -83
- package/src/utils/urlUtils.ts +13 -13
|
@@ -1,81 +1,88 @@
|
|
|
1
|
-
import React, { useState, useEffect } from 'react';
|
|
2
|
-
import { View, ViewStyle } from 'react-native';
|
|
3
|
-
import { initialWindowMetrics } from 'react-native-safe-area-context';
|
|
4
|
-
import { getWidgetStyles, getWidgetVisibility
|
|
5
|
-
import { FIXED_Z_INDEX } from '../constants/webViewConstants';
|
|
6
|
-
import { CloseButton } from './CloseButton';
|
|
7
|
-
import
|
|
8
|
-
|
|
9
|
-
interface OverlayWidgetProps {
|
|
10
|
-
visible: boolean;
|
|
11
|
-
width: number;
|
|
12
|
-
height: number;
|
|
13
|
-
position: 'top' | 'bottom';
|
|
14
|
-
children?: React.ReactNode;
|
|
15
|
-
onClose?: () => void;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export const OverlayWidget: React.FC<OverlayWidgetProps> = ({
|
|
19
|
-
visible,
|
|
20
|
-
width,
|
|
21
|
-
height,
|
|
22
|
-
position,
|
|
23
|
-
children,
|
|
24
|
-
onClose,
|
|
25
|
-
}) => {
|
|
26
|
-
const insets =
|
|
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
|
-
}
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
|
+
import { View, ViewStyle, Animated } from 'react-native';
|
|
3
|
+
import { initialWindowMetrics } from 'react-native-safe-area-context';
|
|
4
|
+
import { getWidgetStyles, getWidgetVisibility } from '../styles/widgetStyles';
|
|
5
|
+
import { FIXED_Z_INDEX } from '../constants/webViewConstants';
|
|
6
|
+
import { CloseButton } from './CloseButton';
|
|
7
|
+
import { useHeightAnimation } from '../hooks/useHeightAnimation';
|
|
8
|
+
|
|
9
|
+
interface OverlayWidgetProps {
|
|
10
|
+
visible: boolean;
|
|
11
|
+
width: number;
|
|
12
|
+
height: number;
|
|
13
|
+
position: 'top' | 'bottom';
|
|
14
|
+
children?: React.ReactNode;
|
|
15
|
+
onClose?: () => void;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const OverlayWidget: React.FC<OverlayWidgetProps> = ({
|
|
19
|
+
visible,
|
|
20
|
+
width,
|
|
21
|
+
height,
|
|
22
|
+
position,
|
|
23
|
+
children,
|
|
24
|
+
onClose,
|
|
25
|
+
}) => {
|
|
26
|
+
const insets =
|
|
27
|
+
initialWindowMetrics?.insets ?? { top: 0, bottom: 0, left: 0, right: 0 };
|
|
28
|
+
const [isWidgetVisible, setIsWidgetVisible] = useState<boolean>(true);
|
|
29
|
+
|
|
30
|
+
const { animatedHeightStyle, updateHeight } = useHeightAnimation(height);
|
|
31
|
+
|
|
32
|
+
useEffect(() => {
|
|
33
|
+
updateHeight(height);
|
|
34
|
+
}, [height, updateHeight]);
|
|
35
|
+
|
|
36
|
+
const containerStyle: ViewStyle = {
|
|
37
|
+
position: 'absolute',
|
|
38
|
+
top: 0,
|
|
39
|
+
left: 0,
|
|
40
|
+
right: 0,
|
|
41
|
+
bottom: 0,
|
|
42
|
+
width: '100%',
|
|
43
|
+
height: '100%',
|
|
44
|
+
zIndex: FIXED_Z_INDEX,
|
|
45
|
+
pointerEvents: 'box-none',
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
const contentStyle = [
|
|
49
|
+
getWidgetStyles(position).content,
|
|
50
|
+
{
|
|
51
|
+
width,
|
|
52
|
+
pointerEvents: 'auto' as const,
|
|
53
|
+
...(position === 'top' && {
|
|
54
|
+
top: insets.top,
|
|
55
|
+
}),
|
|
56
|
+
...(position === 'bottom' && {
|
|
57
|
+
bottom: insets.bottom,
|
|
58
|
+
}),
|
|
59
|
+
},
|
|
60
|
+
];
|
|
61
|
+
|
|
62
|
+
return (
|
|
63
|
+
<>
|
|
64
|
+
{isWidgetVisible && (
|
|
65
|
+
<View style={[containerStyle, getWidgetVisibility(visible)]}>
|
|
66
|
+
<Animated.View
|
|
67
|
+
style={[
|
|
68
|
+
contentStyle,
|
|
69
|
+
animatedHeightStyle,
|
|
70
|
+
getWidgetVisibility(visible),
|
|
71
|
+
]}
|
|
72
|
+
>
|
|
73
|
+
{children}
|
|
74
|
+
<CloseButton
|
|
75
|
+
visible={visible}
|
|
76
|
+
onPress={() => {
|
|
77
|
+
setIsWidgetVisible(false);
|
|
78
|
+
if (onClose) {
|
|
79
|
+
onClose();
|
|
80
|
+
}
|
|
81
|
+
}}
|
|
82
|
+
/>
|
|
83
|
+
</Animated.View>
|
|
84
|
+
</View>
|
|
85
|
+
)}
|
|
86
|
+
</>
|
|
87
|
+
);
|
|
88
|
+
};
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
export const BASE_URL = 'https://survey-link.solucx.com.br/link';
|
|
2
|
-
export const STORAGE_KEY = '@solucxWidgetLog';
|
|
3
|
-
export const DEFAULT_CHANNEL_NUMBER = 1;
|
|
4
|
-
export const DEFAULT_CHANNEL = 'widget';
|
|
5
|
-
export const DEFAULT_WIDTH = 380;
|
|
6
|
-
export const MIN_HEIGHT = 200;
|
|
7
|
-
export const FIXED_Z_INDEX = 9999;
|
|
8
|
-
export const MODAL_Z_INDEX = 10000;
|
|
9
|
-
export const DESIGN_HEIGHT = 700;
|
|
10
|
-
export const WEB_VIEW_MESSAGE_LISTENER = `
|
|
11
|
-
window.addEventListener('message', function(event) {
|
|
12
|
-
window.ReactNativeWebView.postMessage(event.data);
|
|
13
|
-
});
|
|
14
|
-
`;
|
|
1
|
+
export const BASE_URL = 'https://survey-link.solucx.com.br/link';
|
|
2
|
+
export const STORAGE_KEY = '@solucxWidgetLog';
|
|
3
|
+
export const DEFAULT_CHANNEL_NUMBER = 1;
|
|
4
|
+
export const DEFAULT_CHANNEL = 'widget';
|
|
5
|
+
export const DEFAULT_WIDTH = 380;
|
|
6
|
+
export const MIN_HEIGHT = 200;
|
|
7
|
+
export const FIXED_Z_INDEX = 9999;
|
|
8
|
+
export const MODAL_Z_INDEX = 10000;
|
|
9
|
+
export const DESIGN_HEIGHT = 700;
|
|
10
|
+
export const WEB_VIEW_MESSAGE_LISTENER = `
|
|
11
|
+
window.addEventListener('message', function(event) {
|
|
12
|
+
window.ReactNativeWebView.postMessage(event.data);
|
|
13
|
+
});
|
|
14
|
+
`;
|
package/src/hooks/index.ts
CHANGED
|
@@ -1 +1,2 @@
|
|
|
1
|
-
export { useWidgetState } from './useWidgetState';
|
|
1
|
+
export { useWidgetState } from './useWidgetState';
|
|
2
|
+
export { useWidgetHeight } from './useWidgetHeight';
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// hooks/useHeightAnimation.ts
|
|
2
|
+
import { useRef, useCallback } from 'react';
|
|
3
|
+
import { Animated } from 'react-native';
|
|
4
|
+
|
|
5
|
+
export function useHeightAnimation(initialHeight = 0, duration = 300) {
|
|
6
|
+
const height = useRef(new Animated.Value(initialHeight)).current;
|
|
7
|
+
|
|
8
|
+
const updateHeight = useCallback(
|
|
9
|
+
(toValue: number) => {
|
|
10
|
+
Animated.timing(height, {
|
|
11
|
+
toValue,
|
|
12
|
+
duration,
|
|
13
|
+
useNativeDriver: false,
|
|
14
|
+
}).start();
|
|
15
|
+
},
|
|
16
|
+
[height, duration],
|
|
17
|
+
);
|
|
18
|
+
|
|
19
|
+
const animatedHeightStyle = { height };
|
|
20
|
+
|
|
21
|
+
return { animatedHeightStyle, updateHeight, height };
|
|
22
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { useState, useCallback } from 'react';
|
|
2
|
+
import type { WidgetOptions } from '../interfaces';
|
|
3
|
+
|
|
4
|
+
interface UseWidgetHeightProps {
|
|
5
|
+
options?: WidgetOptions;
|
|
6
|
+
initialHeight?: number;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
interface UseWidgetHeightReturn {
|
|
10
|
+
height: number;
|
|
11
|
+
isFixedHeight: boolean;
|
|
12
|
+
handleResize: (newHeight: number) => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const useWidgetHeight = ({
|
|
16
|
+
options,
|
|
17
|
+
initialHeight = 300
|
|
18
|
+
}: UseWidgetHeightProps): UseWidgetHeightReturn => {
|
|
19
|
+
const [dynamicHeight, setDynamicHeight] = useState<number>(initialHeight);
|
|
20
|
+
const hasFixedHeight = typeof options?.height === 'number';
|
|
21
|
+
|
|
22
|
+
const height = hasFixedHeight ? options!.height! : dynamicHeight;
|
|
23
|
+
|
|
24
|
+
const handleResize = useCallback(
|
|
25
|
+
(newHeight: number) => {
|
|
26
|
+
if (!hasFixedHeight && newHeight > 0) {
|
|
27
|
+
setDynamicHeight(newHeight);
|
|
28
|
+
}
|
|
29
|
+
},
|
|
30
|
+
[hasFixedHeight]
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
return {
|
|
34
|
+
height,
|
|
35
|
+
isFixedHeight: hasFixedHeight,
|
|
36
|
+
handleResize
|
|
37
|
+
};
|
|
38
|
+
};
|
|
@@ -1,77 +1,101 @@
|
|
|
1
|
-
import { useState, useCallback } from 'react';
|
|
2
|
-
import { Dimensions } from 'react-native';
|
|
3
|
-
import {
|
|
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
|
-
|
|
1
|
+
import { useState, useCallback, useMemo } from 'react';
|
|
2
|
+
import { Dimensions } from 'react-native';
|
|
3
|
+
import {
|
|
4
|
+
WidgetData,
|
|
5
|
+
WidgetOptions,
|
|
6
|
+
WidgetType,
|
|
7
|
+
WidgetSamplerLog
|
|
8
|
+
} from '../interfaces';
|
|
9
|
+
import { StorageService } from '../services/storage';
|
|
10
|
+
|
|
11
|
+
function getUserId(widgetData: WidgetData): string {
|
|
12
|
+
return (
|
|
13
|
+
widgetData.customer_id ??
|
|
14
|
+
widgetData.document ??
|
|
15
|
+
widgetData.email ??
|
|
16
|
+
'default_user'
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export const useWidgetState = (
|
|
21
|
+
data: WidgetData,
|
|
22
|
+
options?: WidgetOptions,
|
|
23
|
+
type?: WidgetType
|
|
24
|
+
) => {
|
|
25
|
+
const [savedData, setSavedData] = useState<WidgetSamplerLog | null>(null);
|
|
26
|
+
const [isWidgetVisible, setIsWidgetVisible] = useState<boolean>(false);
|
|
27
|
+
|
|
28
|
+
const userId = getUserId(data);
|
|
29
|
+
|
|
30
|
+
const storageService = useMemo(() => new StorageService(userId), [userId]);
|
|
31
|
+
|
|
32
|
+
const screenHeight = Dimensions.get('screen').height;
|
|
33
|
+
const height = options?.height ? Number(options.height) : undefined;
|
|
34
|
+
|
|
35
|
+
const [widgetHeight, setWidgetHeight] = useState<number>(height ?? 300);
|
|
36
|
+
|
|
37
|
+
const loadSavedData = useCallback(async () => {
|
|
38
|
+
try {
|
|
39
|
+
const jsonValue = await storageService.read();
|
|
40
|
+
setSavedData(jsonValue);
|
|
41
|
+
} catch (error) {
|
|
42
|
+
console.error('Error loading storage data:', error);
|
|
43
|
+
}
|
|
44
|
+
}, [storageService]);
|
|
45
|
+
|
|
46
|
+
const saveData = useCallback(
|
|
47
|
+
async (data: WidgetSamplerLog) => {
|
|
48
|
+
try {
|
|
49
|
+
await storageService.write(data);
|
|
50
|
+
setSavedData(data);
|
|
51
|
+
} catch (error) {
|
|
52
|
+
console.error('Error saving storage data:', error);
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
[storageService]
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
const open = useCallback(async () => {
|
|
59
|
+
const userLogs = await storageService.read();
|
|
60
|
+
userLogs.attempts = (userLogs.attempts || 0) + 1;
|
|
61
|
+
userLogs.lastAttempt = Date.now();
|
|
62
|
+
try {
|
|
63
|
+
await storageService.write(userLogs);
|
|
64
|
+
setSavedData(userLogs);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error('Error saving storage data:', error);
|
|
67
|
+
}
|
|
68
|
+
setIsWidgetVisible(true);
|
|
69
|
+
}, [storageService]);
|
|
70
|
+
|
|
71
|
+
const close = useCallback(() => {
|
|
72
|
+
setIsWidgetVisible(false);
|
|
73
|
+
}, []);
|
|
74
|
+
|
|
75
|
+
const resize = useCallback(
|
|
76
|
+
(value: string) => {
|
|
77
|
+
const receivedHeight = Number(value);
|
|
78
|
+
|
|
79
|
+
if (height !== undefined) {
|
|
80
|
+
setWidgetHeight(height);
|
|
81
|
+
} else if (receivedHeight > 0) {
|
|
82
|
+
setWidgetHeight(receivedHeight);
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
[height]
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
return {
|
|
89
|
+
savedData,
|
|
90
|
+
widgetHeight,
|
|
91
|
+
isWidgetVisible,
|
|
92
|
+
setIsWidgetVisible,
|
|
93
|
+
loadSavedData,
|
|
94
|
+
saveData,
|
|
95
|
+
open,
|
|
96
|
+
close,
|
|
97
|
+
resize,
|
|
98
|
+
userId,
|
|
99
|
+
screenHeight
|
|
100
|
+
};
|
|
101
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export { SoluCXWidget } from './SoluCXWidget';
|
|
2
|
-
export { useWidgetState } from './hooks/useWidgetState';
|
|
3
|
-
export { WidgetEventService } from './services/widgetEventService';
|
|
4
|
-
export { StorageService } from './services/storage';
|
|
5
|
-
export { buildWidgetURL } from './utils/urlUtils';
|
|
6
|
-
export { ModalWidget } from './components/ModalWidget';
|
|
7
|
-
export { getWidgetStyles, styles } from './styles/widgetStyles';
|
|
8
|
-
export * from './interfaces';
|
|
1
|
+
export { SoluCXWidget } from './SoluCXWidget';
|
|
2
|
+
export { useWidgetState } from './hooks/useWidgetState';
|
|
3
|
+
export { WidgetEventService } from './services/widgetEventService';
|
|
4
|
+
export { StorageService } from './services/storage';
|
|
5
|
+
export { buildWidgetURL } from './utils/urlUtils';
|
|
6
|
+
export { ModalWidget } from './components/ModalWidget';
|
|
7
|
+
export { getWidgetStyles, styles } from './styles/widgetStyles';
|
|
8
|
+
export * from './interfaces';
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
-
export interface WidgetData {
|
|
2
|
-
transaction_id?: string;
|
|
3
|
-
attempt_id?: string;
|
|
4
|
-
form_id?: string;
|
|
5
|
-
customer_id?: string;
|
|
6
|
-
name?: string;
|
|
7
|
-
email?: string;
|
|
8
|
-
phone?: string;
|
|
9
|
-
phone2?: string;
|
|
10
|
-
document?: string;
|
|
11
|
-
birth_date?: string;
|
|
12
|
-
store_id?: string;
|
|
13
|
-
store_name?: string;
|
|
14
|
-
employee_id?: string;
|
|
15
|
-
employee_name?: string;
|
|
16
|
-
amount?: number;
|
|
17
|
-
score?: number;
|
|
18
|
-
journey?: string;
|
|
19
|
-
[key: string]: string | number | undefined;
|
|
1
|
+
export interface WidgetData {
|
|
2
|
+
transaction_id?: string;
|
|
3
|
+
attempt_id?: string;
|
|
4
|
+
form_id?: string;
|
|
5
|
+
customer_id?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
email?: string;
|
|
8
|
+
phone?: string;
|
|
9
|
+
phone2?: string;
|
|
10
|
+
document?: string;
|
|
11
|
+
birth_date?: string;
|
|
12
|
+
store_id?: string;
|
|
13
|
+
store_name?: string;
|
|
14
|
+
employee_id?: string;
|
|
15
|
+
employee_name?: string;
|
|
16
|
+
amount?: number;
|
|
17
|
+
score?: number;
|
|
18
|
+
journey?: string;
|
|
19
|
+
[key: string]: string | number | undefined;
|
|
20
20
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export interface WidgetOptions {
|
|
2
|
-
height?: number;
|
|
3
|
-
retry?: {
|
|
4
|
-
attempts?: number;
|
|
5
|
-
interval?: number;
|
|
6
|
-
};
|
|
7
|
-
waitDelayAfterRating?: number;
|
|
1
|
+
export interface WidgetOptions {
|
|
2
|
+
height?: number;
|
|
3
|
+
retry?: {
|
|
4
|
+
attempts?: number;
|
|
5
|
+
interval?: number;
|
|
6
|
+
};
|
|
7
|
+
waitDelayAfterRating?: number;
|
|
8
8
|
}
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
export interface WidgetResponse {
|
|
2
|
-
status?: "success" | "error";
|
|
3
|
-
message?: string;
|
|
4
|
-
}
|
|
5
|
-
|
|
6
|
-
export class WidgetError extends Error implements WidgetResponse {
|
|
7
|
-
status: "error";
|
|
8
|
-
message: string;
|
|
9
|
-
|
|
10
|
-
constructor(message: string) {
|
|
11
|
-
super(message);
|
|
12
|
-
this.status = "error";
|
|
13
|
-
this.message = message;
|
|
14
|
-
}
|
|
15
|
-
}
|
|
1
|
+
export interface WidgetResponse {
|
|
2
|
+
status?: "success" | "error";
|
|
3
|
+
message?: string;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
export class WidgetError extends Error implements WidgetResponse {
|
|
7
|
+
status: "error";
|
|
8
|
+
message: string;
|
|
9
|
+
|
|
10
|
+
constructor(message: string) {
|
|
11
|
+
super(message);
|
|
12
|
+
this.status = "error";
|
|
13
|
+
this.message = message;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export interface WidgetSamplerLog {
|
|
2
|
-
attempts: number;
|
|
3
|
-
lastAttempt: number;
|
|
4
|
-
lastRating: number;
|
|
5
|
-
lastParcial: number;
|
|
1
|
+
export interface WidgetSamplerLog {
|
|
2
|
+
attempts: number;
|
|
3
|
+
lastAttempt: number;
|
|
4
|
+
lastRating: number;
|
|
5
|
+
lastParcial: number;
|
|
6
6
|
}
|
package/src/interfaces/index.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
export type SoluCXKey = string;
|
|
2
|
-
export type WidgetType = "bottom" | "top" | "inline" | "modal";
|
|
3
|
-
export type EventKey =
|
|
4
|
-
| "FORM_OPENED"
|
|
5
|
-
| "FORM_CLOSE"
|
|
6
|
-
| "FORM_ERROR"
|
|
7
|
-
| "FORM_PAGECHANGED"
|
|
8
|
-
| "QUESTION_ANSWERED"
|
|
9
|
-
| "FORM_COMPLETED"
|
|
10
|
-
| "FORM_PARTIALCOMPLETED"
|
|
11
|
-
| "FORM_RESIZE";
|
|
12
|
-
export type SurveyEventKey =
|
|
13
|
-
| "closeSoluCXWidget"
|
|
14
|
-
| "dismissSoluCXWidget"
|
|
15
|
-
| "completeSoluCXWidget"
|
|
16
|
-
| "partialSoluCXWidget"
|
|
17
|
-
| "resizeSoluCXWidget"
|
|
18
|
-
| "openSoluCXWidget"
|
|
19
|
-
| `errorSoluCXWidget`;
|
|
20
|
-
export type { WidgetResponse } from './WidgetResponse';
|
|
21
|
-
export type { WidgetData } from './WidgetData';
|
|
22
|
-
export type { WidgetOptions } from './WidgetOptions';
|
|
23
|
-
export type { WidgetSamplerLog } from './WidgetSamplerLog';
|
|
1
|
+
export type SoluCXKey = string;
|
|
2
|
+
export type WidgetType = "bottom" | "top" | "inline" | "modal";
|
|
3
|
+
export type EventKey =
|
|
4
|
+
| "FORM_OPENED"
|
|
5
|
+
| "FORM_CLOSE"
|
|
6
|
+
| "FORM_ERROR"
|
|
7
|
+
| "FORM_PAGECHANGED"
|
|
8
|
+
| "QUESTION_ANSWERED"
|
|
9
|
+
| "FORM_COMPLETED"
|
|
10
|
+
| "FORM_PARTIALCOMPLETED"
|
|
11
|
+
| "FORM_RESIZE";
|
|
12
|
+
export type SurveyEventKey =
|
|
13
|
+
| "closeSoluCXWidget"
|
|
14
|
+
| "dismissSoluCXWidget"
|
|
15
|
+
| "completeSoluCXWidget"
|
|
16
|
+
| "partialSoluCXWidget"
|
|
17
|
+
| "resizeSoluCXWidget"
|
|
18
|
+
| "openSoluCXWidget"
|
|
19
|
+
| `errorSoluCXWidget`;
|
|
20
|
+
export type { WidgetResponse } from './WidgetResponse';
|
|
21
|
+
export type { WidgetData } from './WidgetData';
|
|
22
|
+
export type { WidgetOptions } from './WidgetOptions';
|
|
23
|
+
export type { WidgetSamplerLog } from './WidgetSamplerLog';
|
|
24
24
|
export type { WidgetError } from './WidgetResponse';
|
package/src/services/storage.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
2
|
-
import { WidgetSamplerLog } from '../interfaces';
|
|
3
|
-
import { STORAGE_KEY } from '../constants/webViewConstants';
|
|
4
|
-
|
|
5
|
-
export class StorageService {
|
|
6
|
-
private key: string;
|
|
7
|
-
|
|
8
|
-
constructor(key: string) {
|
|
9
|
-
this.key = `${STORAGE_KEY}_${key}`;
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
async write(data: WidgetSamplerLog): Promise<void> {
|
|
13
|
-
const json = JSON.stringify(data);
|
|
14
|
-
await AsyncStorage.setItem(this.key, json);
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
async read(): Promise<WidgetSamplerLog> {
|
|
18
|
-
const json = await AsyncStorage.getItem(this.key);
|
|
19
|
-
return json ? JSON.parse(json) as WidgetSamplerLog : {} as WidgetSamplerLog;
|
|
20
|
-
}
|
|
1
|
+
import AsyncStorage from '@react-native-async-storage/async-storage';
|
|
2
|
+
import { WidgetSamplerLog } from '../interfaces';
|
|
3
|
+
import { STORAGE_KEY } from '../constants/webViewConstants';
|
|
4
|
+
|
|
5
|
+
export class StorageService {
|
|
6
|
+
private key: string;
|
|
7
|
+
|
|
8
|
+
constructor(key: string) {
|
|
9
|
+
this.key = `${STORAGE_KEY}_${key}`;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async write(data: WidgetSamplerLog): Promise<void> {
|
|
13
|
+
const json = JSON.stringify(data);
|
|
14
|
+
await AsyncStorage.setItem(this.key, json);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async read(): Promise<WidgetSamplerLog> {
|
|
18
|
+
const json = await AsyncStorage.getItem(this.key);
|
|
19
|
+
return json ? JSON.parse(json) as WidgetSamplerLog : {} as WidgetSamplerLog;
|
|
20
|
+
}
|
|
21
21
|
}
|