@capillarytech/creatives-library 8.0.357 → 8.0.359-alpha.0
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/index.html +0 -1
- package/package.json +1 -1
- package/utils/cdnTransformation.js +3 -75
- package/utils/tests/cdnTransformation.test.js +0 -127
- package/v2Components/CommonTestAndPreview/UnifiedPreview/PreviewHeader.js +0 -16
- package/v2Components/CommonTestAndPreview/UnifiedPreview/ViberPreviewContent.js +132 -14
- package/v2Components/CommonTestAndPreview/UnifiedPreview/_unifiedPreview.scss +163 -54
- package/v2Components/CommonTestAndPreview/UnifiedPreview/index.js +6 -52
- package/v2Components/CommonTestAndPreview/constants.js +0 -2
- package/v2Components/CommonTestAndPreview/index.js +231 -77
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/PreviewHeader.test.js +0 -163
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/ViberPreviewContent.test.js +364 -0
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/index.test.js +0 -255
- package/v2Components/CommonTestAndPreview/tests/constants.test.js +1 -2
- package/v2Components/CommonTestAndPreview/tests/index.test.js +0 -194
- package/v2Components/FormBuilder/index.js +52 -162
- package/v2Components/TestAndPreviewSlidebox/index.js +2 -2
- package/v2Containers/App/constants.js +0 -3
- package/v2Containers/CreativesContainer/index.js +24 -60
- package/v2Containers/Templates/_templates.scss +77 -0
- package/v2Containers/Templates/index.js +92 -82
- package/v2Containers/Templates/sagas.js +1 -6
- package/v2Containers/Templates/tests/sagas.test.js +6 -23
- package/v2Containers/Viber/constants.js +19 -0
- package/v2Containers/Viber/index.js +714 -47
- package/v2Containers/Viber/index.scss +148 -0
- package/v2Containers/Viber/messages.js +116 -0
- package/v2Containers/Viber/tests/index.test.js +80 -0
- package/v2Containers/WebPush/Create/index.js +8 -91
- package/v2Containers/WebPush/Create/index.scss +0 -7
- package/v2Components/CommonTestAndPreview/UnifiedPreview/WebPushPreviewContent.js +0 -169
- package/v2Components/CommonTestAndPreview/tests/UnifiedPreview/WebPushPreviewContent.test.js +0 -522
- package/v2Containers/App/tests/constants.test.js +0 -61
- package/v2Containers/Templates/tests/webpush.test.js +0 -375
- package/v2Containers/WebPush/Create/tests/getTemplateContent.test.js +0 -348
- package/v2Containers/WebPush/Create/tests/testAndPreviewIntegration.test.js +0 -325
|
@@ -72,6 +72,7 @@ import * as ebillActions from '../Ebill/actions';
|
|
|
72
72
|
import * as emailActions from '../Email/actions';
|
|
73
73
|
import * as lineActions from '../Line/Container/actions';
|
|
74
74
|
import * as viberActions from '../Viber/actions';
|
|
75
|
+
import { VIBER_MEDIA_TYPES } from '../Viber/constants';
|
|
75
76
|
import * as facebookActions from '../Facebook/actions';
|
|
76
77
|
import * as whatsappActions from '../Whatsapp/actions';
|
|
77
78
|
import * as rcsActions from '../Rcs/actions';
|
|
@@ -104,9 +105,6 @@ import {
|
|
|
104
105
|
VIBER as VIBER_CHANNEL,
|
|
105
106
|
FACEBOOK as FACEBOOK_CHANNEL,
|
|
106
107
|
CREATE,
|
|
107
|
-
EXTERNAL_URL,
|
|
108
|
-
URL,
|
|
109
|
-
SITE_URL,
|
|
110
108
|
} from '../App/constants';
|
|
111
109
|
import {MAX_WHATSAPP_TEMPLATES, WARNING_WHATSAPP_TEMPLATES , ACCOUNT_MAPPING_ON_CHANNEL, noFilteredWhatsappZaloTemplatesTitle, noFilteredWhatsappZaloTemplatesDesc, noApprovedWhatsappZaloTemplatesTitle, noApprovedWhatsappTemplatesDesc, zaloDescIllustration, noApprovedRcsTemplatesTitle, noApprovedRcsTemplatesDesc, ARCHIVE_STATUS_ACTIVE, ARCHIVE_STATUS_ARCHIVED, ARCHIVE_REFRESH_TYPE_ARCHIVE, ARCHIVE_REFRESH_TYPE_UNARCHIVE} from './constants';
|
|
112
110
|
import { COPY_OF, EMBEDDED } from '../../constants/unified';
|
|
@@ -1374,6 +1372,11 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1374
1372
|
const image = viberContent.image || {};
|
|
1375
1373
|
const video = viberContent.video || {};
|
|
1376
1374
|
const button = viberContent.button || {};
|
|
1375
|
+
const messageType = viberContent.type || '';
|
|
1376
|
+
const cardsRaw = viberContent.cards;
|
|
1377
|
+
const cards = Array.isArray(cardsRaw) ? cardsRaw : [];
|
|
1378
|
+
const isCarousel =
|
|
1379
|
+
messageType === VIBER_MEDIA_TYPES.CAROUSEL || cards.length > 0;
|
|
1377
1380
|
|
|
1378
1381
|
const viberPreview = {
|
|
1379
1382
|
messageContent: text,
|
|
@@ -1391,81 +1394,39 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1391
1394
|
};
|
|
1392
1395
|
}
|
|
1393
1396
|
|
|
1397
|
+
if (isCarousel) {
|
|
1398
|
+
viberPreview.type = VIBER_MEDIA_TYPES.CAROUSEL;
|
|
1399
|
+
viberPreview.cards = cards.map((card) => ({
|
|
1400
|
+
text: card?.text || '',
|
|
1401
|
+
mediaUrl: card?.mediaUrl || '',
|
|
1402
|
+
buttons: (card?.buttons || []).map((btn) => ({
|
|
1403
|
+
title: btn?.title || '',
|
|
1404
|
+
action: btn?.action || '',
|
|
1405
|
+
})),
|
|
1406
|
+
}));
|
|
1407
|
+
viberPreview.showCarouselEditorPreview = true;
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1394
1410
|
// Extract account name
|
|
1395
1411
|
const accountName = get(template, 'definition.accountName', '');
|
|
1396
1412
|
|
|
1397
1413
|
// Return Viber content object (same as Viber/index.js getTemplateContent)
|
|
1398
1414
|
return {
|
|
1399
1415
|
viberPreviewContent: viberPreview,
|
|
1400
|
-
accountName: accountName
|
|
1401
|
-
brandName: accountName
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
onClickAction,
|
|
1415
|
-
cta: existingCta,
|
|
1416
|
-
image,
|
|
1417
|
-
ctas: rawCtas,
|
|
1418
|
-
expandableDetails: existingExpandable,
|
|
1419
|
-
} = webpushContent;
|
|
1420
|
-
const accountId = get(template, 'definition.accountId', null);
|
|
1421
|
-
const templateName = template?.name || '';
|
|
1422
|
-
|
|
1423
|
-
// iconImageUrl stored as brandIcon in creatives format
|
|
1424
|
-
const iconImageUrl = brandIcon || existingIconImageUrl || undefined;
|
|
1425
|
-
|
|
1426
|
-
// cta stored as onClickAction in creatives format (type: URL|SITE_URL, url)
|
|
1427
|
-
// or already as cta in campaign format (type: EXTERNAL_URL|SITE_URL, actionLink)
|
|
1428
|
-
let cta = null;
|
|
1429
|
-
if (onClickAction) {
|
|
1430
|
-
const ctaType = onClickAction.type === URL ? EXTERNAL_URL : (onClickAction.type || SITE_URL);
|
|
1431
|
-
cta = { type: ctaType, actionLink: onClickAction.url || '' };
|
|
1432
|
-
} else if (existingCta) {
|
|
1433
|
-
cta = { type: existingCta.type || EXTERNAL_URL, actionLink: existingCta.actionLink || '' };
|
|
1434
|
-
}
|
|
1435
|
-
|
|
1436
|
-
// expandableDetails: image → media[], ctas[] → mapped ctas
|
|
1437
|
-
let expandableDetails = null;
|
|
1438
|
-
const hasImage = !!image;
|
|
1439
|
-
const hasCtas = Array.isArray(rawCtas) && rawCtas.length > 0;
|
|
1440
|
-
if (hasImage || hasCtas) {
|
|
1441
|
-
expandableDetails = {
|
|
1442
|
-
media: hasImage ? [{ url: image, type: IMAGE }] : [],
|
|
1443
|
-
ctas: hasCtas ? rawCtas.map((ctaItem) => ({
|
|
1444
|
-
type: ctaItem?.type === URL ? EXTERNAL_URL : (ctaItem?.type || EXTERNAL_URL),
|
|
1445
|
-
action: ctaItem?.action || '',
|
|
1446
|
-
title: ctaItem?.actionText || ctaItem?.title || '',
|
|
1447
|
-
actionLink: ctaItem?.actionLink || '',
|
|
1448
|
-
})) : [],
|
|
1449
|
-
};
|
|
1450
|
-
} else if (existingExpandable) {
|
|
1451
|
-
expandableDetails = {
|
|
1452
|
-
media: existingExpandable?.media || [],
|
|
1453
|
-
ctas: existingExpandable?.ctas || [],
|
|
1454
|
-
};
|
|
1455
|
-
}
|
|
1456
|
-
|
|
1457
|
-
return {
|
|
1458
|
-
channel: WEBPUSH,
|
|
1459
|
-
accountId,
|
|
1460
|
-
content: {
|
|
1461
|
-
title,
|
|
1462
|
-
message,
|
|
1463
|
-
...(iconImageUrl ? { iconImageUrl } : {}),
|
|
1464
|
-
...(cta ? { cta } : {}),
|
|
1465
|
-
...(expandableDetails ? { expandableDetails } : {}),
|
|
1466
|
-
},
|
|
1467
|
-
messageSubject: templateName || title,
|
|
1468
|
-
offers: [],
|
|
1416
|
+
accountName: accountName || '',
|
|
1417
|
+
brandName: accountName || '',
|
|
1418
|
+
messageContent: text,
|
|
1419
|
+
...(isCarousel && {
|
|
1420
|
+
type: VIBER_MEDIA_TYPES.CAROUSEL,
|
|
1421
|
+
cards: viberPreview.cards,
|
|
1422
|
+
}),
|
|
1423
|
+
...(!isCarousel && !isEmpty(button) && button.text && (button.url || viberContent.buttonURL) && {
|
|
1424
|
+
button: {
|
|
1425
|
+
text: button.text,
|
|
1426
|
+
url: button.url || viberContent.buttonURL || '',
|
|
1427
|
+
},
|
|
1428
|
+
}),
|
|
1429
|
+
buttonURL: button.url || viberContent.buttonURL || '',
|
|
1469
1430
|
};
|
|
1470
1431
|
}
|
|
1471
1432
|
|
|
@@ -1481,7 +1442,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
1481
1442
|
* @returns {Boolean} - True if channel supports Test and Preview
|
|
1482
1443
|
*/
|
|
1483
1444
|
isTestAndPreviewSupported = () => {
|
|
1484
|
-
const supportedChannels = [EMAIL, SMS, INAPP, MOBILE_PUSH, VIBER, ZALO
|
|
1445
|
+
const supportedChannels = [EMAIL, SMS, INAPP, MOBILE_PUSH, VIBER, ZALO];
|
|
1485
1446
|
return supportedChannels.includes(this.state.channel.toUpperCase());
|
|
1486
1447
|
}
|
|
1487
1448
|
|
|
@@ -2041,7 +2002,7 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2041
2002
|
// Show preview icon only for channels that don't support Test and Preview
|
|
2042
2003
|
(() => {
|
|
2043
2004
|
// Channels that have Test and Preview integrated
|
|
2044
|
-
const testAndPreviewChannels = [EMAIL, SMS, WHATSAPP, RCS, INAPP, MOBILE_PUSH, VIBER, ZALO
|
|
2005
|
+
const testAndPreviewChannels = [EMAIL, SMS, WHATSAPP, RCS, INAPP, MOBILE_PUSH, VIBER, ZALO];
|
|
2045
2006
|
const isTestAndPreviewSupported = testAndPreviewChannels.includes(currentChannel.toUpperCase());
|
|
2046
2007
|
|
|
2047
2008
|
// Don't show preview icon if channel supports Test and Preview
|
|
@@ -2411,10 +2372,52 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
2411
2372
|
image = {},
|
|
2412
2373
|
button = {},
|
|
2413
2374
|
video = {},
|
|
2375
|
+
type = '',
|
|
2376
|
+
cards = [],
|
|
2414
2377
|
} = {},
|
|
2415
2378
|
} = {},
|
|
2416
2379
|
} = template.versions.base;
|
|
2380
|
+
const isViberCarousel = type === VIBER_MEDIA_TYPES.CAROUSEL;
|
|
2417
2381
|
templateData.content = text;
|
|
2382
|
+
if (isViberCarousel) {
|
|
2383
|
+
const previewCards = Array.isArray(cards) ? cards.slice(0, 1) : [];
|
|
2384
|
+
templateData.className = 'viber-carousel-static';
|
|
2385
|
+
templateData.content = (
|
|
2386
|
+
<CapRow className="viber-carousel-static-content">
|
|
2387
|
+
<CapRow className="viber-carousel-static-message-box">
|
|
2388
|
+
<CapLabel type="label1" className="viber-carousel-static-message">
|
|
2389
|
+
{text}
|
|
2390
|
+
</CapLabel>
|
|
2391
|
+
</CapRow>
|
|
2392
|
+
<CapRow className="viber-carousel-static-cards">
|
|
2393
|
+
{previewCards.map((card, cardIdx) => (
|
|
2394
|
+
<CapRow className="viber-carousel-static-card" key={`viber-static-card-${cardIdx}`}>
|
|
2395
|
+
{card?.mediaUrl ? (
|
|
2396
|
+
<CapImage src={card.mediaUrl} className="viber-carousel-static-image" />
|
|
2397
|
+
) : (
|
|
2398
|
+
<CapRow className="viber-carousel-static-image-placeholder" />
|
|
2399
|
+
)}
|
|
2400
|
+
<CapLabel type="label1" className="viber-carousel-static-text">
|
|
2401
|
+
{card?.text}
|
|
2402
|
+
</CapLabel>
|
|
2403
|
+
<CapRow className="viber-carousel-static-buttons">
|
|
2404
|
+
{(Array.isArray(card?.buttons) && card.buttons.length ? card.buttons : [{}, {}]).slice(0, 2).map((carouselButton, btnIdx) => (
|
|
2405
|
+
<CapLabel
|
|
2406
|
+
key={`viber-static-btn-${cardIdx}-${btnIdx}`}
|
|
2407
|
+
type="label1"
|
|
2408
|
+
className={`viber-carousel-static-button ${btnIdx === 1 ? 'viber-carousel-static-button-secondary' : ''}`}
|
|
2409
|
+
>
|
|
2410
|
+
{(carouselButton?.title || '').trim()}
|
|
2411
|
+
</CapLabel>
|
|
2412
|
+
))}
|
|
2413
|
+
</CapRow>
|
|
2414
|
+
</CapRow>
|
|
2415
|
+
))}
|
|
2416
|
+
</CapRow>
|
|
2417
|
+
</CapRow>
|
|
2418
|
+
);
|
|
2419
|
+
break;
|
|
2420
|
+
}
|
|
2418
2421
|
if (!isEmpty(image)) {
|
|
2419
2422
|
const { url = '' } = image;
|
|
2420
2423
|
templateData.url = url;
|
|
@@ -4976,15 +4979,22 @@ export class Templates extends React.Component { // eslint-disable-line react/pr
|
|
|
4976
4979
|
? this.props.Templates.selectedWhatsappAccount.name
|
|
4977
4980
|
: null
|
|
4978
4981
|
}
|
|
4979
|
-
// Pass formData for
|
|
4982
|
+
// Pass formData for tag extraction (EMAIL/SMS use nested formData; VIBER uses content object)
|
|
4980
4983
|
formData={
|
|
4981
|
-
|
|
4982
|
-
|
|
4983
|
-
|
|
4984
|
-
|
|
4985
|
-
|
|
4986
|
-
|
|
4987
|
-
|
|
4984
|
+
(() => {
|
|
4985
|
+
const previewContent = this.state.testAndPreviewContent;
|
|
4986
|
+
const channelUpper = this.state.channel?.toUpperCase();
|
|
4987
|
+
if (!previewContent || typeof previewContent !== 'object') {
|
|
4988
|
+
return null;
|
|
4989
|
+
}
|
|
4990
|
+
if (channelUpper === EMAIL || channelUpper === SMS) {
|
|
4991
|
+
return previewContent.formData || null;
|
|
4992
|
+
}
|
|
4993
|
+
if (channelUpper === VIBER) {
|
|
4994
|
+
return previewContent;
|
|
4995
|
+
}
|
|
4996
|
+
return null;
|
|
4997
|
+
})()
|
|
4988
4998
|
}
|
|
4989
4999
|
/>
|
|
4990
5000
|
)}
|
|
@@ -6,7 +6,7 @@ import { CapNotification } from '@capillarytech/cap-ui-library';
|
|
|
6
6
|
// import { schema, normalize } from 'normalizr';
|
|
7
7
|
import * as Api from '../../services/api';
|
|
8
8
|
import * as types from './constants';
|
|
9
|
-
import { saveCdnConfigs, removeAllCdnLocalStorageItems
|
|
9
|
+
import { saveCdnConfigs, removeAllCdnLocalStorageItems } from '../../utils/cdnTransformation';
|
|
10
10
|
import { COPY_OF } from '../../constants/unified';
|
|
11
11
|
import { ZALO_TEMPLATE_INFO_REQUEST } from '../Zalo/constants';
|
|
12
12
|
import { getTemplateInfoById } from '../Zalo/saga';
|
|
@@ -107,11 +107,6 @@ export function* getOrgLevelCampaignSettings() {
|
|
|
107
107
|
|
|
108
108
|
export function* getCdnTransformationConfig() {
|
|
109
109
|
try {
|
|
110
|
-
// VAPT CAP-183204: prefer env vars injected via window.APP_ENV — avoids the
|
|
111
|
-
// API response that leaked CDN/S3 infrastructure details. Fallback to API
|
|
112
|
-
// keeps clusters that haven't received the env vars yet working during rollout.
|
|
113
|
-
if (initCdnConfigFromEnv()) return;
|
|
114
|
-
|
|
115
110
|
const res = yield call(Api.getCdnTransformationConfig);
|
|
116
111
|
if (res?.success && res?.status?.code === 200) {
|
|
117
112
|
const cdnConfigs = res?.response;
|
|
@@ -54,25 +54,10 @@ jest.mock('@capillarytech/cap-ui-library', () => ({
|
|
|
54
54
|
}));
|
|
55
55
|
|
|
56
56
|
describe('getCdnTransformationConfig saga', () => {
|
|
57
|
-
|
|
58
|
-
delete window.APP_ENV;
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("short-circuits to env config and skips the API call when window.APP_ENV is set", async () => {
|
|
62
|
-
const initSpy = jest.spyOn(cdnUtils, "initCdnConfigFromEnv").mockReturnValue(true);
|
|
63
|
-
const apiSpy = jest.spyOn(api, "getCdnTransformationConfig");
|
|
64
|
-
|
|
65
|
-
await expectSaga(getCdnTransformationConfig).run();
|
|
66
|
-
|
|
67
|
-
expect(initSpy).toHaveBeenCalled();
|
|
68
|
-
expect(apiSpy).not.toHaveBeenCalled();
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
it("handle valid response from api", async () => {
|
|
72
|
-
jest.spyOn(cdnUtils, "initCdnConfigFromEnv").mockReturnValue(false);
|
|
57
|
+
it("handle valid response from api", () => {
|
|
73
58
|
const saveCdnConfigsSpy = jest.spyOn(cdnUtils, "saveCdnConfigs");
|
|
74
59
|
|
|
75
|
-
|
|
60
|
+
expectSaga(getCdnTransformationConfig)
|
|
76
61
|
.provide([
|
|
77
62
|
[
|
|
78
63
|
call(api.getCdnTransformationConfig),
|
|
@@ -83,14 +68,13 @@ describe('getCdnTransformationConfig saga', () => {
|
|
|
83
68
|
expect(saveCdnConfigsSpy).toHaveBeenCalled();
|
|
84
69
|
});
|
|
85
70
|
|
|
86
|
-
it("handle error response from api",
|
|
87
|
-
jest.spyOn(cdnUtils, "initCdnConfigFromEnv").mockReturnValue(false);
|
|
71
|
+
it("handle error response from api", () => {
|
|
88
72
|
const removeAllCdnLocalStorageItemsSpy = jest.spyOn(
|
|
89
73
|
cdnUtils,
|
|
90
74
|
"removeAllCdnLocalStorageItems"
|
|
91
75
|
);
|
|
92
76
|
|
|
93
|
-
|
|
77
|
+
expectSaga(getCdnTransformationConfig)
|
|
94
78
|
.provide([
|
|
95
79
|
[
|
|
96
80
|
call(api.getCdnTransformationConfig),
|
|
@@ -101,8 +85,7 @@ describe('getCdnTransformationConfig saga', () => {
|
|
|
101
85
|
expect(removeAllCdnLocalStorageItemsSpy).toHaveBeenCalled();
|
|
102
86
|
});
|
|
103
87
|
|
|
104
|
-
it("remove localStorage items when an error is thrown",
|
|
105
|
-
jest.spyOn(cdnUtils, "initCdnConfigFromEnv").mockReturnValue(false);
|
|
88
|
+
it("remove localStorage items when an error is thrown", () => {
|
|
106
89
|
const saveCdnConfigsSpy = jest.spyOn(cdnUtils, "saveCdnConfigs").mockImplementation(()=>{
|
|
107
90
|
throw new Error()
|
|
108
91
|
});
|
|
@@ -111,7 +94,7 @@ describe('getCdnTransformationConfig saga', () => {
|
|
|
111
94
|
"removeAllCdnLocalStorageItems"
|
|
112
95
|
);
|
|
113
96
|
|
|
114
|
-
|
|
97
|
+
expectSaga(getCdnTransformationConfig)
|
|
115
98
|
.provide([
|
|
116
99
|
[
|
|
117
100
|
call(api.getCdnTransformationConfig),
|
|
@@ -47,7 +47,22 @@ export const VIBER_MEDIA_TYPES = {
|
|
|
47
47
|
TEXT: 'TEXT',
|
|
48
48
|
IMAGE: 'IMAGE',
|
|
49
49
|
VIDEO: 'VIDEO',
|
|
50
|
+
CAROUSEL: 'CAROUSEL',
|
|
50
51
|
};
|
|
52
|
+
export const VIBER_CAROUSEL_MIN_CARDS = 2;
|
|
53
|
+
export const VIBER_CAROUSEL_MAX_CARDS = 5;
|
|
54
|
+
export const VIBER_CAROUSEL_MAX_BUTTONS = 2;
|
|
55
|
+
export const VIBER_CAROUSEL_CARD_TITLE_MIN_LENGTH = 2;
|
|
56
|
+
export const VIBER_CAROUSEL_CARD_TITLE_MAX_LENGTH = 38;
|
|
57
|
+
export const VIBER_CAROUSEL_FIRST_BUTTON_TITLE_MAX_LENGTH = 10;
|
|
58
|
+
export const VIBER_CAROUSEL_SECOND_BUTTON_TITLE_MAX_LENGTH = 12;
|
|
59
|
+
export const VIBER_CAROUSEL_BUTTON_URL_MAX_LENGTH = 1000;
|
|
60
|
+
/** Recommended / validated carousel image height in pixels (passed to image upload). */
|
|
61
|
+
export const VIBER_CAROUSEL_IMG_HEIGHT = 600;
|
|
62
|
+
/** Recommended / validated carousel image width in pixels (passed to image upload). */
|
|
63
|
+
export const VIBER_CAROUSEL_IMG_WIDTH = 696;
|
|
64
|
+
/** Maximum carousel image file size (bytes). 10_000_000 ≈ 10 MB (decimal). */
|
|
65
|
+
export const VIBER_CAROUSEL_IMG_SIZE = 10000000;
|
|
51
66
|
export const ALLOWED_IMAGE_EXTENSIONS_REGEX_VIBER = /\.(jpe?g|png)$/i;
|
|
52
67
|
export const ALLOWED_EXTENSIONS_VIDEO_REGEX_VIBER = /\.(mp4|3gp|m4v|mov)$/i;
|
|
53
68
|
export const NONE = 'NONE';
|
|
@@ -69,6 +84,10 @@ export const mediaRadioOptions = [
|
|
|
69
84
|
value: VIBER_MEDIA_TYPES.VIDEO,
|
|
70
85
|
label: <FormattedMessage {...messages.mediaVideo} />,
|
|
71
86
|
},
|
|
87
|
+
{
|
|
88
|
+
value: VIBER_MEDIA_TYPES.CAROUSEL,
|
|
89
|
+
label: <FormattedMessage {...messages.mediaCarousel} />,
|
|
90
|
+
},
|
|
72
91
|
];
|
|
73
92
|
|
|
74
93
|
export const buttonRadioOptions = [
|