@capillarytech/creatives-library 8.0.353-alpha.1 → 8.0.353-alpha.3
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 +65 -46
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +112 -42
- package/v2Containers/Templates/_templates.scss +4 -3
- package/v2Containers/Templates/index.js +2 -2
- package/v2Containers/Viber/index.js +76 -27
- package/v2Containers/Viber/index.scss +1 -1
- package/v2Containers/Viber/tests/index.test.js +80 -0
package/package.json
CHANGED
|
@@ -29,6 +29,9 @@ import videoPlay from '../../../assets/videoPlay.svg';
|
|
|
29
29
|
const smsMobileAndroid = require('../../../assets/Android.png');
|
|
30
30
|
const smsMobileIos = require('../../../assets/iOS.png');
|
|
31
31
|
|
|
32
|
+
const getTrimmedText = (value = '') => (value ?? '').trim();
|
|
33
|
+
const hasTrimmedText = (value = '') => Boolean(getTrimmedText(value));
|
|
34
|
+
|
|
32
35
|
const ViberPreviewContent = ({
|
|
33
36
|
content,
|
|
34
37
|
device,
|
|
@@ -58,10 +61,10 @@ const ViberPreviewContent = ({
|
|
|
58
61
|
|
|
59
62
|
const cardHasMeaningfulContent = (card) => {
|
|
60
63
|
if (!card || typeof card !== 'object') return false;
|
|
61
|
-
if ((card
|
|
62
|
-
if ((card
|
|
63
|
-
const buttons = card
|
|
64
|
-
return buttons.some((button) => (button?.title
|
|
64
|
+
if (hasTrimmedText(card?.text)) return true;
|
|
65
|
+
if (hasTrimmedText(card?.mediaUrl)) return true;
|
|
66
|
+
const buttons = card?.buttons ?? [];
|
|
67
|
+
return buttons.some((button) => hasTrimmedText(button?.title));
|
|
65
68
|
};
|
|
66
69
|
|
|
67
70
|
const hasMeaningfulCarousel =
|
|
@@ -76,8 +79,8 @@ const ViberPreviewContent = ({
|
|
|
76
79
|
const previewCarouselCards =
|
|
77
80
|
hasCarouselContent && Array.isArray(cards) && cards.length ? cards : hasCarouselContent ? [{}] : [];
|
|
78
81
|
|
|
79
|
-
const trimmedMessageContent = (messageContent
|
|
80
|
-
const trimmedButtonText = (buttonText
|
|
82
|
+
const trimmedMessageContent = getTrimmedText(messageContent);
|
|
83
|
+
const trimmedButtonText = getTrimmedText(buttonText);
|
|
81
84
|
|
|
82
85
|
// Get account name (first letter for icon)
|
|
83
86
|
const accountIcon = (accountName || brandName || 'V')[0]?.toUpperCase();
|
|
@@ -136,7 +139,7 @@ const ViberPreviewContent = ({
|
|
|
136
139
|
// Check if there's any content to display (whitespace-only strings do not count)
|
|
137
140
|
const hasContent = Boolean(
|
|
138
141
|
trimmedMessageContent
|
|
139
|
-
|| (imageURL
|
|
142
|
+
|| hasTrimmedText(imageURL)
|
|
140
143
|
|| videoParams?.viberVideoSrc
|
|
141
144
|
|| trimmedButtonText
|
|
142
145
|
|| hasMeaningfulCarousel
|
|
@@ -168,7 +171,7 @@ const ViberPreviewContent = ({
|
|
|
168
171
|
{hasContent && (
|
|
169
172
|
<CapRow className={`viber-message-container ${device !== ANDROID ? 'viber-message-container-ios' : ''}`}>
|
|
170
173
|
{/* Brand Name Display (from TemplatePreview line 1136) */}
|
|
171
|
-
<CapRow className=
|
|
174
|
+
<CapRow className={`msg-container viber-preview ${showCarouselInPreview ? 'viber-preview-carousel' : ''}`}>
|
|
172
175
|
{/* Account Icon (from TemplatePreview line 1146-1160) */}
|
|
173
176
|
{!hasCarouselContent && (
|
|
174
177
|
<CapRow className="viber-account-icon">
|
|
@@ -177,14 +180,14 @@ const ViberPreviewContent = ({
|
|
|
177
180
|
)}
|
|
178
181
|
|
|
179
182
|
{/* Message Bubble (from TemplatePreview line 1161-1223) */}
|
|
180
|
-
<CapRow className=
|
|
183
|
+
<CapRow className={`message-pop align-left viber-message-pop ${showCarouselInPreview ? 'viber-message-pop-carousel' : ''}`}>
|
|
181
184
|
{/* Text Viber preview */}
|
|
182
185
|
{trimmedMessageContent && !hasCarouselContent && (
|
|
183
186
|
<CapLabel type="label15" className="viber-message-text">{messageContent}</CapLabel>
|
|
184
187
|
)}
|
|
185
188
|
|
|
186
189
|
{/* Image Viber preview */}
|
|
187
|
-
{(imageURL
|
|
190
|
+
{hasTrimmedText(imageURL) && (
|
|
188
191
|
<CapImage
|
|
189
192
|
src={imageURL}
|
|
190
193
|
className="viber-image-preview"
|
|
@@ -224,52 +227,68 @@ const ViberPreviewContent = ({
|
|
|
224
227
|
{/* Carousel Viber preview */}
|
|
225
228
|
{showCarouselInPreview && (
|
|
226
229
|
<>
|
|
227
|
-
<CapRow className="viber-carousel-message-
|
|
230
|
+
<CapRow className="viber-carousel-message-pop">
|
|
228
231
|
{trimmedMessageContent ? (
|
|
229
|
-
<CapLabel
|
|
232
|
+
<CapLabel
|
|
233
|
+
type="label15"
|
|
234
|
+
className="message-pop-item align-left viber-message-text viber-carousel-message-box-text"
|
|
235
|
+
>
|
|
230
236
|
{messageContent}
|
|
231
237
|
</CapLabel>
|
|
232
238
|
) : (
|
|
233
239
|
<CapRow className="viber-carousel-message-box-placeholder" />
|
|
234
240
|
)}
|
|
241
|
+
<CapLabel type="label1" className="viber-carousel-message-timestamp">
|
|
242
|
+
{timestamp}
|
|
243
|
+
</CapLabel>
|
|
235
244
|
</CapRow>
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
245
|
+
|
|
246
|
+
<CapRow className="viber-carousel-cards-pop">
|
|
247
|
+
<CapRow className="viber-carousel-preview-scroll">
|
|
248
|
+
{previewCarouselCards?.map((card, index) => (
|
|
249
|
+
<CapRow className="viber-carousel-preview-card" key={`viber-carousel-preview-card-${index}`}>
|
|
250
|
+
{hasTrimmedText(card?.mediaUrl) ? (
|
|
251
|
+
<CapImage
|
|
252
|
+
src={card?.mediaUrl}
|
|
253
|
+
className="viber-carousel-preview-image"
|
|
254
|
+
alt="Viber carousel card"
|
|
255
|
+
/>
|
|
256
|
+
) : (
|
|
257
|
+
<CapRow className="viber-carousel-preview-image-placeholder" />
|
|
258
|
+
)}
|
|
259
|
+
<CapRow className="viber-carousel-preview-card-body">
|
|
260
|
+
{hasTrimmedText(card?.text) ? (
|
|
261
|
+
<CapLabel type="label15" className="viber-carousel-preview-text">
|
|
262
|
+
{card?.text}
|
|
263
|
+
</CapLabel>
|
|
264
|
+
) : (
|
|
265
|
+
<CapLabel type="label15" className="viber-carousel-preview-text-placeholder" />
|
|
266
|
+
)}
|
|
267
|
+
{(card?.buttons?.filter((cardButton) => hasTrimmedText(cardButton?.title)) ?? [])
|
|
268
|
+
.slice(0, 2)
|
|
269
|
+
.map((cardButton, btnIndex) => {
|
|
270
|
+
const trimmedCardButtonTitle = getTrimmedText(cardButton?.title);
|
|
271
|
+
return (
|
|
272
|
+
<CapLabel
|
|
273
|
+
className={`viber-carousel-preview-button ${btnIndex === 1 ? 'viber-carousel-preview-button-secondary' : ''}`}
|
|
274
|
+
key={`viber-carousel-preview-btn-${index}-${btnIndex}-${trimmedCardButtonTitle}`}
|
|
275
|
+
>
|
|
276
|
+
{trimmedCardButtonTitle}
|
|
277
|
+
</CapLabel>
|
|
278
|
+
);
|
|
279
|
+
})}
|
|
280
|
+
</CapRow>
|
|
281
|
+
</CapRow>
|
|
282
|
+
))}
|
|
283
|
+
</CapRow>
|
|
267
284
|
</CapRow>
|
|
268
285
|
</>
|
|
269
286
|
)}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
287
|
+
{!showCarouselInPreview && (
|
|
288
|
+
<CapLabel type="label1" className="viber-timestamp">
|
|
289
|
+
{timestamp}
|
|
290
|
+
</CapLabel>
|
|
291
|
+
)}
|
|
273
292
|
<CapRow className="empty-placeholder" />
|
|
274
293
|
</CapRow>
|
|
275
294
|
|
|
@@ -2116,6 +2116,8 @@
|
|
|
2116
2116
|
flex: 1;
|
|
2117
2117
|
display: flex;
|
|
2118
2118
|
flex-direction: column;
|
|
2119
|
+
overflow-y: auto;
|
|
2120
|
+
-webkit-overflow-scrolling: touch;
|
|
2119
2121
|
padding: 0 $CAP_SPACE_16;
|
|
2120
2122
|
background-color: #ffffff;
|
|
2121
2123
|
margin-left: $CAP_SPACE_06;
|
|
@@ -2141,6 +2143,12 @@
|
|
|
2141
2143
|
margin-top: $CAP_SPACE_16;
|
|
2142
2144
|
width: 68%;
|
|
2143
2145
|
|
|
2146
|
+
&.viber-preview-carousel {
|
|
2147
|
+
width: 100%;
|
|
2148
|
+
margin-left: $CAP_SPACE_12;
|
|
2149
|
+
max-height: none;
|
|
2150
|
+
}
|
|
2151
|
+
|
|
2144
2152
|
// Account icon (from TemplatePreview line 1146-1160)
|
|
2145
2153
|
.viber-account-icon {
|
|
2146
2154
|
width: $CAP_SPACE_20;
|
|
@@ -2169,6 +2177,18 @@
|
|
|
2169
2177
|
border-radius: $CAP_SPACE_04;
|
|
2170
2178
|
padding: $CAP_SPACE_04;
|
|
2171
2179
|
|
|
2180
|
+
&.viber-message-pop-carousel {
|
|
2181
|
+
width: 100%;
|
|
2182
|
+
left: 0;
|
|
2183
|
+
margin-top: 0;
|
|
2184
|
+
padding: 0;
|
|
2185
|
+
background: transparent;
|
|
2186
|
+
display: flex;
|
|
2187
|
+
flex-direction: column;
|
|
2188
|
+
align-items: flex-start;
|
|
2189
|
+
gap: $CAP_SPACE_06;
|
|
2190
|
+
}
|
|
2191
|
+
|
|
2172
2192
|
// Text Viber preview (from TemplatePreview line 1166-1174)
|
|
2173
2193
|
.viber-message-text {
|
|
2174
2194
|
margin: 0.107rem $CAP_SPACE_06 $CAP_SPACE_01 0.5rem;
|
|
@@ -2240,38 +2260,110 @@
|
|
|
2240
2260
|
}
|
|
2241
2261
|
}
|
|
2242
2262
|
|
|
2263
|
+
.viber-carousel-message-pop,
|
|
2264
|
+
.viber-carousel-cards-pop {
|
|
2265
|
+
width: 100%;
|
|
2266
|
+
background: $CAP_G08;
|
|
2267
|
+
border-radius: $CAP_SPACE_06;
|
|
2268
|
+
padding: $CAP_SPACE_08;
|
|
2269
|
+
}
|
|
2270
|
+
|
|
2271
|
+
.viber-carousel-message-pop {
|
|
2272
|
+
margin-top: 0;
|
|
2273
|
+
width: 68%;
|
|
2274
|
+
border-radius: 0 $CAP_SPACE_06 $CAP_SPACE_06 $CAP_SPACE_06;
|
|
2275
|
+
}
|
|
2276
|
+
|
|
2277
|
+
.viber-carousel-cards-pop {
|
|
2278
|
+
margin-top: 0;
|
|
2279
|
+
width: 100%;
|
|
2280
|
+
background: transparent;
|
|
2281
|
+
border: none;
|
|
2282
|
+
border-radius: 0;
|
|
2283
|
+
padding: 0;
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2286
|
+
.viber-carousel-message-box {
|
|
2287
|
+
width: 100%;
|
|
2288
|
+
min-height: 2.25rem;
|
|
2289
|
+
height: auto;
|
|
2290
|
+
border-radius: $CAP_SPACE_04;
|
|
2291
|
+
background: transparent;
|
|
2292
|
+
padding: 0 $CAP_SPACE_08;
|
|
2293
|
+
display: flex;
|
|
2294
|
+
align-items: center;
|
|
2295
|
+
}
|
|
2296
|
+
|
|
2297
|
+
.viber-carousel-message-box-text {
|
|
2298
|
+
color: $CAP_G01;
|
|
2299
|
+
margin: 0.107rem $CAP_SPACE_06 $CAP_SPACE_01 0.5rem;
|
|
2300
|
+
white-space: normal;
|
|
2301
|
+
word-break: break-word;
|
|
2302
|
+
overflow: visible;
|
|
2303
|
+
width: 100%;
|
|
2304
|
+
}
|
|
2305
|
+
|
|
2306
|
+
.viber-carousel-message-box-placeholder {
|
|
2307
|
+
width: 100%;
|
|
2308
|
+
height: 0.875rem;
|
|
2309
|
+
border-radius: $CAP_SPACE_04;
|
|
2310
|
+
background: $CAP_G07;
|
|
2311
|
+
}
|
|
2312
|
+
|
|
2313
|
+
.viber-carousel-message-timestamp,
|
|
2314
|
+
.viber-carousel-cards-timestamp {
|
|
2315
|
+
display: block;
|
|
2316
|
+
text-align: right;
|
|
2317
|
+
margin-top: $CAP_SPACE_06;
|
|
2318
|
+
color: $CAP_G04;
|
|
2319
|
+
}
|
|
2320
|
+
|
|
2243
2321
|
.viber-carousel-preview-scroll {
|
|
2244
|
-
margin-top: $CAP_SPACE_08;
|
|
2245
2322
|
display: flex;
|
|
2323
|
+
width: 100%;
|
|
2246
2324
|
overflow-x: auto;
|
|
2247
|
-
|
|
2248
|
-
|
|
2325
|
+
overflow-y: visible;
|
|
2326
|
+
|
|
2249
2327
|
scrollbar-width: none;
|
|
2328
|
+
-webkit-overflow-scrolling: touch;
|
|
2250
2329
|
|
|
2251
2330
|
&::-webkit-scrollbar {
|
|
2252
2331
|
display: none;
|
|
2253
2332
|
}
|
|
2254
2333
|
|
|
2255
2334
|
.viber-carousel-preview-card {
|
|
2256
|
-
|
|
2257
|
-
|
|
2258
|
-
|
|
2259
|
-
|
|
2335
|
+
flex: 0 0 68%;
|
|
2336
|
+
min-width: 68%;
|
|
2337
|
+
margin-right: $CAP_SPACE_08;
|
|
2338
|
+
background: $CAP_G09;
|
|
2339
|
+
border: 1px solid $CAP_G07;
|
|
2340
|
+
border-radius: $CAP_SPACE_12;
|
|
2341
|
+
overflow: hidden;
|
|
2260
2342
|
display: flex;
|
|
2261
2343
|
flex-direction: column;
|
|
2262
|
-
|
|
2344
|
+
|
|
2345
|
+
&:last-child {
|
|
2346
|
+
margin-right: 0;
|
|
2347
|
+
}
|
|
2348
|
+
|
|
2349
|
+
.viber-carousel-preview-card-body {
|
|
2350
|
+
padding: $CAP_SPACE_08;
|
|
2351
|
+
display: flex;
|
|
2352
|
+
flex-direction: column;
|
|
2353
|
+
gap: $CAP_SPACE_06;
|
|
2354
|
+
}
|
|
2263
2355
|
|
|
2264
2356
|
.viber-carousel-preview-image {
|
|
2265
2357
|
width: 100%;
|
|
2266
|
-
height:
|
|
2358
|
+
height: 10rem;
|
|
2267
2359
|
object-fit: cover;
|
|
2268
|
-
border-radius:
|
|
2360
|
+
border-radius: 0;
|
|
2269
2361
|
}
|
|
2270
2362
|
|
|
2271
2363
|
.viber-carousel-preview-image-placeholder {
|
|
2272
2364
|
width: 100%;
|
|
2273
|
-
height:
|
|
2274
|
-
border-radius:
|
|
2365
|
+
height: 10rem;
|
|
2366
|
+
border-radius: 0;
|
|
2275
2367
|
background: $CAP_G07;
|
|
2276
2368
|
}
|
|
2277
2369
|
|
|
@@ -2294,45 +2386,23 @@
|
|
|
2294
2386
|
background: $CAP_PURPLE01;
|
|
2295
2387
|
border-radius: $CAP_SPACE_12;
|
|
2296
2388
|
text-align: center;
|
|
2297
|
-
|
|
2389
|
+
width: 100%;
|
|
2390
|
+
display: flex;
|
|
2391
|
+
align-items: center;
|
|
2392
|
+
justify-content: center;
|
|
2393
|
+
min-height: 1.5rem;
|
|
2394
|
+
padding: $CAP_SPACE_06 $CAP_SPACE_08;
|
|
2298
2395
|
white-space: normal;
|
|
2299
|
-
min-height: 1rem;
|
|
2300
2396
|
}
|
|
2301
2397
|
|
|
2302
2398
|
.viber-carousel-preview-button-secondary {
|
|
2303
2399
|
color: $CAP_PURPLE01;
|
|
2304
|
-
background:
|
|
2305
|
-
border:
|
|
2400
|
+
background: transparent;
|
|
2401
|
+
border: none;
|
|
2306
2402
|
}
|
|
2307
2403
|
}
|
|
2308
2404
|
}
|
|
2309
2405
|
|
|
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
|
-
|
|
2336
2406
|
.empty-placeholder {
|
|
2337
2407
|
height: $CAP_SPACE_08;
|
|
2338
2408
|
}
|
|
@@ -215,7 +215,7 @@
|
|
|
215
215
|
}
|
|
216
216
|
.viber-carousel-static-button {
|
|
217
217
|
display: block;
|
|
218
|
-
min-height:
|
|
218
|
+
min-height: 1.5rem;
|
|
219
219
|
border-radius: $CAP_SPACE_12;
|
|
220
220
|
background: $CAP_PURPLE01;
|
|
221
221
|
color: $CAP_WHITE;
|
|
@@ -225,8 +225,9 @@
|
|
|
225
225
|
}
|
|
226
226
|
.viber-carousel-static-button-secondary {
|
|
227
227
|
color: $CAP_PURPLE01;
|
|
228
|
-
background:
|
|
229
|
-
border:
|
|
228
|
+
background: transparent;
|
|
229
|
+
border: none;
|
|
230
|
+
box-shadow: none;
|
|
230
231
|
}
|
|
231
232
|
}
|
|
232
233
|
|
|
@@ -1413,8 +1413,8 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1413
1413
|
// Return Viber content object (same as Viber/index.js getTemplateContent)
|
|
1414
1414
|
return {
|
|
1415
1415
|
viberPreviewContent: viberPreview,
|
|
1416
|
-
accountName: accountName
|
|
1417
|
-
brandName: accountName
|
|
1416
|
+
accountName: accountName || '',
|
|
1417
|
+
brandName: accountName || '',
|
|
1418
1418
|
messageContent: text,
|
|
1419
1419
|
...(isCarousel && {
|
|
1420
1420
|
type: VIBER_MEDIA_TYPES.CAROUSEL,
|
|
@@ -96,6 +96,7 @@ const createEmptyCarouselButton = () => ({
|
|
|
96
96
|
urlType: STATIC_URL,
|
|
97
97
|
isSaved: false,
|
|
98
98
|
hasAttemptedSave: false,
|
|
99
|
+
hasTouchedAction: false,
|
|
99
100
|
});
|
|
100
101
|
const createEmptyCarouselCard = () => ({
|
|
101
102
|
id: getNextCarouselCardId(),
|
|
@@ -217,6 +218,7 @@ export const Viber = (props) => {
|
|
|
217
218
|
urlType: carouselButton?.urlType || STATIC_URL,
|
|
218
219
|
isSaved: Boolean(carouselButton?.title && carouselButton?.action),
|
|
219
220
|
hasAttemptedSave: Boolean(carouselButton?.hasAttemptedSave),
|
|
221
|
+
hasTouchedAction: Boolean(carouselButton?.hasTouchedAction),
|
|
220
222
|
})),
|
|
221
223
|
}));
|
|
222
224
|
const cardsToSet = normalizedCards.length
|
|
@@ -435,7 +437,7 @@ export const Viber = (props) => {
|
|
|
435
437
|
if (!trimmedCardText) {
|
|
436
438
|
return false;
|
|
437
439
|
}
|
|
438
|
-
if (trimmedCardText
|
|
440
|
+
if (trimmedCardText?.length < VIBER_CAROUSEL_CARD_TITLE_MIN_LENGTH) {
|
|
439
441
|
return formatMessage(messages.carouselCardTitleMinLengthError);
|
|
440
442
|
}
|
|
441
443
|
if (cardText.length > VIBER_CAROUSEL_CARD_TITLE_MAX_LENGTH) {
|
|
@@ -445,11 +447,12 @@ export const Viber = (props) => {
|
|
|
445
447
|
};
|
|
446
448
|
const getCarouselButtonTitleError = (button = {}, buttonIndex = 0, showEmptyError = true) => {
|
|
447
449
|
const title = button?.title || '';
|
|
450
|
+
const trimmedTitle = title.trim();
|
|
448
451
|
const maxLength = getCarouselButtonTitleMaxLength(buttonIndex);
|
|
449
|
-
if (!
|
|
452
|
+
if (!trimmedTitle && showEmptyError) {
|
|
450
453
|
return formatMessage(messages.textCannotBeEmptyError);
|
|
451
454
|
}
|
|
452
|
-
if (!
|
|
455
|
+
if (!trimmedTitle) {
|
|
453
456
|
return false;
|
|
454
457
|
}
|
|
455
458
|
if (title.length > maxLength) {
|
|
@@ -459,11 +462,14 @@ export const Viber = (props) => {
|
|
|
459
462
|
}
|
|
460
463
|
return false;
|
|
461
464
|
};
|
|
462
|
-
const getCarouselButtonActionError = (button = {}) => {
|
|
465
|
+
const getCarouselButtonActionError = (button = {}, showEmptyError = true) => {
|
|
463
466
|
const action = button?.action || '';
|
|
464
|
-
if (!action
|
|
467
|
+
if (!action?.trim() && showEmptyError) {
|
|
465
468
|
return formatMessage(messages.urlCannotBeEmptyError);
|
|
466
469
|
}
|
|
470
|
+
if (!action?.trim()) {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
467
473
|
if (action.length > VIBER_CAROUSEL_BUTTON_URL_MAX_LENGTH) {
|
|
468
474
|
return formatMessage(messages.carouselButtonUrlMaxLengthError);
|
|
469
475
|
}
|
|
@@ -673,7 +679,28 @@ export const Viber = (props) => {
|
|
|
673
679
|
return {
|
|
674
680
|
...card,
|
|
675
681
|
buttons: (card?.buttons || []).map((button, idx) => (
|
|
676
|
-
idx === buttonIndex
|
|
682
|
+
idx === buttonIndex
|
|
683
|
+
? {
|
|
684
|
+
...button,
|
|
685
|
+
[key]: value,
|
|
686
|
+
isSaved: false,
|
|
687
|
+
...(key === 'action' && value?.trim() ? { hasTouchedAction: true } : {}),
|
|
688
|
+
}
|
|
689
|
+
: button
|
|
690
|
+
)),
|
|
691
|
+
};
|
|
692
|
+
}));
|
|
693
|
+
};
|
|
694
|
+
|
|
695
|
+
const markCarouselButtonActionTouched = (cardIndex, buttonIndex) => {
|
|
696
|
+
setCarouselCards((prevCards) => prevCards.map((card, index) => {
|
|
697
|
+
if (index !== cardIndex) {
|
|
698
|
+
return card;
|
|
699
|
+
}
|
|
700
|
+
return {
|
|
701
|
+
...card,
|
|
702
|
+
buttons: (card?.buttons || []).map((button, idx) => (
|
|
703
|
+
idx === buttonIndex ? { ...button, hasTouchedAction: true } : button
|
|
677
704
|
)),
|
|
678
705
|
};
|
|
679
706
|
}));
|
|
@@ -800,13 +827,15 @@ export const Viber = (props) => {
|
|
|
800
827
|
updateOnReUpload={() => updateOnCarouselImageReUpload(cardIndex)}
|
|
801
828
|
index={cardIndex}
|
|
802
829
|
className="cap-custom-image-upload"
|
|
803
|
-
key={`viber-carousel-image-upload-${card
|
|
830
|
+
key={`viber-carousel-image-upload-${card?.id}`}
|
|
804
831
|
imageData={viber}
|
|
805
832
|
channel={VIBER}
|
|
806
833
|
/>
|
|
807
|
-
|
|
808
|
-
|
|
809
|
-
|
|
834
|
+
{showCarouselValidationErrors && !isUrl(card?.mediaUrl || '') && (
|
|
835
|
+
<CapLabel type="label3" className="viber-carousel-image-recommendation">
|
|
836
|
+
Supported image types are .jpg, .jpeg, .png. Max size: 10 MB. Recommended resolution: 696 px x 600 px.
|
|
837
|
+
</CapLabel>
|
|
838
|
+
)}
|
|
810
839
|
<CapRow className="viber-carousel-card-title-header" type="flex" justify="space-between">
|
|
811
840
|
<CapHeading type="h5">
|
|
812
841
|
{formatMessage(messages.carouselCardTextLabel)}
|
|
@@ -839,13 +868,13 @@ export const Viber = (props) => {
|
|
|
839
868
|
</CapHeading>
|
|
840
869
|
{(card?.buttons || []).map((button, buttonIndex) => (
|
|
841
870
|
// eslint-disable-next-line react/no-array-index-key
|
|
842
|
-
<div className="viber-carousel-button" key={`carousel-button-${card
|
|
843
|
-
{button
|
|
871
|
+
<div className="viber-carousel-button" key={`carousel-button-${card?.id}-${buttonIndex}`}>
|
|
872
|
+
{button?.isSaved ? (
|
|
844
873
|
<CapRow className="viber-carousel-saved-button" align="middle" type="flex">
|
|
845
874
|
<CapIcon size="s" type="six-dots" className="viber-carousel-saved-button-icon" />
|
|
846
875
|
<CapIcon size="s" type="reply" className="viber-carousel-saved-button-icon" />
|
|
847
876
|
<CapLabel type="label4" className="viber-carousel-saved-button-text">
|
|
848
|
-
{button
|
|
877
|
+
{button?.title}
|
|
849
878
|
</CapLabel>
|
|
850
879
|
<CapColumn className="button-edit-icon" onClick={() => editCarouselButton(cardIndex, buttonIndex)}>
|
|
851
880
|
<CapIcon type="edit" size="s" />
|
|
@@ -873,7 +902,7 @@ export const Viber = (props) => {
|
|
|
873
902
|
</CapHeading>
|
|
874
903
|
</CapRow>
|
|
875
904
|
<CapInput
|
|
876
|
-
value={button
|
|
905
|
+
value={button?.title ?? ''}
|
|
877
906
|
onChange={({ target: { value } }) => onCarouselButtonChange(cardIndex, buttonIndex, 'title', value)}
|
|
878
907
|
placeholder={formatMessage(messages.carouselButtonTitlePlaceholder)}
|
|
879
908
|
errorMessage={getCarouselButtonTitleError(
|
|
@@ -900,10 +929,16 @@ export const Viber = (props) => {
|
|
|
900
929
|
<CapColumn span={18}>
|
|
901
930
|
<CapInput
|
|
902
931
|
label={formatMessage(messages.carouselButtonActionLabel)}
|
|
903
|
-
value={button
|
|
932
|
+
value={button?.action ?? ''}
|
|
904
933
|
onChange={({ target: { value } }) => onCarouselButtonChange(cardIndex, buttonIndex, 'action', value)}
|
|
934
|
+
onBlur={() => markCarouselButtonActionTouched(cardIndex, buttonIndex)}
|
|
905
935
|
placeholder={formatMessage(messages.carouselButtonActionPlaceholder)}
|
|
906
|
-
errorMessage={getCarouselButtonActionError(
|
|
936
|
+
errorMessage={getCarouselButtonActionError(
|
|
937
|
+
button,
|
|
938
|
+
showCarouselValidationErrors
|
|
939
|
+
|| Boolean(button?.hasAttemptedSave)
|
|
940
|
+
|| Boolean(button?.hasTouchedAction),
|
|
941
|
+
)}
|
|
907
942
|
/>
|
|
908
943
|
</CapColumn>
|
|
909
944
|
</CapRow>
|
|
@@ -1077,11 +1112,11 @@ export const Viber = (props) => {
|
|
|
1077
1112
|
...(isMediaTypeCarousel && {
|
|
1078
1113
|
type: VIBER_MEDIA_TYPES.CAROUSEL,
|
|
1079
1114
|
cards: carouselCards.map((card) => ({
|
|
1080
|
-
text: card
|
|
1081
|
-
mediaUrl: card
|
|
1082
|
-
buttons: (card
|
|
1083
|
-
title: button
|
|
1084
|
-
action: button
|
|
1115
|
+
text: card?.text ?? '',
|
|
1116
|
+
mediaUrl: card?.mediaUrl ?? '',
|
|
1117
|
+
buttons: (card?.buttons ?? []).map((button) => ({
|
|
1118
|
+
title: button?.title ?? '',
|
|
1119
|
+
action: button?.action ?? '',
|
|
1085
1120
|
})),
|
|
1086
1121
|
})),
|
|
1087
1122
|
}),
|
|
@@ -1290,11 +1325,11 @@ export const Viber = (props) => {
|
|
|
1290
1325
|
if (isMediaTypeCarousel) {
|
|
1291
1326
|
messageData.type = VIBER_MEDIA_TYPES.CAROUSEL;
|
|
1292
1327
|
messageData.cards = carouselCards.map((card) => ({
|
|
1293
|
-
text: card
|
|
1294
|
-
mediaUrl: card
|
|
1295
|
-
buttons: (card
|
|
1296
|
-
title: button
|
|
1297
|
-
action: button
|
|
1328
|
+
text: card?.text ?? '',
|
|
1329
|
+
mediaUrl: card?.mediaUrl ?? '',
|
|
1330
|
+
buttons: (card?.buttons ?? []).map((button) => ({
|
|
1331
|
+
title: button?.title ?? '',
|
|
1332
|
+
action: button?.action ?? '',
|
|
1298
1333
|
})),
|
|
1299
1334
|
}));
|
|
1300
1335
|
}
|
|
@@ -1397,6 +1432,20 @@ export const Viber = (props) => {
|
|
|
1397
1432
|
});
|
|
1398
1433
|
};
|
|
1399
1434
|
|
|
1435
|
+
const hasCarouselValidationError = isCarouselCardCountInvalid || hasInvalidCarouselCard || hasInvalidCarouselButton;
|
|
1436
|
+
const getDoneHandler = () => {
|
|
1437
|
+
const doneCallback = onDoneCallback();
|
|
1438
|
+
return () => {
|
|
1439
|
+
if (isMediaTypeCarousel) {
|
|
1440
|
+
setShowCarouselValidationErrors(true);
|
|
1441
|
+
if (hasCarouselValidationError) {
|
|
1442
|
+
return;
|
|
1443
|
+
}
|
|
1444
|
+
}
|
|
1445
|
+
doneCallback();
|
|
1446
|
+
};
|
|
1447
|
+
};
|
|
1448
|
+
|
|
1400
1449
|
const isDisableDone = () => {
|
|
1401
1450
|
// textbox area should not empty and should have max 1000 charactor
|
|
1402
1451
|
if (messageContent?.trim() === '' || errorMessageTextarea) {
|
|
@@ -1476,7 +1525,7 @@ export const Viber = (props) => {
|
|
|
1476
1525
|
</CapRow>
|
|
1477
1526
|
<ViberFooter>
|
|
1478
1527
|
<CapButton
|
|
1479
|
-
onClick={
|
|
1528
|
+
onClick={getDoneHandler()}
|
|
1480
1529
|
disabled={isDisableDone()}
|
|
1481
1530
|
className="create-msg viber-create-msg"
|
|
1482
1531
|
>
|
|
@@ -383,4 +383,84 @@ describe('Test Viber container', () => {
|
|
|
383
383
|
const doneBtn = screen.getByRole('button', { name: /done/i });
|
|
384
384
|
expect(doneBtn).toBeEnabled();
|
|
385
385
|
});
|
|
386
|
+
|
|
387
|
+
it('does not show empty URL error on focus or while typing in carousel button action', async () => {
|
|
388
|
+
renderComponent({
|
|
389
|
+
actions: mockActions,
|
|
390
|
+
globalActions: mockGlobalActions,
|
|
391
|
+
templateData: { mode: 'create' },
|
|
392
|
+
viber: {
|
|
393
|
+
uploadedAssetData: {},
|
|
394
|
+
createTemplateInProgress: false,
|
|
395
|
+
},
|
|
396
|
+
location: {
|
|
397
|
+
pathname: '/sms/edit',
|
|
398
|
+
query: { type: false, module: 'default' },
|
|
399
|
+
search: '',
|
|
400
|
+
},
|
|
401
|
+
isFullMode: true,
|
|
402
|
+
handleClose: jest.fn(),
|
|
403
|
+
});
|
|
404
|
+
|
|
405
|
+
fireEvent.click(screen.getByRole('radio', { name: /carousel/i }));
|
|
406
|
+
const actionInput = await screen.findByPlaceholderText('https://example.com/action');
|
|
407
|
+
|
|
408
|
+
fireEvent.focus(actionInput);
|
|
409
|
+
expect(screen.queryByText("URL can't be empty")).not.toBeInTheDocument();
|
|
410
|
+
|
|
411
|
+
fireEvent.change(actionInput, { target: { value: 'https://' } });
|
|
412
|
+
expect(screen.queryByText("URL can't be empty")).not.toBeInTheDocument();
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
it('shows empty URL error on blur when carousel button action is left empty', async () => {
|
|
416
|
+
renderComponent({
|
|
417
|
+
actions: mockActions,
|
|
418
|
+
globalActions: mockGlobalActions,
|
|
419
|
+
templateData: { mode: 'create' },
|
|
420
|
+
viber: {
|
|
421
|
+
uploadedAssetData: {},
|
|
422
|
+
createTemplateInProgress: false,
|
|
423
|
+
},
|
|
424
|
+
location: {
|
|
425
|
+
pathname: '/sms/edit',
|
|
426
|
+
query: { type: false, module: 'default' },
|
|
427
|
+
search: '',
|
|
428
|
+
},
|
|
429
|
+
isFullMode: true,
|
|
430
|
+
handleClose: jest.fn(),
|
|
431
|
+
});
|
|
432
|
+
|
|
433
|
+
fireEvent.click(screen.getByRole('radio', { name: /carousel/i }));
|
|
434
|
+
const actionInput = await screen.findByPlaceholderText('https://example.com/action');
|
|
435
|
+
|
|
436
|
+
fireEvent.focus(actionInput);
|
|
437
|
+
fireEvent.blur(actionInput);
|
|
438
|
+
|
|
439
|
+
expect(await screen.findByText("URL can't be empty")).toBeInTheDocument();
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
it('shows empty URL error on save when carousel button action is empty', async () => {
|
|
443
|
+
renderComponent({
|
|
444
|
+
actions: mockActions,
|
|
445
|
+
globalActions: mockGlobalActions,
|
|
446
|
+
templateData: { mode: 'create' },
|
|
447
|
+
viber: {
|
|
448
|
+
uploadedAssetData: {},
|
|
449
|
+
createTemplateInProgress: false,
|
|
450
|
+
},
|
|
451
|
+
location: {
|
|
452
|
+
pathname: '/sms/edit',
|
|
453
|
+
query: { type: false, module: 'default' },
|
|
454
|
+
search: '',
|
|
455
|
+
},
|
|
456
|
+
isFullMode: true,
|
|
457
|
+
handleClose: jest.fn(),
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
fireEvent.click(screen.getByRole('radio', { name: /carousel/i }));
|
|
461
|
+
await screen.findByPlaceholderText('https://example.com/action');
|
|
462
|
+
fireEvent.click(screen.getByRole('button', { name: /save/i }));
|
|
463
|
+
|
|
464
|
+
expect(await screen.findByText("URL can't be empty")).toBeInTheDocument();
|
|
465
|
+
});
|
|
386
466
|
});
|