@capillarytech/creatives-library 8.0.352 → 8.0.353-alpha.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.
- package/package.json +1 -1
- package/v2Components/CommonTestAndPreview/UnifiedPreview/ViberPreviewContent.js +108 -9
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +93 -0
- package/v2Components/CommonTestAndPreview/index.js +47 -7
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/ViberPreviewContent.test.js +364 -0
- package/v2Containers/Templates/_templates.scss +76 -0
- package/v2Containers/Templates/index.js +73 -0
- package/v2Containers/Viber/constants.js +19 -0
- package/v2Containers/Viber/index.js +664 -46
- package/v2Containers/Viber/index.scss +148 -0
- package/v2Containers/Viber/messages.js +116 -0
package/package.json
CHANGED
|
@@ -14,7 +14,14 @@ import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
|
|
|
14
14
|
import CapImage from '@capillarytech/cap-ui-library/CapImage';
|
|
15
15
|
import CapTooltip from '@capillarytech/cap-ui-library/CapTooltip';
|
|
16
16
|
import CapRow from '@capillarytech/cap-ui-library/CapRow';
|
|
17
|
-
import {
|
|
17
|
+
import {
|
|
18
|
+
ANDROID,
|
|
19
|
+
IOS,
|
|
20
|
+
ANDROID_DEVICE_NAME,
|
|
21
|
+
IOS_DEVICE_NAME,
|
|
22
|
+
VIBER_ACCOUNT_NAME,
|
|
23
|
+
MEDIA_TYPE_CAROUSEL,
|
|
24
|
+
} from '../constants';
|
|
18
25
|
import messages from '../messages';
|
|
19
26
|
import videoPlay from '../../../assets/videoPlay.svg';
|
|
20
27
|
|
|
@@ -43,7 +50,34 @@ const ViberPreviewContent = ({
|
|
|
43
50
|
imageURL = '',
|
|
44
51
|
videoParams = {},
|
|
45
52
|
buttonText = '',
|
|
53
|
+
type = '',
|
|
54
|
+
cards = [],
|
|
55
|
+
showCarouselEditorPreview = false,
|
|
46
56
|
} = viberContent;
|
|
57
|
+
const hasCarouselContent = type === MEDIA_TYPE_CAROUSEL;
|
|
58
|
+
|
|
59
|
+
const cardHasMeaningfulContent = (card) => {
|
|
60
|
+
if (!card || typeof card !== 'object') return false;
|
|
61
|
+
if ((card.text || '').trim()) return true;
|
|
62
|
+
if ((card.mediaUrl || '').trim()) return true;
|
|
63
|
+
const buttons = card.buttons || [];
|
|
64
|
+
return buttons.some((button) => (button?.title || '').trim());
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
const hasMeaningfulCarousel =
|
|
68
|
+
hasCarouselContent &&
|
|
69
|
+
Array.isArray(cards) &&
|
|
70
|
+
cards.length > 0 &&
|
|
71
|
+
cards.some(cardHasMeaningfulContent);
|
|
72
|
+
|
|
73
|
+
const showCarouselInPreview =
|
|
74
|
+
hasCarouselContent && (Boolean(showCarouselEditorPreview) || hasMeaningfulCarousel);
|
|
75
|
+
|
|
76
|
+
const previewCarouselCards =
|
|
77
|
+
hasCarouselContent && Array.isArray(cards) && cards.length ? cards : hasCarouselContent ? [{}] : [];
|
|
78
|
+
|
|
79
|
+
const trimmedMessageContent = (messageContent || '').trim();
|
|
80
|
+
const trimmedButtonText = (buttonText || '').trim();
|
|
47
81
|
|
|
48
82
|
// Get account name (first letter for icon)
|
|
49
83
|
const accountIcon = (accountName || brandName || 'V')[0]?.toUpperCase();
|
|
@@ -99,8 +133,15 @@ const ViberPreviewContent = ({
|
|
|
99
133
|
);
|
|
100
134
|
}
|
|
101
135
|
|
|
102
|
-
// Check if there's any content to display
|
|
103
|
-
const hasContent =
|
|
136
|
+
// Check if there's any content to display (whitespace-only strings do not count)
|
|
137
|
+
const hasContent = Boolean(
|
|
138
|
+
trimmedMessageContent
|
|
139
|
+
|| (imageURL || '').trim()
|
|
140
|
+
|| videoParams?.viberVideoSrc
|
|
141
|
+
|| trimmedButtonText
|
|
142
|
+
|| hasMeaningfulCarousel
|
|
143
|
+
|| (hasCarouselContent && showCarouselEditorPreview)
|
|
144
|
+
);
|
|
104
145
|
|
|
105
146
|
// Render normal Viber preview
|
|
106
147
|
return (
|
|
@@ -129,19 +170,21 @@ const ViberPreviewContent = ({
|
|
|
129
170
|
{/* Brand Name Display (from TemplatePreview line 1136) */}
|
|
130
171
|
<CapRow className="msg-container viber-preview">
|
|
131
172
|
{/* Account Icon (from TemplatePreview line 1146-1160) */}
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
173
|
+
{!hasCarouselContent && (
|
|
174
|
+
<CapRow className="viber-account-icon">
|
|
175
|
+
{accountIcon}
|
|
176
|
+
</CapRow>
|
|
177
|
+
)}
|
|
135
178
|
|
|
136
179
|
{/* Message Bubble (from TemplatePreview line 1161-1223) */}
|
|
137
180
|
<CapRow className="message-pop align-left viber-message-pop">
|
|
138
181
|
{/* Text Viber preview */}
|
|
139
|
-
{
|
|
182
|
+
{trimmedMessageContent && !hasCarouselContent && (
|
|
140
183
|
<CapLabel type="label15" className="viber-message-text">{messageContent}</CapLabel>
|
|
141
184
|
)}
|
|
142
185
|
|
|
143
186
|
{/* Image Viber preview */}
|
|
144
|
-
{imageURL && (
|
|
187
|
+
{(imageURL || '').trim() && (
|
|
145
188
|
<CapImage
|
|
146
189
|
src={imageURL}
|
|
147
190
|
className="viber-image-preview"
|
|
@@ -171,13 +214,59 @@ const ViberPreviewContent = ({
|
|
|
171
214
|
)}
|
|
172
215
|
|
|
173
216
|
{/* Button Viber preview */}
|
|
174
|
-
{
|
|
217
|
+
{trimmedButtonText && (
|
|
175
218
|
<CapLabel className="viber-button-base">
|
|
176
219
|
<p className="viber-button-card-text">
|
|
177
220
|
{buttonText}
|
|
178
221
|
</p>
|
|
179
222
|
</CapLabel>
|
|
180
223
|
)}
|
|
224
|
+
{/* Carousel Viber preview */}
|
|
225
|
+
{showCarouselInPreview && (
|
|
226
|
+
<>
|
|
227
|
+
<CapRow className="viber-carousel-message-box">
|
|
228
|
+
{trimmedMessageContent ? (
|
|
229
|
+
<CapLabel type="label15" className="viber-carousel-message-box-text">
|
|
230
|
+
{messageContent}
|
|
231
|
+
</CapLabel>
|
|
232
|
+
) : (
|
|
233
|
+
<CapRow className="viber-carousel-message-box-placeholder" />
|
|
234
|
+
)}
|
|
235
|
+
</CapRow>
|
|
236
|
+
<CapRow className="viber-carousel-preview-scroll">
|
|
237
|
+
{previewCarouselCards?.map((card, index) => (
|
|
238
|
+
<CapRow className="viber-carousel-preview-card" key={`viber-carousel-preview-card-${index}`}>
|
|
239
|
+
{(card?.mediaUrl || '').trim() ? (
|
|
240
|
+
<CapImage
|
|
241
|
+
src={card?.mediaUrl}
|
|
242
|
+
className="viber-carousel-preview-image"
|
|
243
|
+
alt="Viber carousel card"
|
|
244
|
+
/>
|
|
245
|
+
) : (
|
|
246
|
+
<CapRow className="viber-carousel-preview-image-placeholder" />
|
|
247
|
+
)}
|
|
248
|
+
{(card?.text || '').trim() ? (
|
|
249
|
+
<CapLabel type="label15" className="viber-carousel-preview-text">
|
|
250
|
+
{card?.text}
|
|
251
|
+
</CapLabel>
|
|
252
|
+
) : (
|
|
253
|
+
<CapLabel type="label15" className="viber-carousel-preview-text-placeholder" />
|
|
254
|
+
)}
|
|
255
|
+
{(card?.buttons?.filter((cardButton) => (cardButton?.title || '').trim()) ?? [])
|
|
256
|
+
.slice(0, 2)
|
|
257
|
+
.map((cardButton, btnIndex) => (
|
|
258
|
+
<CapLabel
|
|
259
|
+
className={`viber-carousel-preview-button ${btnIndex === 1 ? 'viber-carousel-preview-button-secondary' : ''}`}
|
|
260
|
+
key={`viber-carousel-preview-btn-${index}-${btnIndex}-${(cardButton?.title || '').trim()}`}
|
|
261
|
+
>
|
|
262
|
+
{(cardButton?.title || '').trim()}
|
|
263
|
+
</CapLabel>
|
|
264
|
+
))}
|
|
265
|
+
</CapRow>
|
|
266
|
+
))}
|
|
267
|
+
</CapRow>
|
|
268
|
+
</>
|
|
269
|
+
)}
|
|
181
270
|
<CapLabel type="label1" className="viber-timestamp">
|
|
182
271
|
{timestamp}
|
|
183
272
|
</CapLabel>
|
|
@@ -214,6 +303,16 @@ ViberPreviewContent.propTypes = {
|
|
|
214
303
|
viberVideoPreviewImg: PropTypes.string,
|
|
215
304
|
}),
|
|
216
305
|
buttonText: PropTypes.string,
|
|
306
|
+
type: PropTypes.string,
|
|
307
|
+
cards: PropTypes.arrayOf(PropTypes.shape({
|
|
308
|
+
text: PropTypes.string,
|
|
309
|
+
mediaUrl: PropTypes.string,
|
|
310
|
+
buttons: PropTypes.arrayOf(PropTypes.shape({
|
|
311
|
+
title: PropTypes.string,
|
|
312
|
+
action: PropTypes.string,
|
|
313
|
+
})),
|
|
314
|
+
})),
|
|
315
|
+
showCarouselEditorPreview: PropTypes.bool,
|
|
217
316
|
}),
|
|
218
317
|
}),
|
|
219
318
|
device: PropTypes.oneOf([ANDROID, IOS]),
|
|
@@ -2240,6 +2240,99 @@
|
|
|
2240
2240
|
}
|
|
2241
2241
|
}
|
|
2242
2242
|
|
|
2243
|
+
.viber-carousel-preview-scroll {
|
|
2244
|
+
margin-top: $CAP_SPACE_08;
|
|
2245
|
+
display: flex;
|
|
2246
|
+
overflow-x: auto;
|
|
2247
|
+
gap: $CAP_SPACE_08;
|
|
2248
|
+
white-space: nowrap;
|
|
2249
|
+
scrollbar-width: none;
|
|
2250
|
+
|
|
2251
|
+
&::-webkit-scrollbar {
|
|
2252
|
+
display: none;
|
|
2253
|
+
}
|
|
2254
|
+
|
|
2255
|
+
.viber-carousel-preview-card {
|
|
2256
|
+
min-width: 8.75rem;
|
|
2257
|
+
background: $CAP_WHITE;
|
|
2258
|
+
border-radius: $CAP_SPACE_04;
|
|
2259
|
+
padding: $CAP_SPACE_06;
|
|
2260
|
+
display: flex;
|
|
2261
|
+
flex-direction: column;
|
|
2262
|
+
gap: $CAP_SPACE_04;
|
|
2263
|
+
|
|
2264
|
+
.viber-carousel-preview-image {
|
|
2265
|
+
width: 100%;
|
|
2266
|
+
height: 5.357rem;
|
|
2267
|
+
object-fit: cover;
|
|
2268
|
+
border-radius: $CAP_SPACE_04;
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
.viber-carousel-preview-image-placeholder {
|
|
2272
|
+
width: 100%;
|
|
2273
|
+
height: 5.357rem;
|
|
2274
|
+
border-radius: $CAP_SPACE_04;
|
|
2275
|
+
background: $CAP_G07;
|
|
2276
|
+
}
|
|
2277
|
+
|
|
2278
|
+
.viber-carousel-preview-text {
|
|
2279
|
+
color: $CAP_G01;
|
|
2280
|
+
line-height: 1.3;
|
|
2281
|
+
white-space: normal;
|
|
2282
|
+
}
|
|
2283
|
+
|
|
2284
|
+
.viber-carousel-preview-text-placeholder {
|
|
2285
|
+
width: 100%;
|
|
2286
|
+
height: 0.875rem;
|
|
2287
|
+
border-radius: $CAP_SPACE_04;
|
|
2288
|
+
background: $CAP_G07;
|
|
2289
|
+
min-height: 0.875rem;
|
|
2290
|
+
}
|
|
2291
|
+
|
|
2292
|
+
.viber-carousel-preview-button {
|
|
2293
|
+
color: $CAP_WHITE;
|
|
2294
|
+
background: $CAP_PURPLE01;
|
|
2295
|
+
border-radius: $CAP_SPACE_12;
|
|
2296
|
+
text-align: center;
|
|
2297
|
+
padding: 0.179rem $CAP_SPACE_08;
|
|
2298
|
+
white-space: normal;
|
|
2299
|
+
min-height: 1rem;
|
|
2300
|
+
}
|
|
2301
|
+
|
|
2302
|
+
.viber-carousel-preview-button-secondary {
|
|
2303
|
+
color: $CAP_PURPLE01;
|
|
2304
|
+
background: $CAP_WHITE;
|
|
2305
|
+
border: 1px solid $CAP_PURPLE01;
|
|
2306
|
+
}
|
|
2307
|
+
}
|
|
2308
|
+
}
|
|
2309
|
+
|
|
2310
|
+
.viber-carousel-message-box {
|
|
2311
|
+
width: 100%;
|
|
2312
|
+
height: 2.25rem;
|
|
2313
|
+
border-radius: $CAP_SPACE_04;
|
|
2314
|
+
background: $CAP_WHITE;
|
|
2315
|
+
margin-top: $CAP_SPACE_08;
|
|
2316
|
+
padding: 0 $CAP_SPACE_08;
|
|
2317
|
+
display: flex;
|
|
2318
|
+
align-items: center;
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2321
|
+
.viber-carousel-message-box-text {
|
|
2322
|
+
color: $CAP_G01;
|
|
2323
|
+
white-space: nowrap;
|
|
2324
|
+
overflow: hidden;
|
|
2325
|
+
text-overflow: ellipsis;
|
|
2326
|
+
width: 100%;
|
|
2327
|
+
}
|
|
2328
|
+
|
|
2329
|
+
.viber-carousel-message-box-placeholder {
|
|
2330
|
+
width: 100%;
|
|
2331
|
+
height: 0.875rem;
|
|
2332
|
+
border-radius: $CAP_SPACE_04;
|
|
2333
|
+
background: $CAP_G07;
|
|
2334
|
+
}
|
|
2335
|
+
|
|
2243
2336
|
.empty-placeholder {
|
|
2244
2337
|
height: $CAP_SPACE_08;
|
|
2245
2338
|
}
|
|
@@ -1554,6 +1554,8 @@ const CommonTestAndPreview = (props) => {
|
|
|
1554
1554
|
let imageData = null;
|
|
1555
1555
|
let videoData = null;
|
|
1556
1556
|
let buttonData = null;
|
|
1557
|
+
let cardsData = [];
|
|
1558
|
+
let messageType = '';
|
|
1557
1559
|
let accountId = null;
|
|
1558
1560
|
let accountDetails = null;
|
|
1559
1561
|
let scenarioKey = '';
|
|
@@ -1568,6 +1570,8 @@ const CommonTestAndPreview = (props) => {
|
|
|
1568
1570
|
imageData = formDataObj.image || null;
|
|
1569
1571
|
videoData = formDataObj.video || null;
|
|
1570
1572
|
buttonData = formDataObj.button || null;
|
|
1573
|
+
cardsData = formDataObj.cards || [];
|
|
1574
|
+
messageType = formDataObj.type || '';
|
|
1571
1575
|
accountId = formDataObj.accountId || null;
|
|
1572
1576
|
accountDetails = formDataObj.accountDetails || null;
|
|
1573
1577
|
scenarioKey = formDataObj.scenarioKey || VIBER_API_SCENARIO_KEY;
|
|
@@ -1594,6 +1598,8 @@ const CommonTestAndPreview = (props) => {
|
|
|
1594
1598
|
url: formDataObj?.buttonURL || '',
|
|
1595
1599
|
};
|
|
1596
1600
|
}
|
|
1601
|
+
cardsData = viberPreview.cards || formDataObj?.cards || [];
|
|
1602
|
+
messageType = viberPreview.type || formDataObj?.type || '';
|
|
1597
1603
|
// Extract account info from parent formDataObj if available
|
|
1598
1604
|
accountId = formDataObj.accountId || null;
|
|
1599
1605
|
accountDetails = formDataObj.accountDetails || null;
|
|
@@ -1636,6 +1642,10 @@ const CommonTestAndPreview = (props) => {
|
|
|
1636
1642
|
text: messageText,
|
|
1637
1643
|
};
|
|
1638
1644
|
|
|
1645
|
+
if (messageType === CHANNELS.VIBER) {
|
|
1646
|
+
messageType = '';
|
|
1647
|
+
}
|
|
1648
|
+
|
|
1639
1649
|
// Add image if present
|
|
1640
1650
|
if (imageData && imageData.url) {
|
|
1641
1651
|
viberContent.image = {
|
|
@@ -1664,6 +1674,19 @@ const CommonTestAndPreview = (props) => {
|
|
|
1664
1674
|
}
|
|
1665
1675
|
}
|
|
1666
1676
|
|
|
1677
|
+
if (messageType === MEDIA_TYPE_CAROUSEL || (Array.isArray(cardsData) && cardsData.length)) {
|
|
1678
|
+
viberContent.type = MEDIA_TYPE_CAROUSEL;
|
|
1679
|
+
viberContent.cards = (cardsData || []).map((card) => ({
|
|
1680
|
+
text: card?.text || '',
|
|
1681
|
+
mediaUrl: card?.mediaUrl || '',
|
|
1682
|
+
buttons: (card?.buttons || []).map((button) => ({
|
|
1683
|
+
title: button?.title || '',
|
|
1684
|
+
action: button?.action || '',
|
|
1685
|
+
})),
|
|
1686
|
+
}));
|
|
1687
|
+
delete viberContent.button;
|
|
1688
|
+
}
|
|
1689
|
+
|
|
1667
1690
|
// Resolve tags in text if custom values are provided
|
|
1668
1691
|
if (customValuesObj && Object.keys(customValuesObj).length > 0 && viberContent.text) {
|
|
1669
1692
|
viberContent.text = resolveTagsInText(viberContent.text, customValuesObj);
|
|
@@ -2010,6 +2033,13 @@ const CommonTestAndPreview = (props) => {
|
|
|
2010
2033
|
// Only use previewDataHtml if preview call was made
|
|
2011
2034
|
if (hasPreviewCallBeenMade && previewDataHtml?.resolvedBody) {
|
|
2012
2035
|
resolvedContent = previewDataHtml.resolvedBody;
|
|
2036
|
+
if (typeof resolvedContent === 'string') {
|
|
2037
|
+
try {
|
|
2038
|
+
resolvedContent = JSON.parse(resolvedContent);
|
|
2039
|
+
} catch (e) {
|
|
2040
|
+
resolvedContent = null;
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2013
2043
|
}
|
|
2014
2044
|
|
|
2015
2045
|
// Parse content if it's a string
|
|
@@ -2021,15 +2051,25 @@ const CommonTestAndPreview = (props) => {
|
|
|
2021
2051
|
parsedViberContent = {};
|
|
2022
2052
|
}
|
|
2023
2053
|
}
|
|
2024
|
-
//
|
|
2054
|
+
// Merge template preview state with API resolved body so carousel type/cards survive slim responses
|
|
2025
2055
|
if (resolvedContent && typeof resolvedContent === 'object') {
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2056
|
+
const base = parsedViberContent && typeof parsedViberContent === 'object' ? parsedViberContent : {};
|
|
2057
|
+
contentObj = {
|
|
2058
|
+
...base,
|
|
2059
|
+
...resolvedContent,
|
|
2060
|
+
viberPreviewContent: {
|
|
2061
|
+
...base.viberPreviewContent,
|
|
2062
|
+
...resolvedContent.viberPreviewContent,
|
|
2063
|
+
...(resolvedContent.messageContent != null && typeof resolvedContent.messageContent === 'string'
|
|
2064
|
+
? { messageContent: resolvedContent.messageContent }
|
|
2065
|
+
: {}),
|
|
2066
|
+
},
|
|
2067
|
+
};
|
|
2068
|
+
if (base.accountName && !contentObj.accountName) {
|
|
2069
|
+
contentObj.accountName = base.accountName;
|
|
2030
2070
|
}
|
|
2031
|
-
if (
|
|
2032
|
-
contentObj.brandName =
|
|
2071
|
+
if (base.brandName && !contentObj.brandName) {
|
|
2072
|
+
contentObj.brandName = base.brandName;
|
|
2033
2073
|
}
|
|
2034
2074
|
} else {
|
|
2035
2075
|
// Use raw content if no preview call was made or resolvedContent is not available
|