@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.
Files changed (256) hide show
  1. package/assets/Android.png +0 -0
  2. package/assets/iOS.png +0 -0
  3. package/config/app.js +1 -1
  4. package/constants/unified.js +2 -2
  5. package/initialReducer.js +0 -2
  6. package/package.json +1 -1
  7. package/services/api.js +5 -10
  8. package/services/tests/api.test.js +0 -18
  9. package/translations/en.json +4 -3
  10. package/utils/common.js +6 -5
  11. package/utils/commonUtils.js +1 -14
  12. package/utils/imageUrlUpload.js +141 -0
  13. package/utils/tests/commonUtil.test.js +0 -224
  14. package/utils/transformTemplateConfig.js +10 -0
  15. package/v2Components/CapDeviceContent/index.js +56 -61
  16. package/v2Components/CapImageUpload/constants.js +2 -0
  17. package/v2Components/CapImageUpload/index.js +65 -16
  18. package/v2Components/CapImageUpload/index.scss +4 -1
  19. package/v2Components/CapImageUpload/messages.js +5 -1
  20. package/v2Components/CapImageUrlUpload/constants.js +26 -0
  21. package/v2Components/CapImageUrlUpload/index.js +365 -0
  22. package/v2Components/CapImageUrlUpload/index.scss +35 -0
  23. package/v2Components/CapImageUrlUpload/messages.js +47 -0
  24. package/v2Components/CapTagList/index.js +1 -6
  25. package/v2Components/CapTagListWithInput/index.js +1 -5
  26. package/v2Components/CapTagListWithInput/messages.js +1 -1
  27. package/v2Components/CapWhatsappCTA/tests/index.test.js +0 -5
  28. package/v2Components/ErrorInfoNote/index.js +72 -412
  29. package/v2Components/ErrorInfoNote/messages.js +0 -22
  30. package/v2Components/ErrorInfoNote/style.scss +2 -279
  31. package/v2Components/HtmlEditor/HTMLEditor.js +91 -220
  32. package/v2Components/HtmlEditor/__tests__/HTMLEditor.test.js +133 -1132
  33. package/v2Components/HtmlEditor/__tests__/index.lazy.test.js +12 -17
  34. package/v2Components/HtmlEditor/_htmlEditor.scss +45 -107
  35. package/v2Components/HtmlEditor/_index.lazy.scss +1 -1
  36. package/v2Components/HtmlEditor/components/CodeEditorPane/_codeEditorPane.scss +101 -13
  37. package/v2Components/HtmlEditor/components/CodeEditorPane/index.js +139 -148
  38. package/v2Components/HtmlEditor/components/DeviceToggle/_deviceToggle.scss +1 -2
  39. package/v2Components/HtmlEditor/components/DeviceToggle/index.js +3 -3
  40. package/v2Components/HtmlEditor/components/EditorToolbar/_editorToolbar.scss +0 -9
  41. package/v2Components/HtmlEditor/components/EditorToolbar/index.js +1 -1
  42. package/v2Components/HtmlEditor/components/FullscreenModal/_fullscreenModal.scss +0 -22
  43. package/v2Components/HtmlEditor/components/InAppPreviewPane/DeviceFrame.js +7 -4
  44. package/v2Components/HtmlEditor/components/InAppPreviewPane/__tests__/DeviceFrame.test.js +45 -35
  45. package/v2Components/HtmlEditor/components/InAppPreviewPane/_inAppPreviewPane.scss +3 -1
  46. package/v2Components/HtmlEditor/components/InAppPreviewPane/constants.js +33 -33
  47. package/v2Components/HtmlEditor/components/InAppPreviewPane/index.js +6 -7
  48. package/v2Components/HtmlEditor/components/PreviewPane/_previewPane.scss +6 -3
  49. package/v2Components/HtmlEditor/components/PreviewPane/index.js +11 -10
  50. package/v2Components/HtmlEditor/components/SplitContainer/_splitContainer.scss +1 -1
  51. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/__tests__/index.test.js +72 -70
  52. package/v2Components/HtmlEditor/components/ValidationErrorDisplay/index.js +31 -49
  53. package/v2Components/HtmlEditor/constants.js +20 -29
  54. package/v2Components/HtmlEditor/hooks/__tests__/useInAppContent.test.js +16 -373
  55. package/v2Components/HtmlEditor/hooks/useEditorContent.js +2 -5
  56. package/v2Components/HtmlEditor/hooks/useInAppContent.js +146 -88
  57. package/v2Components/HtmlEditor/index.js +1 -1
  58. package/v2Components/HtmlEditor/messages.js +85 -95
  59. package/v2Components/HtmlEditor/utils/liquidTemplateSupport.js +101 -99
  60. package/v2Components/HtmlEditor/utils/properSyntaxHighlighting.js +25 -23
  61. package/v2Components/HtmlEditor/utils/validationAdapter.js +41 -34
  62. package/v2Components/MobilePushPreviewV2/index.js +7 -32
  63. package/v2Components/TemplatePreview/_templatePreview.scss +24 -44
  64. package/v2Components/TemplatePreview/index.js +32 -47
  65. package/v2Components/TemplatePreview/messages.js +0 -4
  66. package/v2Components/TestAndPreviewSlidebox/index.js +25 -31
  67. package/v2Containers/App/constants.js +5 -0
  68. package/v2Containers/BeeEditor/index.js +80 -82
  69. package/v2Containers/Cap/tests/__snapshots__/index.test.js.snap +4 -3
  70. package/v2Containers/CreativesContainer/SlideBoxContent.js +118 -148
  71. package/v2Containers/CreativesContainer/SlideBoxFooter.js +3 -9
  72. package/v2Containers/CreativesContainer/SlideBoxHeader.js +2 -2
  73. package/v2Containers/CreativesContainer/constants.js +2 -1
  74. package/v2Containers/CreativesContainer/index.js +41 -173
  75. package/v2Containers/CreativesContainer/messages.js +4 -4
  76. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +210 -0
  77. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +354 -38
  78. package/v2Containers/CreativesContainer/tests/__snapshots__/index.test.js.snap +0 -36
  79. package/v2Containers/Email/actions.js +0 -7
  80. package/v2Containers/Email/constants.js +1 -5
  81. package/v2Containers/Email/index.js +0 -13
  82. package/v2Containers/Email/messages.js +0 -32
  83. package/v2Containers/Email/reducer.js +1 -12
  84. package/v2Containers/Email/sagas.js +6 -41
  85. package/v2Containers/Email/tests/__snapshots__/reducer.test.js.snap +0 -2
  86. package/v2Containers/EmailWrapper/components/EmailWrapperView.js +7 -193
  87. package/v2Containers/EmailWrapper/components/HTMLEditorTesting.js +74 -40
  88. package/v2Containers/EmailWrapper/components/__tests__/HTMLEditorTesting.test.js +67 -2
  89. package/v2Containers/EmailWrapper/constants.js +0 -2
  90. package/v2Containers/EmailWrapper/hooks/useEmailWrapper.js +67 -436
  91. package/v2Containers/EmailWrapper/index.js +23 -99
  92. package/v2Containers/EmailWrapper/messages.js +1 -61
  93. package/v2Containers/EmailWrapper/tests/EmailWrapperView.test.js +214 -0
  94. package/v2Containers/EmailWrapper/tests/useEmailWrapper.test.js +77 -111
  95. package/v2Containers/InApp/actions.js +0 -7
  96. package/v2Containers/InApp/constants.js +4 -20
  97. package/v2Containers/InApp/index.js +357 -801
  98. package/v2Containers/InApp/index.scss +3 -4
  99. package/v2Containers/InApp/messages.js +3 -7
  100. package/v2Containers/InApp/reducer.js +3 -21
  101. package/v2Containers/InApp/sagas.js +9 -29
  102. package/v2Containers/InApp/selectors.js +5 -25
  103. package/v2Containers/InApp/tests/index.test.js +50 -154
  104. package/v2Containers/InApp/tests/reducer.test.js +0 -34
  105. package/v2Containers/InApp/tests/sagas.test.js +9 -61
  106. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/content.test.js.snap +12 -12
  107. package/v2Containers/Line/Container/ImageCarousel/tests/__snapshots__/index.test.js.snap +8 -8
  108. package/v2Containers/Line/Container/Wrapper/tests/__snapshots__/index.test.js.snap +100 -77
  109. package/v2Containers/Line/Container/tests/__snapshots__/index.test.js.snap +72 -63
  110. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +184 -150
  111. package/v2Containers/SmsTrai/Create/tests/__snapshots__/index.test.js.snap +16 -12
  112. package/v2Containers/SmsTrai/Edit/tests/__snapshots__/index.test.js.snap +32 -28
  113. package/v2Containers/TagList/index.js +1 -67
  114. package/v2Containers/Templates/ChannelTypeIllustration.js +13 -1
  115. package/v2Containers/Templates/_templates.scss +202 -56
  116. package/v2Containers/Templates/actions.js +2 -1
  117. package/v2Containers/Templates/constants.js +1 -0
  118. package/v2Containers/Templates/index.js +278 -128
  119. package/v2Containers/Templates/messages.js +24 -4
  120. package/v2Containers/Templates/reducer.js +2 -0
  121. package/v2Containers/Templates/tests/index.test.js +10 -0
  122. package/v2Containers/TemplatesV2/index.js +8 -1
  123. package/v2Containers/TemplatesV2/messages.js +4 -0
  124. package/v2Containers/WebPush/Create/components/BrandIconSection.js +108 -0
  125. package/v2Containers/WebPush/Create/components/ButtonForm.js +172 -0
  126. package/v2Containers/WebPush/Create/components/ButtonItem.js +101 -0
  127. package/v2Containers/WebPush/Create/components/ButtonList.js +145 -0
  128. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.js +164 -0
  129. package/v2Containers/WebPush/Create/components/ButtonsLinksSection.test.js +463 -0
  130. package/v2Containers/WebPush/Create/components/FormActions.js +54 -0
  131. package/v2Containers/WebPush/Create/components/FormActions.test.js +163 -0
  132. package/v2Containers/WebPush/Create/components/MediaSection.js +142 -0
  133. package/v2Containers/WebPush/Create/components/MediaSection.test.js +341 -0
  134. package/v2Containers/WebPush/Create/components/MessageSection.js +103 -0
  135. package/v2Containers/WebPush/Create/components/MessageSection.test.js +268 -0
  136. package/v2Containers/WebPush/Create/components/NotificationTitleSection.js +87 -0
  137. package/v2Containers/WebPush/Create/components/NotificationTitleSection.test.js +210 -0
  138. package/v2Containers/WebPush/Create/components/TemplateNameSection.js +54 -0
  139. package/v2Containers/WebPush/Create/components/TemplateNameSection.test.js +143 -0
  140. package/v2Containers/WebPush/Create/components/__snapshots__/ButtonsLinksSection.test.js.snap +86 -0
  141. package/v2Containers/WebPush/Create/components/__snapshots__/FormActions.test.js.snap +16 -0
  142. package/v2Containers/WebPush/Create/components/__snapshots__/MediaSection.test.js.snap +41 -0
  143. package/v2Containers/WebPush/Create/components/__snapshots__/MessageSection.test.js.snap +54 -0
  144. package/v2Containers/WebPush/Create/components/__snapshots__/NotificationTitleSection.test.js.snap +37 -0
  145. package/v2Containers/WebPush/Create/components/__snapshots__/TemplateNameSection.test.js.snap +21 -0
  146. package/v2Containers/WebPush/Create/components/_buttons.scss +246 -0
  147. package/v2Containers/WebPush/Create/components/tests/ButtonForm.test.js +554 -0
  148. package/v2Containers/WebPush/Create/components/tests/ButtonItem.test.js +607 -0
  149. package/v2Containers/WebPush/Create/components/tests/ButtonList.test.js +633 -0
  150. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonForm.test.js.snap +666 -0
  151. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonItem.test.js.snap +74 -0
  152. package/v2Containers/WebPush/Create/components/tests/__snapshots__/ButtonList.test.js.snap +78 -0
  153. package/v2Containers/WebPush/Create/hooks/useButtonManagement.js +138 -0
  154. package/v2Containers/WebPush/Create/hooks/useButtonManagement.test.js +406 -0
  155. package/v2Containers/WebPush/Create/hooks/useCharacterCount.js +30 -0
  156. package/v2Containers/WebPush/Create/hooks/useCharacterCount.test.js +151 -0
  157. package/v2Containers/WebPush/Create/hooks/useImageUpload.js +104 -0
  158. package/v2Containers/WebPush/Create/hooks/useImageUpload.test.js +538 -0
  159. package/v2Containers/WebPush/Create/hooks/useTagManagement.js +122 -0
  160. package/v2Containers/WebPush/Create/hooks/useTagManagement.test.js +633 -0
  161. package/v2Containers/WebPush/Create/index.js +1056 -0
  162. package/v2Containers/WebPush/Create/index.scss +134 -0
  163. package/v2Containers/WebPush/Create/messages.js +203 -0
  164. package/v2Containers/WebPush/Create/preview/DevicePreviewContent.js +228 -0
  165. package/v2Containers/WebPush/Create/preview/NotificationContainer.js +294 -0
  166. package/v2Containers/WebPush/Create/preview/PreviewContent.js +90 -0
  167. package/v2Containers/WebPush/Create/preview/PreviewControls.js +305 -0
  168. package/v2Containers/WebPush/Create/preview/PreviewDisclaimer.js +23 -0
  169. package/v2Containers/WebPush/Create/preview/WebPushPreview.js +150 -0
  170. package/v2Containers/WebPush/Create/preview/assets/Light.svg +53 -0
  171. package/v2Containers/WebPush/Create/preview/assets/Top.svg +5 -0
  172. package/v2Containers/WebPush/Create/preview/assets/android-arrow-down.svg +9 -0
  173. package/v2Containers/WebPush/Create/preview/assets/android-arrow-up.svg +9 -0
  174. package/v2Containers/WebPush/Create/preview/assets/chrome-icon.png +0 -0
  175. package/v2Containers/WebPush/Create/preview/assets/edge-icon.png +0 -0
  176. package/v2Containers/WebPush/Create/preview/assets/firefox-icon.svg +106 -0
  177. package/v2Containers/WebPush/Create/preview/assets/iOS.svg +26 -0
  178. package/v2Containers/WebPush/Create/preview/assets/macos-arrow-down-icon.svg +9 -0
  179. package/v2Containers/WebPush/Create/preview/assets/macos-triple-dot-icon.svg +9 -0
  180. package/v2Containers/WebPush/Create/preview/assets/opera-icon.svg +18 -0
  181. package/v2Containers/WebPush/Create/preview/assets/safari-icon.svg +29 -0
  182. package/v2Containers/WebPush/Create/preview/assets/windows-close-icon.svg +9 -0
  183. package/v2Containers/WebPush/Create/preview/assets/windows-triple-dot-icon.svg +9 -0
  184. package/v2Containers/WebPush/Create/preview/components/AndroidMobileChromeHeader.js +47 -0
  185. package/v2Containers/WebPush/Create/preview/components/AndroidMobileExpanded.js +141 -0
  186. package/v2Containers/WebPush/Create/preview/components/IOSHeader.js +45 -0
  187. package/v2Containers/WebPush/Create/preview/components/NotificationExpandedContent.js +68 -0
  188. package/v2Containers/WebPush/Create/preview/components/NotificationHeader.js +61 -0
  189. package/v2Containers/WebPush/Create/preview/components/WindowsChromeExpanded.js +99 -0
  190. package/v2Containers/WebPush/Create/preview/components/tests/AndroidMobileExpanded.test.js +733 -0
  191. package/v2Containers/WebPush/Create/preview/components/tests/WindowsChromeExpanded.test.js +571 -0
  192. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/AndroidMobileExpanded.test.js.snap +81 -0
  193. package/v2Containers/WebPush/Create/preview/components/tests/__snapshots__/WindowsChromeExpanded.test.js.snap +81 -0
  194. package/v2Containers/WebPush/Create/preview/config/notificationMappings.js +50 -0
  195. package/v2Containers/WebPush/Create/preview/constants.js +637 -0
  196. package/v2Containers/WebPush/Create/preview/notification-container.scss +79 -0
  197. package/v2Containers/WebPush/Create/preview/preview.scss +351 -0
  198. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-chrome.scss +370 -0
  199. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-edge.scss +12 -0
  200. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-firefox.scss +12 -0
  201. package/v2Containers/WebPush/Create/preview/styles/_android-mobile-opera.scss +12 -0
  202. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-chrome.scss +47 -0
  203. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-edge.scss +11 -0
  204. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-firefox.scss +11 -0
  205. package/v2Containers/WebPush/Create/preview/styles/_android-tablet-opera.scss +11 -0
  206. package/v2Containers/WebPush/Create/preview/styles/_base.scss +207 -0
  207. package/v2Containers/WebPush/Create/preview/styles/_ios.scss +153 -0
  208. package/v2Containers/WebPush/Create/preview/styles/_ipados.scss +107 -0
  209. package/v2Containers/WebPush/Create/preview/styles/_macos-chrome.scss +101 -0
  210. package/v2Containers/WebPush/Create/preview/styles/_windows-chrome.scss +229 -0
  211. package/v2Containers/WebPush/Create/preview/tests/DevicePreviewContent.test.js +909 -0
  212. package/v2Containers/WebPush/Create/preview/tests/NotificationContainer.test.js +1081 -0
  213. package/v2Containers/WebPush/Create/preview/tests/PreviewControls.test.js +723 -0
  214. package/v2Containers/WebPush/Create/preview/tests/WebPushPreview.test.js +943 -0
  215. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/DevicePreviewContent.test.js.snap +131 -0
  216. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/NotificationContainer.test.js.snap +112 -0
  217. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/PreviewControls.test.js.snap +144 -0
  218. package/v2Containers/WebPush/Create/preview/tests/__snapshots__/WebPushPreview.test.js.snap +129 -0
  219. package/v2Containers/WebPush/Create/utils/payloadBuilder.js +94 -0
  220. package/v2Containers/WebPush/Create/utils/payloadBuilder.test.js +390 -0
  221. package/v2Containers/WebPush/Create/utils/previewUtils.js +89 -0
  222. package/v2Containers/WebPush/Create/utils/urlValidation.js +115 -0
  223. package/v2Containers/WebPush/Create/utils/urlValidation.test.js +449 -0
  224. package/v2Containers/WebPush/Create/utils/validation.js +75 -0
  225. package/v2Containers/WebPush/Create/utils/validation.test.js +283 -0
  226. package/v2Containers/WebPush/actions.js +60 -0
  227. package/v2Containers/WebPush/constants.js +128 -0
  228. package/v2Containers/WebPush/index.js +2 -0
  229. package/v2Containers/WebPush/reducer.js +104 -0
  230. package/v2Containers/WebPush/sagas.js +119 -0
  231. package/v2Containers/WebPush/selectors.js +65 -0
  232. package/v2Containers/WebPush/tests/reducer.test.js +863 -0
  233. package/v2Containers/WebPush/tests/sagas.test.js +566 -0
  234. package/v2Containers/WebPush/tests/selectors.test.js +843 -0
  235. package/v2Containers/Whatsapp/tests/__snapshots__/index.test.js.snap +528 -431
  236. package/v2Components/HtmlEditor/components/ValidationTabs/_validationTabs.scss +0 -254
  237. package/v2Components/HtmlEditor/components/ValidationTabs/index.js +0 -362
  238. package/v2Components/HtmlEditor/components/ValidationTabs/messages.js +0 -51
  239. package/v2Containers/BeePopupEditor/constants.js +0 -10
  240. package/v2Containers/BeePopupEditor/index.js +0 -193
  241. package/v2Containers/BeePopupEditor/tests/index.test.js +0 -627
  242. package/v2Containers/EmailWrapper/components/EmailHTMLEditor.js +0 -1046
  243. package/v2Containers/InApp/__tests__/InAppHTMLEditor.test.js +0 -376
  244. package/v2Containers/InApp/__tests__/sagas.test.js +0 -363
  245. package/v2Containers/InApp/tests/selectors.test.js +0 -612
  246. package/v2Containers/InAppWrapper/components/InAppWrapperView.js +0 -162
  247. package/v2Containers/InAppWrapper/components/__tests__/InAppWrapperView.test.js +0 -267
  248. package/v2Containers/InAppWrapper/components/inAppWrapperView.scss +0 -9
  249. package/v2Containers/InAppWrapper/constants.js +0 -16
  250. package/v2Containers/InAppWrapper/hooks/__tests__/useInAppWrapper.test.js +0 -473
  251. package/v2Containers/InAppWrapper/hooks/useInAppWrapper.js +0 -198
  252. package/v2Containers/InAppWrapper/index.js +0 -148
  253. package/v2Containers/InAppWrapper/messages.js +0 -49
  254. package/v2Containers/InappAdvance/index.js +0 -1099
  255. package/v2Containers/InappAdvance/index.scss +0 -10
  256. 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, // Minimum 1 second between auto-saves
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
- [DEVICE_TYPES.IOS]: '',
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(() => deviceContent?.[activeDevice] || '', [deviceContent, activeDevice]);
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?.DEFAULT_CONTENT_TYPE) {
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((prev) => {
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 - pass only changed device content
178
- // This prevents parent from updating both device states when only one changed
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 - in sync mode, pass full content
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(() => typeof currentContent === CONTENT_VALIDATION.DEFAULT_CONTENT_TYPE
279
- && currentContent?.trim()?.length > CONTENT_VALIDATION.MIN_CONTENT_LENGTH, [currentContent]);
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(() => typeof currentContent === CONTENT_VALIDATION.DEFAULT_CONTENT_TYPE
283
- ? currentContent?.length
284
- : CONTENT_VALIDATION?.MIN_CONTENT_LENGTH, [currentContent]);
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) => deviceContent[device] || '', [deviceContent]);
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((prev) => ({
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
- if (autoSaveTimerRef.current) {
322
- clearTimeout(autoSaveTimerRef.current);
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
  };
@@ -26,4 +26,4 @@ export { HTML_EDITOR_VARIANTS, DEVICE_TYPES } from './constants';
26
26
  * - Default export (lazy): ~0KB initial bundle (loads ~400KB when needed)
27
27
  * - HTMLEditorSync: ~400KB added to initial bundle
28
28
  * - Constants: ~1KB added to initial bundle
29
- */
29
+ */