@capillarytech/creatives-library 8.0.242-alpha.10 → 8.0.242-alpha.11
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/assets/Android.png +0 -0
- package/assets/iOS.png +0 -0
- package/config/app.js +1 -1
- package/constants/unified.js +2 -2
- package/initialReducer.js +0 -2
- package/package.json +1 -1
- package/services/api.js +5 -10
- package/services/tests/api.test.js +0 -18
- package/translations/en.json +4 -3
- package/utils/common.js +6 -5
- package/utils/commonUtils.js +1 -14
- package/utils/imageUrlUpload.js +141 -0
- package/utils/tests/commonUtil.test.js +0 -224
- package/utils/transformTemplateConfig.js +10 -0
- package/v2Components/CapDeviceContent/index.js +56 -61
- package/v2Components/CapImageUpload/constants.js +2 -0
- package/v2Components/CapImageUpload/index.js +65 -16
- package/v2Components/CapImageUpload/index.scss +4 -1
- package/v2Components/CapImageUpload/messages.js +5 -1
- package/v2Components/CapImageUrlUpload/constants.js +26 -0
- package/v2Components/CapImageUrlUpload/index.js +365 -0
- package/v2Components/CapImageUrlUpload/index.scss +35 -0
- package/v2Components/CapImageUrlUpload/messages.js +47 -0
- package/v2Components/CapTagList/index.js +1 -6
- package/v2Components/CapTagListWithInput/index.js +1 -5
- package/v2Components/CapTagListWithInput/messages.js +1 -1
- package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
- package/v2Components/ErrorInfoNote/index.js +72 -412
- package/v2Components/ErrorInfoNote/messages.js +0 -22
- package/v2Components/ErrorInfoNote/style.scss +2 -279
- package/v2Components/HtmlEditor/HTMLEditor.js +91 -220
- package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1132
- package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +12 -17
- package/v2Components/HtmlEditor/_htmlEditor.scss +45 -107
- package/v2Components/HtmlEditor/_index.lazy.scss +1 -1
- package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +101 -13
- package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +139 -148
- package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
- package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
- package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +0 -9
- package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
- package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -22
- package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
- package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
- package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
- package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
- package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
- package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +6 -3
- package/v2Components/HtmlEditor/components/PreviewPane/index.js +11 -10
- package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +72 -70
- package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -49
- package/v2Components/HtmlEditor/constants.js +20 -29
- package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
- package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
- package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
- package/v2Components/HtmlEditor/index.js +1 -1
- package/v2Components/HtmlEditor/messages.js +85 -95
- package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +101 -99
- package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
- package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -34
- package/v2Components/MobilePushPreviewV2/index.js +7 -32
- package/v2Components/TemplatePreview/_templatePreview.scss +24 -44
- package/v2Components/TemplatePreview/index.js +32 -47
- package/v2Components/TemplatePreview/messages.js +0 -4
- package/v2Components/TestAndPreviewSlidebox/index.js +25 -31
- package/v2Containers/App/constants.js +5 -0
- package/v2Containers/BeeEditor/index.js +80 -82
- package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +4 -3
- package/v2Containers/CreativesContainer/SlideBoxContent.js +118 -148
- package/v2Containers/CreativesContainer/SlideBoxFooter.js +3 -9
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -2
- package/v2Containers/CreativesContainer/constants.js +2 -1
- package/v2Containers/CreativesContainer/index.js +41 -173
- package/v2Containers/CreativesContainer/messages.js +4 -4
- package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +210 -0
- package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +354 -38
- package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -36
- package/v2Containers/Email/actions.js +0 -7
- package/v2Containers/Email/constants.js +1 -5
- package/v2Containers/Email/index.js +0 -13
- package/v2Containers/Email/messages.js +0 -32
- package/v2Containers/Email/reducer.js +1 -12
- package/v2Containers/Email/sagas.js +6 -41
- package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
- package/v2Containers/EmailWrapper/components/EmailWrapperView.js +7 -193
- package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
- package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
- package/v2Containers/EmailWrapper/constants.js +0 -2
- package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +67 -436
- package/v2Containers/EmailWrapper/index.js +23 -99
- package/v2Containers/EmailWrapper/messages.js +1 -61
- package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +214 -0
- package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -111
- package/v2Containers/InApp/actions.js +0 -7
- package/v2Containers/InApp/constants.js +4 -20
- package/v2Containers/InApp/index.js +357 -801
- package/v2Containers/InApp/index.scss +3 -4
- package/v2Containers/InApp/messages.js +3 -7
- package/v2Containers/InApp/reducer.js +3 -21
- package/v2Containers/InApp/sagas.js +9 -29
- package/v2Containers/InApp/selectors.js +5 -25
- package/v2Containers/InApp/tests/index.test.js +50 -154
- package/v2Containers/InApp/tests/reducer.test.js +0 -34
- package/v2Containers/InApp/tests/sagas.test.js +9 -61
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +12 -12
- package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +8 -8
- package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +100 -77
- package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +72 -63
- package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +184 -150
- package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +16 -12
- package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +32 -28
- package/v2Containers/TagList/index.js +1 -67
- package/v2Containers/Templates/ChannelTypeIllustration.js +13 -1
- package/v2Containers/Templates/_templates.scss +202 -56
- package/v2Containers/Templates/actions.js +2 -1
- package/v2Containers/Templates/constants.js +1 -0
- package/v2Containers/Templates/index.js +278 -128
- package/v2Containers/Templates/messages.js +24 -4
- package/v2Containers/Templates/reducer.js +2 -0
- package/v2Containers/Templates/tests/index.test.js +10 -0
- package/v2Containers/TemplatesV2/index.js +8 -1
- package/v2Containers/TemplatesV2/messages.js +4 -0
- package/v2Containers/WebPush/Create/components/BrandIconSection.js +108 -0
- package/v2Containers/WebPush/Create/components/ButtonForm.js +172 -0
- package/v2Containers/WebPush/Create/components/ButtonItem.js +101 -0
- package/v2Containers/WebPush/Create/components/ButtonList.js +145 -0
- package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +164 -0
- package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +463 -0
- package/v2Containers/WebPush/Create/components/FormActions.js +54 -0
- package/v2Containers/WebPush/Create/components/FormActions.test.js +163 -0
- package/v2Containers/WebPush/Create/components/MediaSection.js +142 -0
- package/v2Containers/WebPush/Create/components/MediaSection.test.js +341 -0
- package/v2Containers/WebPush/Create/components/MessageSection.js +103 -0
- package/v2Containers/WebPush/Create/components/MessageSection.test.js +268 -0
- package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +87 -0
- package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +210 -0
- package/v2Containers/WebPush/Create/components/TemplateNameSection.js +54 -0
- package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +143 -0
- package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +86 -0
- package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +16 -0
- package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +41 -0
- package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +54 -0
- package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +37 -0
- package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +21 -0
- package/v2Containers/WebPush/Create/components/_buttons.scss +246 -0
- package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +554 -0
- package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +607 -0
- package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +633 -0
- package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +666 -0
- package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +74 -0
- package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +78 -0
- package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +138 -0
- package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +406 -0
- package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +30 -0
- package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +151 -0
- package/v2Containers/WebPush/Create/hooks/useImageUpload.js +104 -0
- package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +538 -0
- package/v2Containers/WebPush/Create/hooks/useTagManagement.js +122 -0
- package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +633 -0
- package/v2Containers/WebPush/Create/index.js +1056 -0
- package/v2Containers/WebPush/Create/index.scss +134 -0
- package/v2Containers/WebPush/Create/messages.js +203 -0
- package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +228 -0
- package/v2Containers/WebPush/Create/preview/NotificationContainer.js +294 -0
- package/v2Containers/WebPush/Create/preview/PreviewContent.js +90 -0
- package/v2Containers/WebPush/Create/preview/PreviewControls.js +305 -0
- package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +23 -0
- package/v2Containers/WebPush/Create/preview/WebPushPreview.js +150 -0
- package/v2Containers/WebPush/Create/preview/assets/Light.svg +53 -0
- package/v2Containers/WebPush/Create/preview/assets/Top.svg +5 -0
- package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +9 -0
- package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +9 -0
- package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
- package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
- package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +106 -0
- package/v2Containers/WebPush/Create/preview/assets/iOS.svg +26 -0
- package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +9 -0
- package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +9 -0
- package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +18 -0
- package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +29 -0
- package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +9 -0
- package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +9 -0
- package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +47 -0
- package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +141 -0
- package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +45 -0
- package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +68 -0
- package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +61 -0
- package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +99 -0
- package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +733 -0
- package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +571 -0
- package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +81 -0
- package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +81 -0
- package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +50 -0
- package/v2Containers/WebPush/Create/preview/constants.js +637 -0
- package/v2Containers/WebPush/Create/preview/notification-container.scss +79 -0
- package/v2Containers/WebPush/Create/preview/preview.scss +351 -0
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +370 -0
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +12 -0
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +12 -0
- package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +12 -0
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +47 -0
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +11 -0
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +11 -0
- package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +11 -0
- package/v2Containers/WebPush/Create/preview/styles/_base.scss +207 -0
- package/v2Containers/WebPush/Create/preview/styles/_ios.scss +153 -0
- package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +107 -0
- package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +101 -0
- package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +229 -0
- package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +909 -0
- package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +1081 -0
- package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +723 -0
- package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +943 -0
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +131 -0
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +112 -0
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +144 -0
- package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +129 -0
- package/v2Containers/WebPush/Create/utils/payloadBuilder.js +94 -0
- package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +390 -0
- package/v2Containers/WebPush/Create/utils/previewUtils.js +89 -0
- package/v2Containers/WebPush/Create/utils/urlValidation.js +115 -0
- package/v2Containers/WebPush/Create/utils/urlValidation.test.js +449 -0
- package/v2Containers/WebPush/Create/utils/validation.js +75 -0
- package/v2Containers/WebPush/Create/utils/validation.test.js +283 -0
- package/v2Containers/WebPush/actions.js +60 -0
- package/v2Containers/WebPush/constants.js +128 -0
- package/v2Containers/WebPush/index.js +2 -0
- package/v2Containers/WebPush/reducer.js +104 -0
- package/v2Containers/WebPush/sagas.js +119 -0
- package/v2Containers/WebPush/selectors.js +65 -0
- package/v2Containers/WebPush/tests/reducer.test.js +863 -0
- package/v2Containers/WebPush/tests/sagas.test.js +566 -0
- package/v2Containers/WebPush/tests/selectors.test.js +843 -0
- package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +528 -431
- package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -254
- package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -362
- package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
- package/v2Containers/BeePopupEditor/constants.js +0 -10
- package/v2Containers/BeePopupEditor/index.js +0 -193
- package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
- package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1046
- package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
- package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
- package/v2Containers/InApp/tests/selectors.test.js +0 -612
- package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -162
- package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
- package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -9
- package/v2Containers/InAppWrapper/constants.js +0 -16
- package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
- package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
- package/v2Containers/InAppWrapper/index.js +0 -148
- package/v2Containers/InAppWrapper/messages.js +0 -49
- package/v2Containers/InappAdvance/index.js +0 -1099
- package/v2Containers/InappAdvance/index.scss +0 -10
- package/v2Containers/InappAdvance/tests/index.test.js +0 -448
|
@@ -4,30 +4,133 @@
|
|
|
4
4
|
* Manages separate HTML content for Android and iOS devices with sync functionality
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
useState, useCallback, useRef, useEffect, useMemo,
|
|
9
|
-
} from 'react';
|
|
7
|
+
import { useState, useCallback, useRef, useEffect, useMemo } from 'react';
|
|
10
8
|
import { DEVICE_TYPES, PERFORMANCE } from '../constants';
|
|
11
9
|
|
|
12
10
|
// Constants for better maintainability
|
|
13
11
|
const CONTENT_VALIDATION = {
|
|
14
12
|
MIN_CONTENT_LENGTH: 0,
|
|
15
|
-
DEFAULT_CONTENT_TYPE: 'string'
|
|
13
|
+
DEFAULT_CONTENT_TYPE: 'string'
|
|
16
14
|
};
|
|
17
15
|
|
|
18
16
|
const AUTO_SAVE_CONFIG = {
|
|
19
17
|
DEFAULT_ENABLED: true,
|
|
20
18
|
DEFAULT_INTERVAL: PERFORMANCE.AUTO_SAVE_INTERVAL,
|
|
21
|
-
MIN_AUTO_SAVE_INTERVAL_MS: 1000
|
|
19
|
+
MIN_AUTO_SAVE_INTERVAL_MS: 1000 // Minimum 1 second between auto-saves
|
|
22
20
|
};
|
|
23
21
|
|
|
24
22
|
/**
|
|
25
23
|
* Default InApp content for different devices
|
|
26
|
-
* Empty strings - no default content for new templates
|
|
27
24
|
*/
|
|
28
25
|
const DEFAULT_INAPP_CONTENT = {
|
|
29
|
-
[DEVICE_TYPES.ANDROID]:
|
|
30
|
-
|
|
26
|
+
[DEVICE_TYPES.ANDROID]: `<!DOCTYPE html>
|
|
27
|
+
<html lang="en">
|
|
28
|
+
<head>
|
|
29
|
+
<meta charset="UTF-8">
|
|
30
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
31
|
+
<title>In-App Notification</title>
|
|
32
|
+
<style>
|
|
33
|
+
body {
|
|
34
|
+
margin: 0;
|
|
35
|
+
padding: 16px;
|
|
36
|
+
font-family: -apple-system, BlinkMacSystemFont, 'Roboto', sans-serif;
|
|
37
|
+
background-color: #ffffff;
|
|
38
|
+
color: #212121;
|
|
39
|
+
}
|
|
40
|
+
.notification {
|
|
41
|
+
max-width: 100%;
|
|
42
|
+
background: white;
|
|
43
|
+
border-radius: 8px;
|
|
44
|
+
padding: 16px;
|
|
45
|
+
box-shadow: 0 4px 12px rgba(0,0,0,0.15);
|
|
46
|
+
}
|
|
47
|
+
.title {
|
|
48
|
+
font-size: 16px;
|
|
49
|
+
font-weight: 500;
|
|
50
|
+
margin: 0 0 8px 0;
|
|
51
|
+
color: #212121;
|
|
52
|
+
}
|
|
53
|
+
.message {
|
|
54
|
+
font-size: 14px;
|
|
55
|
+
line-height: 1.4;
|
|
56
|
+
margin: 0 0 16px 0;
|
|
57
|
+
color: #424242;
|
|
58
|
+
}
|
|
59
|
+
.cta-button {
|
|
60
|
+
background-color: #42b040;
|
|
61
|
+
color: white;
|
|
62
|
+
border: none;
|
|
63
|
+
border-radius: 4px;
|
|
64
|
+
padding: 8px 16px;
|
|
65
|
+
font-size: 12px;
|
|
66
|
+
font-weight: 500;
|
|
67
|
+
cursor: pointer;
|
|
68
|
+
width: 100%;
|
|
69
|
+
}
|
|
70
|
+
</style>
|
|
71
|
+
</head>
|
|
72
|
+
<body>
|
|
73
|
+
<div class="notification">
|
|
74
|
+
<h2 class="title">Sample template</h2>
|
|
75
|
+
<p class="message">This is a sample template for in-app notification content. This can be triggered on any behavioural event while the user is on the app</p>
|
|
76
|
+
<button class="cta-button">Add to cart</button>
|
|
77
|
+
</div>
|
|
78
|
+
</body>
|
|
79
|
+
</html>`,
|
|
80
|
+
[DEVICE_TYPES.IOS]: `<!DOCTYPE html>
|
|
81
|
+
<html lang="en">
|
|
82
|
+
<head>
|
|
83
|
+
<meta charset="UTF-8">
|
|
84
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
85
|
+
<title>In-App Notification</title>
|
|
86
|
+
<style>
|
|
87
|
+
body {
|
|
88
|
+
margin: 0;
|
|
89
|
+
padding: 16px;
|
|
90
|
+
font-family: -apple-system, BlinkMacSystemFont, 'SF Pro Text', sans-serif;
|
|
91
|
+
background-color: #ffffff;
|
|
92
|
+
color: #000000;
|
|
93
|
+
}
|
|
94
|
+
.notification {
|
|
95
|
+
max-width: 100%;
|
|
96
|
+
background: white;
|
|
97
|
+
border-radius: 12px;
|
|
98
|
+
padding: 16px;
|
|
99
|
+
box-shadow: 0 4px 16px rgba(0,0,0,0.1);
|
|
100
|
+
}
|
|
101
|
+
.title {
|
|
102
|
+
font-size: 17px;
|
|
103
|
+
font-weight: 600;
|
|
104
|
+
margin: 0 0 8px 0;
|
|
105
|
+
color: #000000;
|
|
106
|
+
}
|
|
107
|
+
.message {
|
|
108
|
+
font-size: 15px;
|
|
109
|
+
line-height: 1.4;
|
|
110
|
+
margin: 0 0 16px 0;
|
|
111
|
+
color: #3c3c43;
|
|
112
|
+
}
|
|
113
|
+
.cta-button {
|
|
114
|
+
background-color: #007AFF;
|
|
115
|
+
color: white;
|
|
116
|
+
border: none;
|
|
117
|
+
border-radius: 8px;
|
|
118
|
+
padding: 12px 16px;
|
|
119
|
+
font-size: 16px;
|
|
120
|
+
font-weight: 600;
|
|
121
|
+
cursor: pointer;
|
|
122
|
+
width: 100%;
|
|
123
|
+
}
|
|
124
|
+
</style>
|
|
125
|
+
</head>
|
|
126
|
+
<body>
|
|
127
|
+
<div class="notification">
|
|
128
|
+
<h2 class="title">Sample template</h2>
|
|
129
|
+
<p class="message">This is a sample template for in-app notification content. This can be triggered on any behavioural event while the user is on the app</p>
|
|
130
|
+
<button class="cta-button">Add to cart</button>
|
|
131
|
+
</div>
|
|
132
|
+
</body>
|
|
133
|
+
</html>`
|
|
31
134
|
};
|
|
32
135
|
|
|
33
136
|
/**
|
|
@@ -47,7 +150,7 @@ export const useInAppContent = (initialContent = {}, options = {}) => {
|
|
|
47
150
|
autoSave = AUTO_SAVE_CONFIG.DEFAULT_ENABLED,
|
|
48
151
|
autoSaveInterval = AUTO_SAVE_CONFIG.DEFAULT_INTERVAL,
|
|
49
152
|
onSave,
|
|
50
|
-
onChange
|
|
153
|
+
onChange
|
|
51
154
|
} = options;
|
|
52
155
|
|
|
53
156
|
// Destructure device types for cleaner code
|
|
@@ -56,7 +159,7 @@ export const useInAppContent = (initialContent = {}, options = {}) => {
|
|
|
56
159
|
// Device-specific content state with optional chaining
|
|
57
160
|
const [deviceContent, setDeviceContent] = useState(() => ({
|
|
58
161
|
[ANDROID]: initialContent?.[ANDROID] || DEFAULT_INAPP_CONTENT[ANDROID],
|
|
59
|
-
[IOS]: initialContent?.[IOS] || DEFAULT_INAPP_CONTENT[IOS]
|
|
162
|
+
[IOS]: initialContent?.[IOS] || DEFAULT_INAPP_CONTENT[IOS]
|
|
60
163
|
}));
|
|
61
164
|
|
|
62
165
|
// Current active device
|
|
@@ -86,67 +189,15 @@ export const useInAppContent = (initialContent = {}, options = {}) => {
|
|
|
86
189
|
deviceContentRef.current = deviceContent;
|
|
87
190
|
}, [deviceContent]);
|
|
88
191
|
|
|
89
|
-
// Ref to track if we've loaded initial content to prevent overriding user edits
|
|
90
|
-
const initialContentLoadedRef = useRef(false);
|
|
91
|
-
const previousContentRef = useRef({ android: '', ios: '' });
|
|
92
|
-
|
|
93
|
-
// Update content when initialContent prop changes (for edit mode)
|
|
94
|
-
// This should only run when loading a template for editing, NOT during active editing
|
|
95
|
-
useEffect(() => {
|
|
96
|
-
const newAndroidContent = initialContent?.[ANDROID];
|
|
97
|
-
const newIosContent = initialContent?.[IOS];
|
|
98
|
-
|
|
99
|
-
// Check if this is meaningful initialContent (has actual content)
|
|
100
|
-
const hasMeaningfulContent = (newAndroidContent && newAndroidContent.trim() !== '')
|
|
101
|
-
|| (newIosContent && newIosContent.trim() !== '');
|
|
102
|
-
|
|
103
|
-
// Check if we're transitioning from empty to meaningful content (library mode scenario)
|
|
104
|
-
const wasEmpty = (!previousContentRef.current.android || previousContentRef.current.android.trim() === '')
|
|
105
|
-
&& (!previousContentRef.current.ios || previousContentRef.current.ios.trim() === '');
|
|
106
|
-
const isTransitioningToContent = wasEmpty && hasMeaningfulContent;
|
|
107
|
-
|
|
108
|
-
// Only update if:
|
|
109
|
-
// 1. We haven't loaded initial content yet (first load), OR
|
|
110
|
-
// 2. We're transitioning from empty to meaningful content (library mode data fetch)
|
|
111
|
-
// This prevents the effect from overriding user edits during active editing
|
|
112
|
-
// while still allowing content to load properly in library mode
|
|
113
|
-
if (!initialContentLoadedRef.current || isTransitioningToContent) {
|
|
114
|
-
if (hasMeaningfulContent) {
|
|
115
|
-
// Mark as loaded to prevent future updates from overriding user edits
|
|
116
|
-
initialContentLoadedRef.current = true;
|
|
117
|
-
|
|
118
|
-
setDeviceContent((prev) => {
|
|
119
|
-
let updated = false;
|
|
120
|
-
const updatedContent = { ...prev };
|
|
121
|
-
|
|
122
|
-
if (newAndroidContent !== undefined && newAndroidContent !== prev[ANDROID]) {
|
|
123
|
-
updatedContent[ANDROID] = newAndroidContent;
|
|
124
|
-
updated = true;
|
|
125
|
-
}
|
|
126
|
-
if (newIosContent !== undefined && newIosContent !== prev[IOS]) {
|
|
127
|
-
updatedContent[IOS] = newIosContent;
|
|
128
|
-
updated = true;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
return updated ? updatedContent : prev;
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
// Update previous content ref
|
|
135
|
-
previousContentRef.current = {
|
|
136
|
-
android: newAndroidContent || '',
|
|
137
|
-
ios: newIosContent || '',
|
|
138
|
-
};
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}, [initialContent, ANDROID, IOS]);
|
|
142
|
-
|
|
143
192
|
// Get current active content
|
|
144
|
-
const currentContent = useMemo(() =>
|
|
193
|
+
const currentContent = useMemo(() => {
|
|
194
|
+
return deviceContent[activeDevice] || '';
|
|
195
|
+
}, [deviceContent, activeDevice]);
|
|
145
196
|
|
|
146
197
|
// Update content for current device
|
|
147
198
|
const updateContent = useCallback((newContent) => {
|
|
148
199
|
// Validate input
|
|
149
|
-
if (typeof newContent !== CONTENT_VALIDATION
|
|
200
|
+
if (typeof newContent !== CONTENT_VALIDATION.DEFAULT_CONTENT_TYPE) {
|
|
150
201
|
console.warn('useInAppContent: newContent must be a string');
|
|
151
202
|
return;
|
|
152
203
|
}
|
|
@@ -158,14 +209,14 @@ export const useInAppContent = (initialContent = {}, options = {}) => {
|
|
|
158
209
|
// When sync is enabled, update both devices with the same content
|
|
159
210
|
updatedDeviceContent = {
|
|
160
211
|
[ANDROID]: newContent,
|
|
161
|
-
[IOS]: newContent
|
|
212
|
+
[IOS]: newContent
|
|
162
213
|
};
|
|
163
214
|
} else {
|
|
164
215
|
// When sync is disabled, update only the current device
|
|
165
|
-
setDeviceContent(
|
|
216
|
+
setDeviceContent(prev => {
|
|
166
217
|
updatedDeviceContent = {
|
|
167
218
|
...prev,
|
|
168
|
-
[activeDevice]: newContent
|
|
219
|
+
[activeDevice]: newContent
|
|
169
220
|
};
|
|
170
221
|
return updatedDeviceContent;
|
|
171
222
|
});
|
|
@@ -174,9 +225,8 @@ export const useInAppContent = (initialContent = {}, options = {}) => {
|
|
|
174
225
|
setIsDirty(true);
|
|
175
226
|
changeTimestampRef.current = Date.now();
|
|
176
227
|
|
|
177
|
-
// Trigger onChange callback
|
|
178
|
-
|
|
179
|
-
onChange?.({ [activeDevice]: newContent }, activeDevice);
|
|
228
|
+
// Trigger onChange callback with optional chaining
|
|
229
|
+
onChange?.(updatedDeviceContent, activeDevice);
|
|
180
230
|
|
|
181
231
|
// Setup auto-save for independent mode
|
|
182
232
|
if (autoSave && autoSaveInterval > AUTO_SAVE_CONFIG.MIN_AUTO_SAVE_INTERVAL_MS && newContent.length > CONTENT_VALIDATION.MIN_CONTENT_LENGTH) {
|
|
@@ -207,7 +257,7 @@ export const useInAppContent = (initialContent = {}, options = {}) => {
|
|
|
207
257
|
setIsDirty(true);
|
|
208
258
|
changeTimestampRef.current = Date.now();
|
|
209
259
|
|
|
210
|
-
// Trigger onChange callback
|
|
260
|
+
// Trigger onChange callback with optional chaining
|
|
211
261
|
onChange?.(updatedDeviceContent, activeDevice);
|
|
212
262
|
|
|
213
263
|
// Setup auto-save
|
|
@@ -251,7 +301,7 @@ export const useInAppContent = (initialContent = {}, options = {}) => {
|
|
|
251
301
|
const currentActiveContent = deviceContent[activeDevice];
|
|
252
302
|
const syncedContent = {
|
|
253
303
|
[ANDROID]: currentActiveContent,
|
|
254
|
-
[IOS]: currentActiveContent
|
|
304
|
+
[IOS]: currentActiveContent
|
|
255
305
|
};
|
|
256
306
|
|
|
257
307
|
setDeviceContent(syncedContent);
|
|
@@ -275,16 +325,22 @@ export const useInAppContent = (initialContent = {}, options = {}) => {
|
|
|
275
325
|
}, [deviceContent, onSave]);
|
|
276
326
|
|
|
277
327
|
// Check if content exists for current device
|
|
278
|
-
const hasContent = useMemo(() =>
|
|
279
|
-
|
|
328
|
+
const hasContent = useMemo(() => {
|
|
329
|
+
return typeof currentContent === CONTENT_VALIDATION.DEFAULT_CONTENT_TYPE &&
|
|
330
|
+
currentContent.trim().length > CONTENT_VALIDATION.MIN_CONTENT_LENGTH;
|
|
331
|
+
}, [currentContent]);
|
|
280
332
|
|
|
281
333
|
// Get content size for current device
|
|
282
|
-
const getContentSize = useCallback(() =>
|
|
283
|
-
|
|
284
|
-
|
|
334
|
+
const getContentSize = useCallback(() => {
|
|
335
|
+
return typeof currentContent === CONTENT_VALIDATION.DEFAULT_CONTENT_TYPE
|
|
336
|
+
? currentContent.length
|
|
337
|
+
: CONTENT_VALIDATION.MIN_CONTENT_LENGTH;
|
|
338
|
+
}, [currentContent]);
|
|
285
339
|
|
|
286
340
|
// Get content for specific device
|
|
287
|
-
const getDeviceContent = useCallback((device) =>
|
|
341
|
+
const getDeviceContent = useCallback((device) => {
|
|
342
|
+
return deviceContent[device] || '';
|
|
343
|
+
}, [deviceContent]);
|
|
288
344
|
|
|
289
345
|
// Set content for specific device
|
|
290
346
|
const setDeviceContent_ = useCallback((device, content) => {
|
|
@@ -304,23 +360,25 @@ export const useInAppContent = (initialContent = {}, options = {}) => {
|
|
|
304
360
|
// Update both devices when sync is enabled
|
|
305
361
|
setDeviceContent({
|
|
306
362
|
[ANDROID]: content,
|
|
307
|
-
[IOS]: content
|
|
363
|
+
[IOS]: content
|
|
308
364
|
});
|
|
309
365
|
} else {
|
|
310
366
|
// Update specific device
|
|
311
|
-
setDeviceContent(
|
|
367
|
+
setDeviceContent(prev => ({
|
|
312
368
|
...prev,
|
|
313
|
-
[device]: content
|
|
369
|
+
[device]: content
|
|
314
370
|
}));
|
|
315
371
|
}
|
|
316
372
|
setIsDirty(true);
|
|
317
373
|
}, [keepContentSame, ANDROID, IOS]);
|
|
318
374
|
|
|
319
375
|
// Cleanup on unmount
|
|
320
|
-
useEffect(() =>
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
376
|
+
useEffect(() => {
|
|
377
|
+
return () => {
|
|
378
|
+
if (autoSaveTimerRef.current) {
|
|
379
|
+
clearTimeout(autoSaveTimerRef.current);
|
|
380
|
+
}
|
|
381
|
+
};
|
|
324
382
|
}, []);
|
|
325
383
|
|
|
326
384
|
return {
|
|
@@ -344,6 +402,6 @@ export const useInAppContent = (initialContent = {}, options = {}) => {
|
|
|
344
402
|
toggleContentSync,
|
|
345
403
|
|
|
346
404
|
// Save management
|
|
347
|
-
markAsSaved
|
|
405
|
+
markAsSaved
|
|
348
406
|
};
|
|
349
407
|
};
|