@videowisehq/videowise-react-native-sdk 1.3.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.
Files changed (38) hide show
  1. package/README.md +80 -0
  2. package/lib/components/floating.d.ts +5 -0
  3. package/lib/components/floating.d.ts.map +1 -0
  4. package/lib/components/floating.js +100 -0
  5. package/lib/components/inline.d.ts +5 -0
  6. package/lib/components/inline.d.ts.map +1 -0
  7. package/lib/components/inline.js +112 -0
  8. package/lib/components/live-shopping-channel.d.ts +5 -0
  9. package/lib/components/live-shopping-channel.d.ts.map +1 -0
  10. package/lib/components/live-shopping-channel.js +72 -0
  11. package/lib/components/modal-video.d.ts +5 -0
  12. package/lib/components/modal-video.d.ts.map +1 -0
  13. package/lib/components/modal-video.js +8 -0
  14. package/lib/components/video-feed.d.ts +5 -0
  15. package/lib/components/video-feed.d.ts.map +1 -0
  16. package/lib/components/video-feed.js +55 -0
  17. package/lib/index.d.ts +11 -0
  18. package/lib/index.d.ts.map +1 -0
  19. package/lib/index.js +11 -0
  20. package/lib/interfaces.d.ts +67 -0
  21. package/lib/interfaces.d.ts.map +1 -0
  22. package/lib/interfaces.js +1 -0
  23. package/lib/types.d.ts +136 -0
  24. package/lib/types.d.ts.map +1 -0
  25. package/lib/types.js +58 -0
  26. package/lib/utils/get-notch-height.d.ts +2 -0
  27. package/lib/utils/get-notch-height.d.ts.map +1 -0
  28. package/lib/utils/get-notch-height.js +36 -0
  29. package/lib/utils/handle-on-event.d.ts +4 -0
  30. package/lib/utils/handle-on-event.d.ts.map +1 -0
  31. package/lib/utils/handle-on-event.js +19 -0
  32. package/lib/utils/injected-javascript.d.ts +2 -0
  33. package/lib/utils/injected-javascript.d.ts.map +1 -0
  34. package/lib/utils/injected-javascript.js +26 -0
  35. package/lib/utils/unify-ls-product.d.ts +3 -0
  36. package/lib/utils/unify-ls-product.d.ts.map +1 -0
  37. package/lib/utils/unify-ls-product.js +15 -0
  38. package/package.json +64 -0
package/README.md ADDED
@@ -0,0 +1,80 @@
1
+ # The repository contains 2 parts:
2
+
3
+ - ### the SDK src files
4
+ - ### the `example` (a **React Native** boilerplate) which can be used for previewing the SDK
5
+
6
+ ## For Dev Env.
7
+
8
+ Needed to install the dependencies required for running dev mode (with watch over files) for the SDK.
9
+ Use Node v22.
10
+
11
+ ### 1. Run `npm i`
12
+
13
+ ### 2. Run `npm run dev:install`
14
+
15
+ ### 4. Run `npm start`
16
+
17
+ Needed to install the dependencies required for running the `React Native` example.
18
+
19
+ ### 📱 For iOS -> Open new terminal ` npm run dev:install:ios`
20
+
21
+ ### Run `npm run dev:ios`
22
+
23
+ ### 🤖 For Android -> Open new terminal `npm run dev:doctor` to see what's missing and install all the required dependencies.
24
+
25
+ ### After -> `npm run dev:android`
26
+
27
+ # SDK
28
+
29
+ interface VideowiseSDKProps {
30
+ LiveShoppingChannel: React.FC<LiveShoppingChannelProps>;
31
+ Inline: React.FC<InlineProps>;
32
+ Floating: React.FC<FloatingProps>;
33
+ }
34
+
35
+
36
+ const VideowiseSDK: VideowiseSDKProps = {
37
+ LiveShoppingChannel: LiveShoppingChannel,
38
+ Inline: Inline,
39
+ Floating: Floating,
40
+ };
41
+
42
+ ## Videowise Live Shopping Channel
43
+
44
+ interface GenericProps<
45
+ T extends 'custom-event' | 'live-shopping' = 'custom-event',
46
+ > {
47
+ onEvent?: (event: OnEventType<T>) => void;
48
+ onAddToCart?: (event: OnEventType<T>) => void;
49
+ onCheckout?: (event: OnEventType<T>) => void;
50
+ environment?: undefined | 'local' | 'staging' | 'production';
51
+ }
52
+
53
+ export interface LiveShoppingChannelProps
54
+ extends GenericProps<'live-shopping'> {
55
+ videowiseInfo: {
56
+ shop: string;
57
+ };
58
+ offsetY?: number; // reduces the height of the component wrapper by FULL - offsetY
59
+ style?: StyleProp<ViewStyle>; // the overidden style of the component wrapper
60
+ }
61
+
62
+ To embed the `Videowise Live Shopping Channel` you need to use `VideowiseSDK.LiveShoppingChannel` component.
63
+
64
+ e.g.
65
+
66
+ <VideowiseSDK.LiveShoppingChannel
67
+ videowiseInfo={{ shop: 'storename.myshopify.com' }}
68
+ environment="staging"
69
+ offsetY={50}
70
+ onEvent={event => {
71
+ console.log('event');
72
+ console.log(event);
73
+ }}
74
+ onAddToCart={event => {
75
+ console.log('add to cart');
76
+ console.log(event);
77
+ }}
78
+ />
79
+
80
+ Here's a list of the possible events triggered inside the `LiveShopping` component -> https://docs.videowise.com/custom-events-ls
@@ -0,0 +1,5 @@
1
+ import React from "react";
2
+ import { FloatingProps } from "../interfaces";
3
+ declare const Floating: React.FC<FloatingProps>;
4
+ export default Floating;
5
+ //# sourceMappingURL=floating.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"floating.d.ts","sourceRoot":"","sources":["../../src/components/floating.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAG9C,QAAA,MAAM,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAyHrC,CAAC;AAEF,eAAe,QAAQ,CAAC"}
@@ -0,0 +1,100 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from "react";
3
+ import { Dimensions, View } from "react-native";
4
+ import WebView from "react-native-webview";
5
+ import { EVENTS } from "../types";
6
+ const Floating = (props) => {
7
+ var _a, _b, _c, _d, _e, _f, _g, _h;
8
+ const [viewStyle, setViewStyle] = React.useState(undefined);
9
+ const previousViewStyle = React.useRef(undefined);
10
+ const assetsUrl = typeof props.environment === "undefined" ||
11
+ props.environment === "production"
12
+ ? "https://assets.videowise.com"
13
+ : "https://staging.riview.app";
14
+ const sourceHtml = `
15
+ <!DOCTYPE html>
16
+ <html style="margin: 0; padding: 0;">
17
+ <head>
18
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
19
+ <script>
20
+ var SKIP_CART = true;
21
+ var FORCE_DOMAIN = true;
22
+ var VIDEOWISE_FAST_INLINE_VIDEO_PLAYER = true;
23
+ var videowiseInfo = {
24
+ cartType: "${(_b = (_a = props.videowiseInfo) === null || _a === void 0 ? void 0 : _a.cartType) !== null && _b !== void 0 ? _b : 'Shopify'}",
25
+ shop: "${props.videowiseInfo.shop}",
26
+ currency: "${(_d = (_c = props.videowiseInfo) === null || _c === void 0 ? void 0 : _c.currency) !== null && _d !== void 0 ? _d : 'USD'}",
27
+ currencyRate: ${(_f = (_e = props.videowiseInfo) === null || _e === void 0 ? void 0 : _e.currencyRate) !== null && _f !== void 0 ? _f : 1},
28
+ pid: ${(_h = (_g = props.videowiseInfo) === null || _g === void 0 ? void 0 : _g.productId) !== null && _h !== void 0 ? _h : null},
29
+ locale: 'en',
30
+ route: '/',
31
+ isReactNative: true,
32
+ forceVideoPlayer: false,
33
+ };
34
+ </script>
35
+ <link rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'" href="${assetsUrl}/style.css.gz" id="videowise-style-css">
36
+ <script defer src="${assetsUrl}/vendors.js.gz" id="videowise-vendors-js"></script>
37
+ <script defer src="${assetsUrl}/client.js.gz" id="videowise-client-js"></script>
38
+ </head>
39
+ <body style="margin: 0; padding: 0;">
40
+ </body>
41
+ </html>
42
+ `;
43
+ const injectedJavaScript = `
44
+ (function() {
45
+ const mutationObserver = new MutationObserver(() => {
46
+ const widgetEl = document.getElementById('reeview-app-widget_${props.widgetId}');
47
+
48
+ if (widgetEl !== null) {
49
+ mutationObserver.disconnect();
50
+
51
+ const resizeObserver = new ResizeObserver(() => {
52
+ window.ReactNativeWebView?.postMessage(
53
+ JSON.stringify({ type: 'WIDGET_BOUNDING_CLIENT_RECT', payload: widgetEl.querySelector('div.vw-cmp__popup-card--root').getBoundingClientRect() })
54
+ );
55
+ });
56
+ resizeObserver.observe(widgetEl);
57
+ }
58
+ });
59
+ mutationObserver.observe(document.documentElement, {
60
+ childList: true,
61
+ subtree: true
62
+ });
63
+ })();
64
+ true;
65
+ `;
66
+ const handleOnMessage = (event) => {
67
+ const dataParsed = JSON.parse(event.nativeEvent.data);
68
+ if (dataParsed.type === "WIDGET_BOUNDING_CLIENT_RECT") {
69
+ const width = dataParsed.payload.width;
70
+ const height = dataParsed.payload.height;
71
+ const right = dataParsed.payload.right;
72
+ if (viewStyle === undefined && width <= Dimensions.get('window').width && height <= Dimensions.get('window').height) {
73
+ previousViewStyle.current = {
74
+ width: width + width + right,
75
+ height: height + width + right,
76
+ position: 'absolute',
77
+ bottom: 0,
78
+ left: 0,
79
+ };
80
+ setViewStyle(previousViewStyle.current);
81
+ }
82
+ }
83
+ else if (dataParsed.type === "custom-event") {
84
+ if (dataParsed.name === EVENTS.videoClick) {
85
+ setViewStyle({
86
+ width: Dimensions.get('window').width,
87
+ height: Dimensions.get('window').height,
88
+ position: 'absolute',
89
+ top: 0,
90
+ right: 0,
91
+ });
92
+ }
93
+ else if (dataParsed.name === EVENTS.playerClose) {
94
+ setViewStyle(previousViewStyle.current);
95
+ }
96
+ }
97
+ };
98
+ return (_jsx(View, { style: viewStyle, children: _jsx(WebView, { source: { html: sourceHtml, baseUrl: assetsUrl }, injectedJavaScript: injectedJavaScript, javaScriptEnabled: true, domStorageEnabled: true, sharedCookiesEnabled: true, thirdPartyCookiesEnabled: true, allowFileAccess: true, allowUniversalAccessFromFileURLs: true, allowFileAccessFromFileURLs: true, allowsFullscreenVideo: false, allowsInlineMediaPlayback: true, scrollEnabled: false, mediaPlaybackRequiresUserAction: false, containerStyle: { flex: 1, backgroundColor: 'transparent' }, style: { flex: 1, backgroundColor: 'transparent' }, showsVerticalScrollIndicator: false, showsHorizontalScrollIndicator: false, onMessage: (event) => handleOnMessage(event) }) }));
99
+ };
100
+ export default Floating;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { InlineProps } from '../interfaces';
3
+ declare const Inline: React.FC<InlineProps>;
4
+ export default Inline;
5
+ //# sourceMappingURL=inline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline.d.ts","sourceRoot":"","sources":["../../src/components/inline.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAK5C,QAAA,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CA0IjC,CAAC;AAEF,eAAe,MAAM,CAAC"}
@@ -0,0 +1,112 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import React from 'react';
3
+ import { View, Dimensions } from 'react-native';
4
+ import WebView from 'react-native-webview';
5
+ import handleOnEventUtil from '../utils/handle-on-event';
6
+ import getNotchHeight from '../utils/get-notch-height';
7
+ import { EVENTS } from '../types';
8
+ const Inline = props => {
9
+ var _a, _b, _c, _d, _e, _f, _g, _h;
10
+ const [viewStyle, setViewStyle] = React.useState({
11
+ width: Dimensions.get('window').width,
12
+ height: 1,
13
+ position: 'static',
14
+ top: undefined,
15
+ left: undefined,
16
+ zIndex: undefined,
17
+ });
18
+ const previousViewHeightRef = React.useRef(0);
19
+ const assetsUrl = typeof props.environment === 'undefined' ||
20
+ props.environment === 'production'
21
+ ? 'https://assets.videowise.com'
22
+ : 'https://staging.riview.app';
23
+ const sourceHtml = `
24
+ <!DOCTYPE html>
25
+ <html style="margin: 0; padding: 0;">
26
+ <head>
27
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
28
+ <script>
29
+ var SKIP_CART=true;
30
+ var FORCE_DOMAIN = true;
31
+ var VIDEOWISE_FAST_INLINE_VIDEO_PLAYER = true;
32
+ var videowiseInfo = {
33
+ cartType: "${(_b = (_a = props.videowiseInfo) === null || _a === void 0 ? void 0 : _a.cartType) !== null && _b !== void 0 ? _b : 'Shopify'}",
34
+ shop: "${props.videowiseInfo.shop}",
35
+ currency: "${(_d = (_c = props.videowiseInfo) === null || _c === void 0 ? void 0 : _c.currency) !== null && _d !== void 0 ? _d : 'USD'}",
36
+ currencyRate: ${(_f = (_e = props.videowiseInfo) === null || _e === void 0 ? void 0 : _e.currencyRate) !== null && _f !== void 0 ? _f : 1},
37
+ pid: ${(_h = (_g = props.videowiseInfo) === null || _g === void 0 ? void 0 : _g.productId) !== null && _h !== void 0 ? _h : null},
38
+ locale: 'en',
39
+ route: '/',
40
+ isReactNative: true,
41
+ forceVideoPlayer: false,
42
+ };
43
+ </script>
44
+ <link rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'" href="${assetsUrl}/style.css.gz" id="videowise-style-css">
45
+ <script defer src="${assetsUrl}/vendors.js.gz" id="videowise-vendors-js"></script>
46
+ <script defer src="${assetsUrl}/client.js.gz" id="videowise-client-js"></script>
47
+ </head>
48
+ <body style="margin: 0; padding: 0;">
49
+ <div class="reeview-app-widget" id="reeview-app-widget_${props.widgetId}"></div>
50
+ </body>
51
+ </html>
52
+ `;
53
+ const injectedJavaScript = `
54
+ (function() {
55
+ const mutationObserver = new MutationObserver(() => {
56
+ const widgetEl = document.getElementById('reeview-app-widget_${props.widgetId}');
57
+
58
+ if (widgetEl !== null) {
59
+ mutationObserver.disconnect();
60
+
61
+ const resizeObserver = new ResizeObserver(() => {
62
+ window.ReactNativeWebView?.postMessage(
63
+ JSON.stringify({ type: 'WIDGET_BOUNDING_CLIENT_RECT', payload: widgetEl.getBoundingClientRect() })
64
+ );
65
+ });
66
+ resizeObserver.observe(widgetEl);
67
+ }
68
+ });
69
+ mutationObserver.observe(document.documentElement, {
70
+ childList: true,
71
+ subtree: true
72
+ });
73
+ })();
74
+ true;
75
+ `;
76
+ const handleOnMessage = (event) => {
77
+ var _a, _b;
78
+ const dataParsed = JSON.parse(event.nativeEvent.data);
79
+ if (dataParsed.type === 'WIDGET_BOUNDING_CLIENT_RECT') {
80
+ previousViewHeightRef.current = dataParsed.payload.height;
81
+ setViewStyle({
82
+ width: Number(dataParsed.payload.width),
83
+ height: Number(dataParsed.payload.height),
84
+ });
85
+ }
86
+ else if (dataParsed.type === 'custom-event') {
87
+ handleOnEventUtil(event, props.onEvent, props.onAddToCart, props.onCheckout);
88
+ if ([EVENTS.videoClick, EVENTS.productClick].includes(dataParsed.name) === true) {
89
+ setViewStyle({
90
+ width: Dimensions.get('window').width,
91
+ height: Dimensions.get('window').height - getNotchHeight(),
92
+ position: 'absolute',
93
+ top: getNotchHeight() + ((_b = (_a = props.scrollY) === null || _a === void 0 ? void 0 : _a.current) !== null && _b !== void 0 ? _b : 0),
94
+ left: 0,
95
+ zIndex: 9,
96
+ });
97
+ }
98
+ else if (dataParsed.name === EVENTS.playerClose) {
99
+ setViewStyle({
100
+ width: Dimensions.get('window').width,
101
+ height: previousViewHeightRef.current,
102
+ position: 'static',
103
+ top: undefined,
104
+ left: undefined,
105
+ zIndex: undefined,
106
+ });
107
+ }
108
+ }
109
+ };
110
+ return (_jsx(View, { style: viewStyle, children: _jsx(WebView, { source: { html: sourceHtml, baseUrl: assetsUrl }, injectedJavaScript: injectedJavaScript, javaScriptEnabled: true, domStorageEnabled: true, sharedCookiesEnabled: true, thirdPartyCookiesEnabled: true, allowFileAccess: true, allowUniversalAccessFromFileURLs: true, allowFileAccessFromFileURLs: true, allowsFullscreenVideo: false, allowsInlineMediaPlayback: true, scrollEnabled: false, mediaPlaybackRequiresUserAction: false, containerStyle: { flex: 1, backgroundColor: 'transparent' }, style: { flex: 1, backgroundColor: 'transparent' }, showsVerticalScrollIndicator: false, showsHorizontalScrollIndicator: false, onMessage: event => handleOnMessage(event) }) }));
111
+ };
112
+ export default Inline;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { LiveShoppingChannelProps } from '../interfaces';
3
+ declare const LiveShoppingChannel: React.FC<LiveShoppingChannelProps>;
4
+ export default LiveShoppingChannel;
5
+ //# sourceMappingURL=live-shopping-channel.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"live-shopping-channel.d.ts","sourceRoot":"","sources":["../../src/components/live-shopping-channel.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,wBAAwB,EAAE,MAAM,eAAe,CAAC;AAQzD,QAAA,MAAM,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CA0F3D,CAAC;AAEF,eAAe,mBAAmB,CAAC"}
@@ -0,0 +1,72 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { View, Dimensions } from 'react-native';
3
+ import WebView from 'react-native-webview';
4
+ import { LSWidgetInteractionType, } from '../types';
5
+ import unifyLsProduct from '../utils/unify-ls-product';
6
+ const LiveShoppingChannel = props => {
7
+ var _a;
8
+ const { style, offsetY } = props;
9
+ const assetsUrl = props.environment === 'local'
10
+ ? 'https://ls-dev-gabi.ngrok.io'
11
+ : props.environment === 'staging'
12
+ ? 'https://staging.riview.app'
13
+ : 'https://assets.videowise.com';
14
+ const sourceHtml = `
15
+ <!DOCTYPE html>
16
+ <html>
17
+ <head>
18
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
19
+ <script>
20
+ var videowiseInfo = {
21
+ cartType: 'Shopify',
22
+ shop: "${props.videowiseInfo.shop}",
23
+ host: "${props.videowiseInfo.shop}",
24
+ currency:'USD',
25
+ currencyRate:'1',
26
+ pid: null,
27
+ locale: 'en',
28
+ route: '/',
29
+ isReactNative: true,
30
+ forceVideoPlayer: false,
31
+ };
32
+ window.isInsideRNWebview=true
33
+ </script>
34
+ <link rel="preload" href="${assetsUrl}/videowise-live-streaming-channel-embed.js" as="script">
35
+ <script src="${assetsUrl}/videowise-live-streaming-channel-embed.js"></script>
36
+
37
+ </head>
38
+ <body>
39
+ <div id="videowise_stream_channel"/>
40
+ </body>
41
+ </html>
42
+ `;
43
+ const handleOnMessage = (event) => {
44
+ var _a, _b;
45
+ const dataParsed = JSON.parse(event.nativeEvent.data);
46
+ if ((dataParsed === null || dataParsed === void 0 ? void 0 : dataParsed.request) === 'LIVE_STREAM_DISPATCH_CUSTOM_EVENT') {
47
+ const lsCustomEvent = dataParsed.payload.data;
48
+ let unifiedProduct;
49
+ if (lsCustomEvent.interactionType === LSWidgetInteractionType.AddToCart ||
50
+ lsCustomEvent.interactionType === LSWidgetInteractionType.ProductClick) {
51
+ unifiedProduct = unifyLsProduct(lsCustomEvent.item);
52
+ }
53
+ (_a = props.onEvent) === null || _a === void 0 ? void 0 : _a.call(props, {
54
+ type: 'live-shopping',
55
+ detail: lsCustomEvent,
56
+ });
57
+ if (lsCustomEvent.interactionType === LSWidgetInteractionType.AddToCart) {
58
+ const unifiedProduct = unifyLsProduct(lsCustomEvent.item);
59
+ (_b = props.onAddToCart) === null || _b === void 0 ? void 0 : _b.call(props, {
60
+ type: 'add-to-cart',
61
+ detail: unifiedProduct,
62
+ });
63
+ }
64
+ }
65
+ };
66
+ const SCREEN_HEIGHT = (_a = Dimensions.get('window')) === null || _a === void 0 ? void 0 : _a.height;
67
+ return (_jsx(View, { style: {
68
+ height: SCREEN_HEIGHT - (offsetY || 0),
69
+ ...style,
70
+ }, children: _jsx(WebView, { source: { html: sourceHtml, baseUrl: assetsUrl }, javaScriptEnabled: true, domStorageEnabled: true, sharedCookiesEnabled: true, thirdPartyCookiesEnabled: true, allowFileAccess: true, allowUniversalAccessFromFileURLs: true, allowFileAccessFromFileURLs: true, allowsFullscreenVideo: false, allowsInlineMediaPlayback: true, scrollEnabled: true, mediaPlaybackRequiresUserAction: false, onMessage: event => handleOnMessage(event) }) }));
71
+ };
72
+ export default LiveShoppingChannel;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { ModalVideoProps } from '../interfaces';
3
+ declare const ModalVideo: React.FC<ModalVideoProps>;
4
+ export default ModalVideo;
5
+ //# sourceMappingURL=modal-video.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal-video.d.ts","sourceRoot":"","sources":["../../src/components/modal-video.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAGhD,QAAA,MAAM,UAAU,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAczC,CAAA;AAED,eAAe,UAAU,CAAA"}
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Modal } from 'react-native';
3
+ import VideoFeed from './video-feed';
4
+ const ModalVideo = (props) => {
5
+ var _a;
6
+ return (_jsx(Modal, { visible: props.modalVideo.widgetId !== null, animationType: "none", children: _jsx(VideoFeed, { videowiseInfo: props.videowiseInfo, widgetId: (_a = props.modalVideo.widgetId) !== null && _a !== void 0 ? _a : '', environment: props.environment }) }));
7
+ };
8
+ export default ModalVideo;
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import { VideoFeedProps } from '../interfaces';
3
+ declare const VideoFeed: React.FC<VideoFeedProps>;
4
+ export default VideoFeed;
5
+ //# sourceMappingURL=video-feed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"video-feed.d.ts","sourceRoot":"","sources":["../../src/components/video-feed.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAG/C,QAAA,MAAM,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAmFvC,CAAC;AAEF,eAAe,SAAS,CAAC"}
@@ -0,0 +1,55 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { View, Dimensions } from 'react-native';
3
+ import WebView from 'react-native-webview';
4
+ import handleOnEventUtil from '../utils/handle-on-event';
5
+ const VideoFeed = props => {
6
+ var _a, _b, _c, _d, _e, _f, _g, _h;
7
+ const viewStyle = {
8
+ width: Dimensions.get('window').width,
9
+ height: Dimensions.get('window').height,
10
+ position: 'static',
11
+ ...props.style,
12
+ };
13
+ const assetsUrl = typeof props.environment === 'undefined' ||
14
+ props.environment === 'production'
15
+ ? 'https://assets.videowise.com'
16
+ : 'https://staging.riview.app';
17
+ const sourceHtml = `
18
+ <!DOCTYPE html>
19
+ <html style="margin: 0; padding: 0;">
20
+ <head>
21
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
22
+ <script>
23
+ var SKIP_CART=true;
24
+ var FORCE_DOMAIN = true;
25
+ var VIDEOWISE_FAST_INLINE_VIDEO_PLAYER = true;
26
+ var videowiseInfo = {
27
+ cartType: "${(_b = (_a = props.videowiseInfo) === null || _a === void 0 ? void 0 : _a.cartType) !== null && _b !== void 0 ? _b : 'Shopify'}",
28
+ shop: "${props.videowiseInfo.shop}",
29
+ currency: "${(_d = (_c = props.videowiseInfo) === null || _c === void 0 ? void 0 : _c.currency) !== null && _d !== void 0 ? _d : 'USD'}",
30
+ currencyRate: ${(_f = (_e = props.videowiseInfo) === null || _e === void 0 ? void 0 : _e.currencyRate) !== null && _f !== void 0 ? _f : 1},
31
+ pid: ${(_h = (_g = props.videowiseInfo) === null || _g === void 0 ? void 0 : _g.productId) !== null && _h !== void 0 ? _h : null},
32
+ locale: 'en',
33
+ route: '/',
34
+ isReactNative: true,
35
+ forceVideoPlayer: true,
36
+ };
37
+ </script>
38
+ <link rel="preload" as="style" onload="this.onload=null;this.rel='stylesheet'" href="${assetsUrl}/style.css.gz" id="videowise-style-css">
39
+ <script defer src="${assetsUrl}/vendors.js.gz" id="videowise-vendors-js"></script>
40
+ <script defer src="${assetsUrl}/client.js.gz" id="videowise-client-js"></script>
41
+ </head>
42
+ <body style="margin: 0; padding: 0;">
43
+ <div class="reeview-app-widget" id="reeview-app-widget_${props.widgetId}" style="opacity: 0;"></div>
44
+ </body>
45
+ </html>
46
+ `;
47
+ const handleOnMessage = (event) => {
48
+ const dataParsed = JSON.parse(event.nativeEvent.data);
49
+ if (dataParsed.type === 'custom-event') {
50
+ handleOnEventUtil(event, props.onEvent, props.onAddToCart, props.onCheckout);
51
+ }
52
+ };
53
+ return (_jsx(View, { style: viewStyle, children: _jsx(WebView, { source: { html: sourceHtml, baseUrl: assetsUrl }, javaScriptEnabled: true, domStorageEnabled: true, sharedCookiesEnabled: true, thirdPartyCookiesEnabled: true, allowFileAccess: true, allowUniversalAccessFromFileURLs: true, allowFileAccessFromFileURLs: true, allowsFullscreenVideo: false, allowsInlineMediaPlayback: true, scrollEnabled: false, mediaPlaybackRequiresUserAction: false, containerStyle: { flex: 1 }, style: { flex: 1 }, showsVerticalScrollIndicator: false, showsHorizontalScrollIndicator: false, onMessage: event => handleOnMessage(event) }) }));
54
+ };
55
+ export default VideoFeed;
package/lib/index.d.ts ADDED
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import { FloatingProps, InlineProps, VideoFeedProps, LiveShoppingChannelProps } from './interfaces';
3
+ interface VideowiseSDKProps {
4
+ Inline: React.FC<InlineProps>;
5
+ Floating: React.FC<FloatingProps>;
6
+ VideoFeed: React.FC<VideoFeedProps>;
7
+ LiveShoppingChannel: React.FC<LiveShoppingChannelProps>;
8
+ }
9
+ declare const VideowiseSDK: VideowiseSDKProps;
10
+ export default VideowiseSDK;
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,EACL,aAAa,EACb,WAAW,EACX,cAAc,EACd,wBAAwB,EACzB,MAAM,cAAc,CAAC;AAEtB,UAAU,iBAAiB;IACzB,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;IAClC,SAAS,EAAE,KAAK,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC;IACpC,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC;CACzD;AAED,QAAA,MAAM,YAAY,EAAE,iBAKnB,CAAC;AAEF,eAAe,YAAY,CAAC"}
package/lib/index.js ADDED
@@ -0,0 +1,11 @@
1
+ import Inline from './components/inline';
2
+ import Floating from './components/floating';
3
+ import VideoFeed from './components/video-feed';
4
+ import LiveShoppingChannel from './components/live-shopping-channel';
5
+ const VideowiseSDK = {
6
+ Inline: Inline,
7
+ Floating: Floating,
8
+ VideoFeed: VideoFeed,
9
+ LiveShoppingChannel: LiveShoppingChannel,
10
+ };
11
+ export default VideowiseSDK;
@@ -0,0 +1,67 @@
1
+ import { StyleProp, ViewStyle } from 'react-native';
2
+ import { EventTypeName, OnEventType } from './types';
3
+ export interface VideowiseSDKProps {
4
+ Inline: React.FC<InlineProps>;
5
+ Floating: React.FC<FloatingProps>;
6
+ LiveShoppingChannel: React.FC<LiveShoppingChannelProps>;
7
+ }
8
+ interface GenericProps<T extends EventTypeName = 'custom-event'> {
9
+ onEvent?: (event: OnEventType<T>) => void;
10
+ onAddToCart?: (event: OnEventType<'add-to-cart'>) => void;
11
+ onCheckout?: (event: OnEventType<T>) => void;
12
+ environment?: undefined | 'local' | 'staging' | 'production';
13
+ }
14
+ export interface InlineProps extends GenericProps {
15
+ videowiseInfo: {
16
+ cartType?: undefined | 'Shopify' | 'Magento' | 'SFCC' | 'Tapcart' | 'Other';
17
+ shop: string;
18
+ currency?: undefined | string;
19
+ currencyRate?: undefined | number;
20
+ productId?: undefined | null | number;
21
+ };
22
+ widgetId: string;
23
+ scrollY?: undefined | React.RefObject<number>;
24
+ }
25
+ export interface VideoFeedProps extends GenericProps {
26
+ videowiseInfo: {
27
+ cartType?: undefined | 'Shopify' | 'Magento' | 'SFCC' | 'Tapcart' | 'Other';
28
+ shop: string;
29
+ currency?: undefined | string;
30
+ currencyRate?: undefined | number;
31
+ productId?: undefined | null | number;
32
+ };
33
+ widgetId: string;
34
+ style?: undefined | StyleProp<ViewStyle>;
35
+ }
36
+ export interface FloatingProps extends GenericProps {
37
+ videowiseInfo: {
38
+ cartType?: undefined | 'Shopify' | 'Magento' | 'SFCC' | 'Tapcart' | 'Other';
39
+ shop: string;
40
+ currency?: undefined | string;
41
+ currencyRate?: undefined | number;
42
+ productId?: undefined | null | number;
43
+ };
44
+ widgetId: string;
45
+ }
46
+ /**
47
+ * The offsetYreduces the height of the component wrapper by FULL - offsetY
48
+ * @type {number}
49
+ */
50
+ export type LSWrapperOffsetY = number;
51
+ export interface LiveShoppingChannelProps extends GenericProps<'live-shopping'> {
52
+ videowiseInfo: {
53
+ /**
54
+ * The shop name to fetch the Live Shopping Channel from
55
+ * @type {string}
56
+ */
57
+ shop: string;
58
+ };
59
+ offsetY?: LSWrapperOffsetY;
60
+ /**
61
+ * The overidden style of the component wrapper
62
+ * @type {number}
63
+ */
64
+ style?: StyleProp<ViewStyle>;
65
+ }
66
+ export {};
67
+ //# sourceMappingURL=interfaces.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interfaces.d.ts","sourceRoot":"","sources":["../src/interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEpD,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAErD,MAAM,WAAW,iBAAiB;IAChC,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC;IAC9B,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC;IAClC,mBAAmB,EAAE,KAAK,CAAC,EAAE,CAAC,wBAAwB,CAAC,CAAC;CACzD;AAED,UAAU,YAAY,CAAC,CAAC,SAAS,aAAa,GAAG,cAAc;IAC7D,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAC1C,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,aAAa,CAAC,KAAK,IAAI,CAAC;IAC1D,UAAU,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC;IAC7C,WAAW,CAAC,EAAE,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,YAAY,CAAC;CAC9D;AAED,MAAM,WAAW,WAAY,SAAQ,YAAY;IAC/C,aAAa,EAAE;QACb,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;QAC5E,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;QAC9B,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;QAClC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,CAAC;KACvC,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,cAAe,SAAQ,YAAY;IAClD,aAAa,EAAE;QACb,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;QAC5E,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;QAC9B,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;QAClC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,CAAC;KACvC,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;CAC1C;AAED,MAAM,WAAW,aAAc,SAAQ,YAAY;IACjD,aAAa,EAAE;QACb,QAAQ,CAAC,EAAE,SAAS,GAAG,SAAS,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;QAC5E,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;QAC9B,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;QAClC,SAAS,CAAC,EAAE,SAAS,GAAG,IAAI,GAAG,MAAM,CAAC;KACvC,CAAC;IACF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;GAGG;AACH,MAAM,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEtC,MAAM,WAAW,wBACf,SAAQ,YAAY,CAAC,eAAe,CAAC;IACrC,aAAa,EAAE;QACb;;;WAGG;QACH,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;IAEF,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CAC9B"}
@@ -0,0 +1 @@
1
+ export {};
package/lib/types.d.ts ADDED
@@ -0,0 +1,136 @@
1
+ export declare const EVENTS: {
2
+ readonly widgetLoaded: "videowise:widgetLoaded";
3
+ readonly productAddToCart: "videowiseProductAddToCart";
4
+ readonly productBuyNow: "videowiseProductBuyNow";
5
+ readonly checkoutClick: "videowiseCheckoutClick";
6
+ readonly productClick: "videowiseProductClick";
7
+ readonly videoClick: "videowiseVideoClick";
8
+ readonly videoStart: "videowiseVideoStart";
9
+ readonly videoIsPlaying: "videowiseVideoIsPlaying";
10
+ readonly videoFull: "videowiseVideoFull";
11
+ readonly videoSwipe: "videowiseVideoSwipe";
12
+ readonly playerClose: "videowisePlayerClose";
13
+ readonly videoSoundOn: "videowiseVideoSoundOn";
14
+ readonly videoSoundOff: "videowiseVideoSoundOff";
15
+ readonly videoBounce: "videowiseVideoBounce";
16
+ readonly dataReady: "videowiseDataReady";
17
+ readonly campaignReady: "videowiseCampaignReady";
18
+ readonly campaignCheckout: "videowiseCampaignCheckout";
19
+ readonly backgroundV2Rendered: "videowiseBackgroundV2Rendered";
20
+ readonly ctaClick: "videowiseCtaClick";
21
+ readonly triggerPlayerClose: "videowiseTriggerPlayerClose";
22
+ };
23
+ export type EventType = (typeof EVENTS)[keyof typeof EVENTS];
24
+ export type EventDetailType = {
25
+ productName?: undefined | string;
26
+ productId?: undefined | number;
27
+ variantId?: undefined | number;
28
+ selectedVariant?: undefined | number;
29
+ qty?: undefined | number;
30
+ price?: undefined | number;
31
+ currencyCode?: undefined | string;
32
+ videoTitle?: undefined | string;
33
+ videoId?: undefined | string;
34
+ widgetId?: undefined | string;
35
+ deviceType?: undefined | string;
36
+ url?: undefined | string;
37
+ campaignId?: undefined | string;
38
+ items?: undefined | {
39
+ productName?: undefined | string;
40
+ productId?: undefined | number;
41
+ qty?: undefined | number;
42
+ price?: undefined | number;
43
+ currencyCode?: undefined | string;
44
+ }[];
45
+ };
46
+ export type EventTypeName = 'custom-event' | 'add-to-cart' | 'live-shopping' | 'widget';
47
+ export type OnEventType<T extends EventTypeName> = T extends 'custom-event' ? {
48
+ type: T;
49
+ detail: EventDetailType;
50
+ name: EventType;
51
+ targetTag: null;
52
+ } : T extends 'add-to-cart' ? {
53
+ type: T;
54
+ detail: EventDetailType;
55
+ } : T extends 'live-shopping' ? {
56
+ type: T;
57
+ detail: LSTrackingEventData;
58
+ } : T extends 'widget' ? {
59
+ type: T;
60
+ detail: EventDetailType;
61
+ } : unknown;
62
+ export declare const LSSettingsDeviceType: {
63
+ readonly Mobile: "mobile";
64
+ readonly Desktop: "desktop";
65
+ };
66
+ export type LSSettingsDeviceType = (typeof LSSettingsDeviceType)[keyof typeof LSSettingsDeviceType];
67
+ export declare const LSWidgetInteractionType: {
68
+ readonly MutePlayer: "mute_player";
69
+ readonly UnmutePlayer: "unmute_player";
70
+ readonly PausePlayer: "pause_player";
71
+ readonly ResumePlayer: "resume_player";
72
+ readonly Like: "like_reaction";
73
+ readonly Share: "share";
74
+ readonly AddToCalendar: "add_to_calendar";
75
+ readonly SendChat: "send_chat";
76
+ readonly ClosePlayer: "close_player";
77
+ readonly MinimizePlayer: "minimize_player";
78
+ readonly MaximizePlayer: "maximize_player";
79
+ readonly ShowProductList: "show_product_list";
80
+ readonly HideProductList: "hide_product_list";
81
+ readonly ProductClick: "product_click";
82
+ readonly AddToCart: "add_to_cart";
83
+ readonly Checkout: "checkout";
84
+ readonly ShowCart: "show_cart";
85
+ readonly HideCart: "hide_cart";
86
+ readonly ToggleCCOn: "toggle_cc_on";
87
+ readonly ToggleCCOff: "toggle_cc_off";
88
+ readonly Replay: "replay";
89
+ readonly Progress: "progress";
90
+ };
91
+ export type LSWidgetInteractionType = (typeof LSWidgetInteractionType)[keyof typeof LSWidgetInteractionType];
92
+ export declare const LSHostEventType: {
93
+ readonly Play: "play";
94
+ readonly Pause: "pause";
95
+ readonly Stop: "stop";
96
+ readonly Load: "load";
97
+ readonly Pending: "pending";
98
+ readonly Interaction: "interaction";
99
+ };
100
+ export type LSHostEventType = (typeof LSHostEventType)[keyof typeof LSHostEventType];
101
+ export type LSTrackingProductSchemaType = {
102
+ name?: string;
103
+ sku?: string;
104
+ id?: string;
105
+ highlighted?: boolean;
106
+ meta?: {
107
+ customId?: string;
108
+ vendor?: string;
109
+ price?: number | string;
110
+ compareAtPrice?: unknown;
111
+ quantity: number;
112
+ currency: string;
113
+ };
114
+ };
115
+ export type LSTrackingEventData = {
116
+ lsId: string;
117
+ siteId: string;
118
+ organisationId: string;
119
+ clientTS: Date;
120
+ videoElapsedMinutes: number;
121
+ videoElapsedSeconds: number;
122
+ currentTime?: number;
123
+ uid: string;
124
+ device: LSSettingsDeviceType;
125
+ isLive: boolean;
126
+ url: string;
127
+ interactionType: LSWidgetInteractionType;
128
+ eventType: LSHostEventType;
129
+ } & ({
130
+ interactionType?: typeof LSWidgetInteractionType.AddToCart;
131
+ item?: LSTrackingProductSchemaType;
132
+ } | {
133
+ LiveStreamProduct?: typeof LSWidgetInteractionType.ProductClick;
134
+ item?: LSTrackingProductSchemaType;
135
+ });
136
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/lib/types.js ADDED
@@ -0,0 +1,58 @@
1
+ export const EVENTS = {
2
+ widgetLoaded: 'videowise:widgetLoaded',
3
+ productAddToCart: 'videowiseProductAddToCart',
4
+ productBuyNow: 'videowiseProductBuyNow',
5
+ checkoutClick: 'videowiseCheckoutClick',
6
+ productClick: 'videowiseProductClick',
7
+ videoClick: 'videowiseVideoClick',
8
+ videoStart: 'videowiseVideoStart',
9
+ videoIsPlaying: 'videowiseVideoIsPlaying',
10
+ videoFull: 'videowiseVideoFull',
11
+ videoSwipe: 'videowiseVideoSwipe',
12
+ playerClose: 'videowisePlayerClose',
13
+ videoSoundOn: 'videowiseVideoSoundOn',
14
+ videoSoundOff: 'videowiseVideoSoundOff',
15
+ videoBounce: 'videowiseVideoBounce',
16
+ dataReady: 'videowiseDataReady',
17
+ campaignReady: 'videowiseCampaignReady',
18
+ campaignCheckout: 'videowiseCampaignCheckout',
19
+ backgroundV2Rendered: 'videowiseBackgroundV2Rendered',
20
+ ctaClick: 'videowiseCtaClick',
21
+ triggerPlayerClose: 'videowiseTriggerPlayerClose',
22
+ };
23
+ export const LSSettingsDeviceType = {
24
+ Mobile: 'mobile',
25
+ Desktop: 'desktop',
26
+ };
27
+ export const LSWidgetInteractionType = {
28
+ MutePlayer: 'mute_player',
29
+ UnmutePlayer: 'unmute_player',
30
+ PausePlayer: 'pause_player',
31
+ ResumePlayer: 'resume_player',
32
+ Like: 'like_reaction',
33
+ Share: 'share',
34
+ AddToCalendar: 'add_to_calendar',
35
+ SendChat: 'send_chat',
36
+ ClosePlayer: 'close_player',
37
+ MinimizePlayer: 'minimize_player',
38
+ MaximizePlayer: 'maximize_player',
39
+ ShowProductList: 'show_product_list',
40
+ HideProductList: 'hide_product_list',
41
+ ProductClick: 'product_click',
42
+ AddToCart: 'add_to_cart',
43
+ Checkout: 'checkout',
44
+ ShowCart: 'show_cart',
45
+ HideCart: 'hide_cart',
46
+ ToggleCCOn: 'toggle_cc_on',
47
+ ToggleCCOff: 'toggle_cc_off',
48
+ Replay: 'replay',
49
+ Progress: 'progress',
50
+ };
51
+ export const LSHostEventType = {
52
+ Play: 'play',
53
+ Pause: 'pause',
54
+ Stop: 'stop',
55
+ Load: 'load',
56
+ Pending: 'pending',
57
+ Interaction: 'interaction',
58
+ };
@@ -0,0 +1,2 @@
1
+ export default function getNotchHeight(): number;
2
+ //# sourceMappingURL=get-notch-height.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"get-notch-height.d.ts","sourceRoot":"","sources":["../../src/utils/get-notch-height.ts"],"names":[],"mappings":"AA6BA,MAAM,CAAC,OAAO,UAAU,cAAc,WAerC"}
@@ -0,0 +1,36 @@
1
+ import { Platform, StatusBar, Dimensions } from "react-native";
2
+ const { width, height } = Dimensions.get('window');
3
+ const IPHONE_HEIGHTS = {
4
+ // iPhone 14 Pro, 15, 15 Pro, 16
5
+ IPHONE_PRO_STANDARD: 852,
6
+ // iPhone 14 Pro Max, 15 Plus, 15 Pro Max, 16 Plus, 16 Pro Max
7
+ IPHONE_PRO_MAX: 932,
8
+ // iPhone 12, 12 Pro, 13, 13 Pro, 14
9
+ IPHONE_12_13_14: 844,
10
+ // iPhone 12 Pro Max, 13 Pro Max
11
+ IPHONE_12_13_MAX: 926,
12
+ // iPhone 11, XR, XS Max
13
+ IPHONE_XR_XS_MAX: 896,
14
+ // iPhone X, XS, 11 Pro, 12 mini, 13 mini
15
+ IPHONE_X_XS_MINI: 812,
16
+ // iPhone 16 Pro (Specific display scaling)
17
+ IPHONE_16_PRO: 874,
18
+ };
19
+ const hasNotch = () => {
20
+ if (Platform.OS !== 'ios' || Platform.isPad || Platform.isTV)
21
+ return false;
22
+ return Object.values(IPHONE_HEIGHTS).some((h) => h === height || h === width);
23
+ };
24
+ export default function getNotchHeight() {
25
+ if (Platform.OS === 'android') {
26
+ return StatusBar.currentHeight || 0;
27
+ }
28
+ if (!hasNotch()) {
29
+ return 20;
30
+ }
31
+ if (height >= 852 || width >= 852) {
32
+ return 59;
33
+ }
34
+ // Classic Notch models (iPhone X through 14)
35
+ return 44;
36
+ }
@@ -0,0 +1,4 @@
1
+ import { WebViewMessageEvent } from 'react-native-webview';
2
+ import { EventTypeName, OnEventType } from '../types';
3
+ export default function handleOnEventUtil<T extends EventTypeName>(event: WebViewMessageEvent, propsOnEvent?: (event: OnEventType<T>) => void, propsOnAddToCart?: (event: OnEventType<'add-to-cart'>) => void, propsOnCheckout?: (event: OnEventType<T>) => void): void;
4
+ //# sourceMappingURL=handle-on-event.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handle-on-event.d.ts","sourceRoot":"","sources":["../../src/utils/handle-on-event.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAqB,aAAa,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAEzE,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,CAAC,SAAS,aAAa,EAC/D,KAAK,EAAE,mBAAmB,EAC1B,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,EAC9C,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,aAAa,CAAC,KAAK,IAAI,EAC9D,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,KAAK,IAAI,QAyBlD"}
@@ -0,0 +1,19 @@
1
+ import { EVENTS } from '../types';
2
+ export default function handleOnEventUtil(event, propsOnEvent, propsOnAddToCart, propsOnCheckout) {
3
+ const dataParsed = JSON.parse(event.nativeEvent.data);
4
+ const dataParsedName = dataParsed.name;
5
+ const eventValues = Object.values(EVENTS);
6
+ if (eventValues.includes(dataParsedName) === true) {
7
+ if (typeof propsOnEvent !== 'undefined') {
8
+ propsOnEvent(dataParsed);
9
+ }
10
+ if (typeof propsOnAddToCart !== 'undefined' &&
11
+ dataParsedName === 'videowiseProductAddToCart') {
12
+ propsOnAddToCart(dataParsed);
13
+ }
14
+ if (typeof propsOnCheckout !== 'undefined' &&
15
+ dataParsedName === 'videowiseCheckoutClick') {
16
+ propsOnCheckout(dataParsed);
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,2 @@
1
+ export default function injectedJavaScriptUtil(widgetId: string): string;
2
+ //# sourceMappingURL=injected-javascript.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"injected-javascript.d.ts","sourceRoot":"","sources":["../../src/utils/injected-javascript.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAAC,QAAQ,EAAE,MAAM,UAwB9D"}
@@ -0,0 +1,26 @@
1
+ export default function injectedJavaScriptUtil(widgetId) {
2
+ return `
3
+ (function() {
4
+ const mutationObserver = new MutationObserver(() => {
5
+ const floatingEl = document.getElementById('reeview-app-widget_${widgetId}');
6
+
7
+ if (floatingEl !== null) {
8
+ mutationObserver.disconnect();
9
+
10
+ const resizeObserver = new ResizeObserver(() => {
11
+ window.ReactNativeWebView?.postMessage(
12
+ JSON.stringify({ type: 'WIDGET_BOUNDING_CLIENT_RECT', payload: floatingEl.getBoundingClientRect() })
13
+ );
14
+ });
15
+ resizeObserver.observe(floatingEl);
16
+ }
17
+ });
18
+ mutationObserver.observe(document.documentElement, {
19
+ childList: true,
20
+ subtree: true
21
+ });
22
+ })();
23
+ true;
24
+ `;
25
+ }
26
+ ;
@@ -0,0 +1,3 @@
1
+ import { EventDetailType, LSTrackingProductSchemaType } from '../types';
2
+ export default function (product: LSTrackingProductSchemaType): EventDetailType;
3
+ //# sourceMappingURL=unify-ls-product.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"unify-ls-product.d.ts","sourceRoot":"","sources":["../../src/utils/unify-ls-product.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,2BAA2B,EAAE,MAAM,UAAU,CAAC;AAExE,MAAM,CAAC,OAAO,WACZ,OAAO,EAAE,2BAA2B,GACnC,eAAe,CAajB"}
@@ -0,0 +1,15 @@
1
+ export default function (product) {
2
+ var _a, _b, _c, _d, _e, _f, _g, _h;
3
+ return {
4
+ productName: product.name,
5
+ variantId: ((_a = product.meta) === null || _a === void 0 ? void 0 : _a.customId)
6
+ ? Number((_b = product.meta) === null || _b === void 0 ? void 0 : _b.customId)
7
+ : undefined,
8
+ selectedVariant: ((_c = product.meta) === null || _c === void 0 ? void 0 : _c.customId)
9
+ ? Number((_d = product.meta) === null || _d === void 0 ? void 0 : _d.customId)
10
+ : undefined,
11
+ qty: (_e = product.meta) === null || _e === void 0 ? void 0 : _e.quantity,
12
+ price: ((_f = product.meta) === null || _f === void 0 ? void 0 : _f.price) ? Number((_g = product.meta) === null || _g === void 0 ? void 0 : _g.price) : undefined,
13
+ currencyCode: (_h = product.meta) === null || _h === void 0 ? void 0 : _h.currency,
14
+ };
15
+ }
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@videowisehq/videowise-react-native-sdk",
3
+ "version": "1.3.1",
4
+ "private": false,
5
+ "description": "VideoWise SDK for React Native applications.",
6
+ "keywords": [
7
+ "react-native",
8
+ "ios",
9
+ "android",
10
+ "videowise",
11
+ "sdk",
12
+ "webview"
13
+ ],
14
+ "homepage": "https://github.com/vidystar/react-native-sdk",
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "git+https://github.com/vidystar/react-native-sdk.git"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/vidystar/react-native-sdk/issues"
21
+ },
22
+ "license": "MIT",
23
+ "author": "Vidystar <support@vidystar.com>",
24
+ "main": "lib/index.js",
25
+ "types": "lib/index.d.ts",
26
+ "files": [
27
+ "lib",
28
+ "LICENSE"
29
+ ],
30
+ "scripts": {
31
+ "build": "tsc -p tsconfig.build.json",
32
+ "dev": "tsc -p tsconfig.build.json -w",
33
+ "start": "npm run dev",
34
+ "lint": "eslint .",
35
+ "test": "jest",
36
+ "dev:doctor": "cd example && npx react-native doctor",
37
+ "dev:install": "cd example && npm i --no-workspaces",
38
+ "dev:install:ios": "cd example/ios && pod install",
39
+ "dev:start": "npm -w example start",
40
+ "dev:ios": "cd example && npm run ios",
41
+ "dev:android": "cd example && npm run android",
42
+ "prepublishOnly": "npm run build"
43
+ },
44
+ "peerDependencies": {
45
+ "react": "*",
46
+ "react-native": "*",
47
+ "react-native-webview": "*"
48
+ },
49
+ "devDependencies": {
50
+ "typescript": "^5.8.3",
51
+ "@types/react": "^19.2.0",
52
+ "@types/react-native": "^0.72.8",
53
+ "eslint": "^8.19.0",
54
+ "jest": "^29.6.3",
55
+ "prettier": "2.8.8",
56
+ "react-native-webview": "^13.16.0"
57
+ },
58
+ "publishConfig": {
59
+ "access": "public"
60
+ },
61
+ "engines": {
62
+ "node": ">=20"
63
+ }
64
+ }