@capillarytech/creatives-library 7.17.117 → 7.17.118-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.
Files changed (26) hide show
  1. package/package.json +1 -1
  2. package/tests/integration/TemplateCreation/TemplateCreation.integration.test.js +16 -12
  3. package/v2Components/CapImageUpload/constants.js +6 -0
  4. package/v2Components/CapImageUpload/index.js +15 -16
  5. package/v2Components/CapImageUpload/messages.js +1 -5
  6. package/v2Components/CapVideoUpload/constants.js +5 -0
  7. package/v2Components/CapVideoUpload/index.js +28 -8
  8. package/v2Components/CapVideoUpload/index.scss +4 -1
  9. package/v2Components/CapVideoUpload/messages.js +4 -4
  10. package/v2Components/TemplatePreview/_templatePreview.scss +21 -0
  11. package/v2Components/TemplatePreview/index.js +56 -45
  12. package/v2Containers/CreativesContainer/SlideBoxContent.js +10 -4
  13. package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -0
  14. package/v2Containers/CreativesContainer/messages.js +4 -0
  15. package/v2Containers/CreativesContainer/tests/SlideBoxContent.test.js +11 -0
  16. package/v2Containers/CreativesContainer/tests/__snapshots__/SlideBoxContent.test.js.snap +225 -0
  17. package/v2Containers/Rcs/tests/__snapshots__/index.test.js.snap +35 -20
  18. package/v2Containers/Templates/_templates.scss +9 -4
  19. package/v2Containers/Templates/index.js +29 -8
  20. package/v2Containers/Viber/constants.js +58 -0
  21. package/v2Containers/Viber/index.js +409 -421
  22. package/v2Containers/Viber/index.scss +113 -0
  23. package/v2Containers/Viber/messages.js +68 -0
  24. package/v2Containers/Viber/style.js +20 -0
  25. package/v2Containers/Viber/tests/index.test.js +297 -0
  26. package/v2Containers/Viber/tests/mockData.js +134 -0
@@ -1,69 +1,59 @@
1
- import React, { useState, useEffect } from 'react';
1
+ import React, { useState, useEffect, useCallback } from 'react';
2
2
  import { bindActionCreators } from 'redux';
3
3
  import { createStructuredSelector } from 'reselect';
4
4
  import { injectIntl, FormattedMessage } from 'react-intl';
5
- import { isUrl } from '../Line/Container/Wrapper/utils';
6
- import { get } from 'lodash';
7
- import withCreatives from '../../hoc/withCreatives';
8
- import {
9
- CapHeader,
10
- CapRow,
11
- CapColumn,
12
- CapSpin,
13
- CapLabel,
14
- CapInput,
15
- CapHeading,
16
- CapDivider,
17
- CapIcon,
18
- CapButton,
19
- CapUploader,
20
- CapDrawer,
21
- CapNotification,
22
- CapImage,
23
- } from '@capillarytech/cap-ui-library';
5
+ import isEmpty from 'lodash/isEmpty';
6
+ import get from 'lodash/get';
7
+ import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
8
+ import CapRow from '@capillarytech/cap-ui-library/CapRow';
9
+ import CapColumn from '@capillarytech/cap-ui-library/CapColumn';
10
+ import CapSpin from '@capillarytech/cap-ui-library/CapSpin';
11
+ import CapLabel from '@capillarytech/cap-ui-library/CapLabel';
12
+ import CapInput from '@capillarytech/cap-ui-library/CapInput';
13
+ import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
14
+ import CapButton from '@capillarytech/cap-ui-library/CapButton';
15
+ import CapNotification from '@capillarytech/cap-ui-library/CapNotification';
16
+ import CapTooltip from '@capillarytech/cap-ui-library/CapTooltip';
17
+ import CapIcon from '@capillarytech/cap-ui-library/CapIcon';
18
+ import CapRadioGroup from '@capillarytech/cap-ui-library/CapRadioGroup';
19
+ import { GA } from '@capillarytech/cap-ui-utils';
24
20
  import { makeSelectViber, makeSelectCreateViber } from './selectors';
25
21
  import * as viberActions from './actions';
26
22
  import { validateTags } from '../../utils/tagValidations';
27
23
  import TemplatePreview from '../../v2Components/TemplatePreview';
28
- import {
29
- CAP_G09,
30
- CAP_SPACE_08,
31
- CAP_SPACE_12,
32
- FONT_COLOR_05,
33
- CAP_SPACE_32,
34
- CAP_SPACE_24,
35
- CAP_WHITE,
36
- CAP_SPACE_16,
37
- CAP_G07,
38
- } from '@capillarytech/cap-ui-library/styled/variables';
39
- import LabelHOC from '@capillarytech/cap-ui-library/assets/HOCs/ComponentWithLabelHOC';
40
- import styled from 'styled-components';
24
+ import { isUrl } from '../Line/Container/Wrapper/utils';
41
25
  import messages from './messages';
42
26
  import TagList from '../TagList';
43
27
  import { makeSelectMetaEntities, setInjectedTags } from '../Cap/selectors';
44
- import Gallery from '../Assets/Gallery';
45
28
  import {
46
- ALLOWED_EXTENSIONS_REGEX,
29
+ ALLOWED_IMAGE_EXTENSIONS_REGEX_VIBER,
30
+ ALLOWED_EXTENSIONS_VIDEO_REGEX_VIBER,
47
31
  VIBER_IMG_HEIGHT,
48
32
  VIBER_IMG_WIDTH,
49
33
  VIBER_IMG_SIZE,
34
+ VIBER_VIDEO_SIZE,
50
35
  charLimit,
36
+ VIBER_MEDIA_TYPES,
37
+ VIBER_BUTTON_TYPES,
38
+ NONE,
39
+ mediaRadioOptions,
40
+ buttonRadioOptions,
51
41
  } from './constants';
52
- import { GA } from '@capillarytech/cap-ui-utils';
42
+ import withCreatives from '../../hoc/withCreatives';
53
43
  import { CREATE, EDIT, TRACK_CREATE_VIBER, TRACK_EDIT_VIBER } from '../App/constants';
54
44
  import { gtmPush } from '../../utils/gtmTrackers';
55
45
  import { VIBER } from '../CreativesContainer/constants';
56
46
  import { getCdnUrl } from '../../utils/cdnTransformation';
57
47
  import globalMessages from '../Cap/messages';
58
-
59
- const { CapHeadingSpan } = CapHeading;
48
+ import CapImageUpload from '../../v2Components/CapImageUpload';
49
+ import CapVideoUpload from '../../v2Components/CapVideoUpload';
50
+ import './index.scss';
51
+ import { ViberFooter } from './style';
60
52
  const { TextArea } = CapInput;
61
53
 
62
-
63
- const Viber = (props) => {
54
+ export const Viber = (props) => {
64
55
  const {
65
56
  intl,
66
- supportedExtensions,
67
57
  isFullMode,
68
58
  injectedTags,
69
59
  location,
@@ -81,47 +71,37 @@ const Viber = (props) => {
81
71
  } = props || {};
82
72
 
83
73
  const { formatMessage } = intl;
84
- const [isImageError, updateImageErrorMessage] = useState(false);
85
- const [isImage, updateImageStatus] = useState(false);
86
- const [imageSrc, setImageSrc] = useState();
87
- const [isDrawerRequired, updateDrawerRequirement] = useState(false);
74
+ const [imageSrc, setImageSrc] = useState('');
88
75
  const [messageContent, updateTextMessageContent] = useState('');
89
76
  const [buttonText, updateButtonText] = useState('');
90
77
  const [buttonURL, updateButtonUrl] = useState('');
91
78
  const [errorMessageTextarea, updateErrorMessageTextArea] = useState(false);
92
- const [imagePreview, updateImagePreview] = useState();
93
79
  const [isEditLoading, updateEditLoading] = useState(false);
94
80
  const [isEditFlow, checkEditFlow] = useState(false);
95
- const [messageTitle, updateTextMessageTitle] = useState('');
81
+ const [messageTitle, updateTextMessageTitle] = useState("");
96
82
  const [errorMessageTitle, updateErrorMessageTitle] = useState(false);
97
83
  const [buttonURLErrorMessage, updateButtonURLErrorMessage] = useState(false);
98
84
  const [accountName, updateAccountName] = useState("");
99
-
100
-
101
- const updateImageSrc = React.useCallback((url)=>{
85
+ const [templateMediaType, setTemplateMediaType] = useState(
86
+ VIBER_MEDIA_TYPES.TEXT
87
+ );
88
+ const [assetList, updateAssetList] = useState([]);
89
+ const [viberVideoSrcAndPreview, setViberVideoSrcAndPreview] = useState({
90
+ viberVideoSrc: '',
91
+ viberVideoPreviewImg: '',
92
+ duration: 0,
93
+ });
94
+ // cta button
95
+ const [buttonType, setButtonType] = useState(NONE);
96
+ const [ctaData, setCtadata] = useState({});
97
+ const [isCtaSaved, setIsCtaSaved] = useState(false);
98
+
99
+ const updateImageSrc = React.useCallback((url) => {
102
100
  const newUrl = getCdnUrl({url, channelName: 'VIBER'});
103
101
  setImageSrc(newUrl);
104
- },[]);
105
-
106
- const StyledHeader = styled(CapHeader)`
107
- margin-bottom: 14px;
108
- `;
109
- const ViberFooter = styled.div`
110
- background-color: ${CAP_WHITE};
111
- position: fixed;
112
- bottom: 0;
113
- width: 100%;
114
- margin-left: -32px;
115
- padding: ${CAP_SPACE_32} ${CAP_SPACE_24};
116
-
117
- .ant-btn {
118
- margin-right: ${CAP_SPACE_16};
119
- }
120
- }
121
- `;
102
+ }, []);
122
103
 
123
104
  const paramObj = params || {};
124
-
125
105
  useEffect(() => {
126
106
  const { id } = paramObj;
127
107
  if (id && !get(templateData, `versions.base.content`)) {
@@ -138,42 +118,51 @@ const Viber = (props) => {
138
118
 
139
119
  useEffect(() => {
140
120
  if ((params && params.id) || (templateData || {}).edit) {
141
- const { viber: editViberContent = {} } = get(templateData, `versions.base.content`) || get(viber, `templateDetails.versions.base.content`) || {};
142
- const editMessageTitle = (templateData || {}).name || get(viber, 'templateDetails.name');
121
+ const { content: editViberContent = {} } =
122
+ get(templateData, `versions.base.content`) ||
123
+ get(viber, `templateDetails.versions.base.content`) ||
124
+ {};
125
+ const editMessageTitle =
126
+ (templateData || {}).name || get(viber, "templateDetails.name");
127
+ const {
128
+ text = "",
129
+ button = {},
130
+ image = {},
131
+ video = {},
132
+ } = editViberContent || {};
133
+ const { text: ctaBtnText = "", url = "" } = button || {};
143
134
  updateTextMessageTitle(editMessageTitle);
144
- updateTextMessageContent(editViberContent.text || '');
145
- updateButtonText(editViberContent.buttonText || '');
146
- updateButtonUrl(editViberContent.buttonURL || '');
147
- if (editViberContent.imageURL) {
148
- updateImageSrc(editViberContent.imageURL);
149
- updateImagePreview(editViberContent.imageURL);
150
- updateImageStatus(true);
135
+ updateTextMessageContent(text || "");
136
+ updateButtonText(ctaBtnText);
137
+ updateButtonUrl(url);
138
+ setIsCtaSaved(true);
139
+ setButtonType(button?.text ? VIBER_BUTTON_TYPES.CTA : NONE);
140
+ setCtadata({ buttonText: button?.text, buttonURL: button?.url });
141
+ if (!isEmpty(image)) {
142
+ setTemplateMediaType(VIBER_MEDIA_TYPES.IMAGE);
143
+ updateImageSrc(image?.url);
144
+ } else if (!isEmpty(video)) {
145
+ setTemplateMediaType(VIBER_MEDIA_TYPES.VIDEO);
146
+ setViberVideoSrcAndPreview({
147
+ viberVideoSrc: video?.thumbnailUrl,
148
+ viberVideoPreviewImg: video?.thumbnailUrl,
149
+ duration: video?.duration,
150
+ });
151
+ updateAssetList({
152
+ ...assetList,
153
+ previewUrl: video?.thumbnailUrl,
154
+ videoSrc: video?.url,
155
+ videoDuration: video?.duration,
156
+ });
157
+ } else {
158
+ setTemplateMediaType(VIBER_MEDIA_TYPES.TEXT);
151
159
  }
152
160
  }
153
161
  }, [viber[`templateDetails`] || templateData]);
154
162
 
155
- // Common container for TEXT, IMAGE and Button
156
- const container = (icon, message, data, showOptional) => (<CapRow
157
- style={{
158
- border: `solid 1px ${CAP_G07}`,
159
- marginBottom: '20px',
160
- }}>
161
- <CapRow style={{ padding: `${CAP_SPACE_12} ${CAP_SPACE_24} 0px` }}>
162
- <CapIcon type={icon}/>
163
- <CapHeading type="h4" style={{position: 'absolute', display: 'inline-block', top: '13px', paddingLeft: '10px'}}>
164
- {message} {" "}
165
- {showOptional && <CapLabel.CapLabelInline type="label14">{formatMessage(messages.optional)}</CapLabel.CapLabelInline>}
166
- </CapHeading>
167
- </CapRow>
168
- <CapDivider className="cap-divider-margin"/>
169
- <CapRow style={{ padding: `0 ${CAP_SPACE_24} 22px` }}>
170
- {data}
171
- </CapRow>
172
- </CapRow>);
173
-
174
- // ******************** Text area Code start here ******************************
163
+ // Text area Code start here
175
164
 
176
- // Tags Code start from here
165
+ // Tags Code start from here
177
166
  useEffect(() => {
178
167
  const type = location && location.query && location.query.type;
179
168
  const getTagsQuery = {
@@ -208,10 +197,9 @@ const Viber = (props) => {
208
197
  const tags = metaEntities && metaEntities.tags
209
198
  ? metaEntities.tags.standard
210
199
  : [];
211
-
212
200
  // tags Code end here
213
201
 
214
- // validation on Text area and tags validation
202
+ // validation on Text area and tags validation
215
203
  const updateTextContentError = (value) => {
216
204
  let errorMessage = false;
217
205
  const { valid, isBraceError } = validateTags({
@@ -225,12 +213,11 @@ const Viber = (props) => {
225
213
  errorMessage = formatMessage(messages.emptyContentErrorMessage);
226
214
  } else if (value.length > charLimit) {
227
215
  errorMessage = formatMessage(messages.limitExceededContentErrorMessage);
228
- } else if (isBraceError){
216
+ } else if (isBraceError) {
229
217
  errorMessage = formatMessage(globalMessages.unbalanacedCurlyBraces);
230
218
  } else if (!valid) {
231
219
  errorMessage = formatMessage(messages.invalidTagError);
232
220
  }
233
-
234
221
  updateErrorMessageTextArea(errorMessage);
235
222
  };
236
223
 
@@ -253,257 +240,152 @@ const Viber = (props) => {
253
240
  updateErrorMessageTitle(errorMessage);
254
241
  };
255
242
  // Text Area container
256
- const TextAreaViber = (<>
257
- <TextArea
258
- id={'viber_textarea'}
259
- label={(
260
- <>
261
- <FormattedMessage {...messages.textMessage} />
262
- <CapLabel
263
- type="label2" style={{display: 'inline-block',
264
- float: 'right'}}>
265
- {(messageContent || '').length}/{charLimit} {" "}
266
- <FormattedMessage {...messages.characters} />
267
-
268
- </CapLabel>
269
- </>
270
- )}
271
- autosize={false}
272
- onChange={onTextContentChange}
273
- className={`${errorMessageTextarea ? 'error' : ''}`}
274
- errorMessage={errorMessageTextarea}
275
- defaultValue={messageContent || ''}
276
- value={messageContent || ''}
277
- rows={5}
278
- cols={2}
279
- />
280
- <TagList
281
- key={'viber_tags'}
282
- moduleFilterEnabled={location && location.query && location.query.type !== 'embedded'}
283
- label={formatMessage(messages.addLabels)}
284
- onTagSelect={onTagSelect}
285
- onContextChange={handleOnTagsContextChange}
286
- location={location}
287
- tags={tags}
288
- injectedTags={injectedTags || {}}
289
- id={'viber_tags'}
290
- userLocale={localStorage.getItem('jlocale') || 'en'}
291
- selectedOfferDetails={selectedOfferDetails}
292
- />
293
- </>);
243
+ const renderTextAreaViber = () => (
244
+ <>
245
+ <CapColumn className="viber-message-header">
246
+ <CapHeading type="h5" className="viber-message-header-style">
247
+ {formatMessage(messages.message)}
248
+ </CapHeading>
249
+ <TagList
250
+ key={"viber_tags"}
251
+ className="tag-list-viber"
252
+ moduleFilterEnabled={
253
+ location && location.query && location.query.type !== "embedded"
254
+ }
255
+ label={formatMessage(messages.addLabels)}
256
+ onTagSelect={onTagSelect}
257
+ onContextChange={handleOnTagsContextChange}
258
+ location={location}
259
+ tags={tags}
260
+ injectedTags={injectedTags || {}}
261
+ id={"viber_tags"}
262
+ userLocale={localStorage.getItem("jlocale") || "en"}
263
+ selectedOfferDetails={selectedOfferDetails}
264
+ />
265
+ </CapColumn>
266
+ <TextArea
267
+ id={"viber_textarea"}
268
+ autosize={false}
269
+ onChange={onTextContentChange}
270
+ className={`${errorMessageTextarea ? "error" : ""}`}
271
+ errorMessage={errorMessageTextarea}
272
+ defaultValue={messageContent || ""}
273
+ value={messageContent || ""}
274
+ rows={5}
275
+ cols={2}
276
+ placeholder={formatMessage(messages.enterMessage)}
277
+ />
278
+ <CapLabel type="label1" className="char-count-viber">
279
+ <FormattedMessage {...messages.charCount} />
280
+ {(messageContent || "").length}/{charLimit}{" "}
281
+ </CapLabel>
282
+ </>
283
+ );
284
+ // Text area Code End here
294
285
 
295
- // ******************** Text area Code End here ******************************
286
+ // template media code start here
296
287
 
297
- // ******************** Image section Code start here ******************************
298
- useEffect(() => {
299
- if (viber[`uploadedAssetData0`] && Object.keys(viber[`uploadedAssetData0`]).length) {
300
- const imgSrc = get(viber, `uploadedAssetData0.metaInfo.secure_file_path`, '');
301
- actions.clearViberAsset(0);
302
- if (imgSrc) {
303
- updateImageSrc(imgSrc);
304
- updateImageStatus(true);
305
- }
306
- }
307
- }, [viber[`uploadedAssetData0`]]);
308
-
309
- const submitAction = (data, incorrectFile) => {
310
- const {
311
- file: {size},
312
- fileParams: {
313
- height,
314
- width,
315
- },
316
- } = data;
317
- if (incorrectFile || size > VIBER_IMG_SIZE || height > VIBER_IMG_HEIGHT || width > VIBER_IMG_WIDTH) {
318
- updateImageErrorMessage(formatMessage(messages.viberImageIncorrectSize));
319
- } else {
320
- updateImageErrorMessage('');
321
- actions.uploadViberAsset(
322
- data.file,
323
- data.type,
324
- data.fileParams,
325
- 0,
326
- );
327
- }
328
- };
288
+ const isMediaTypeImage = templateMediaType === VIBER_MEDIA_TYPES.IMAGE;
289
+ const isMediaTypeVideo = templateMediaType === VIBER_MEDIA_TYPES.VIDEO;
329
290
 
330
- const uploadImages = (e, {files}) => {
331
- if (e) {
332
- e.preventDefault();
333
- }
334
- const _URL = window.URL || window.webkitURL;
335
- let incorrectFile = false;
336
- const file = files[0];
337
- if (!ALLOWED_EXTENSIONS_REGEX.test(file.name)) {
338
- incorrectFile = true;
339
- }
340
- const img = new Image();
341
- img.src = _URL.createObjectURL(file);
342
- img.onload = () => {
343
- const fileParams = {
344
- width: img.width,
345
- height: img.height,
346
- error: file && (file.size / (1e+6) > 3),
347
- };
348
- submitAction({file, type: 'image', fileParams}, incorrectFile);
349
- };
350
- if (e) {
351
- const event = e;
352
- event.target.value = null;
353
- }
291
+ const onTemplateMediaTypeChange = ({ target: { value } }) => {
292
+ setTemplateMediaType(value);
354
293
  };
355
294
 
356
- const ImageComponent = () => (<>
357
- <CapHeader
358
- title={formatMessage(messages.uploadImage)}
359
- description={formatMessage(messages.imageDesc)}
360
- size="regular"
361
- />
362
- <div
363
- className={`image-container ${props.ifError ? 'error' : ''}`}
364
- style={{
365
- marginTop: 20,
366
- backgroundColor: CAP_G09,
367
- }}
368
- >
369
- {isImage && (<CapImage src={imageSrc} alt="viber-image-src" height="400" />)}
370
- </div></>
371
- );
295
+ const uploadViberAsset = (file, type, fileParams) => {
296
+ actions.uploadViberAsset(file, type, fileParams, 0);
297
+ };
372
298
 
373
- const setDrawerVisibility = (drawervisibleFlag) => updateDrawerRequirement(drawervisibleFlag);
299
+ const updateOnViberImageReUpload = useCallback(() => {
300
+ setImageSrc("");
301
+ }, [imageSrc]);
374
302
 
375
- const onGalleryClick = (event) => {
376
- event.stopPropagation();
377
- setDrawerVisibility(true);
378
- };
303
+ const setUpdateViberImageSrc = useCallback(
304
+ (val) => {
305
+ setImageSrc(val);
306
+ actions.clearViberAsset(0);
307
+ },
308
+ [imageSrc]
309
+ );
379
310
 
380
- const capUploaderCustomRequest = (uploadData) => {
381
- uploadImages(undefined, {files: [uploadData.file]});
382
- };
383
- const onReUpload = () => {
384
- updateImageStatus(false);
385
- // deleteUploadedImgList(index);
386
- updateImageSrc('');
387
- updateImagePreview('');
388
- };
389
- const getViberImageSection = () => {
390
- if (!isImage) {
391
- return (<>
392
- <CapUploader.CapDragger
393
- customRequest={capUploaderCustomRequest}
394
- className="form-builder-dragger"
395
- >
396
- <CapHeading className="dragger-title" type="h7">
397
- <FormattedMessage {...messages.dragAndDrop} />
398
- </CapHeading>
399
- <CapHeading className="dragger-or" type="label6">
400
- <FormattedMessage {...messages.or} />
401
- </CapHeading>
402
- <CapButton className="dragger-button" type="secondary" style={{marginRight: CAP_SPACE_08}}>
403
- <FormattedMessage {...messages.uploadComputer} />
404
- </CapButton>
405
- <CapButton
406
- className="dragger-button"
407
- type="secondary"
408
- style={{marginLeft: CAP_SPACE_08}}
409
- onClick={onGalleryClick}
410
- >
411
- <FormattedMessage {...messages.uploadGallery} />
412
- </CapButton>
413
- </CapUploader.CapDragger>
414
- <div style={{marginTop: '15px' }}>
415
- <CapHeadingSpan type="label2" style={{marginTop: CAP_SPACE_12, marginRight: '46px' }}>
416
- <FormattedMessage {...messages.imageDimenstionDescription} />
417
- </CapHeadingSpan>
418
- <CapHeadingSpan type="label2" style={{marginTop: CAP_SPACE_12 }}>
419
- <FormattedMessage {...messages.imageSizeDescription} />
420
- </CapHeadingSpan>
421
- </div>
422
-
423
- </>
424
- );
425
- }
426
- return (
427
- <CapButton
428
- className="dragger-button"
429
- type="flat"
430
- style={{
431
- top: 0,
432
- position: 'absolute',
433
- right: 0,
434
- color: FONT_COLOR_05,
435
- }}
436
- onClick={onReUpload}
437
- >
438
- <FormattedMessage {...messages.imageReUpload} />
439
- </CapButton>
440
- );
441
- };
311
+ const setUpdateViberVideoSrc = useCallback(
312
+ (index, data) => {
313
+ const { videoSrc = "", previewUrl = "", videoDuration } = data;
314
+ setViberVideoSrcAndPreview({
315
+ viberVideoSrc: videoSrc,
316
+ viberVideoPreviewImg: previewUrl,
317
+ duration: videoDuration,
318
+ });
319
+ updateAssetList(data);
320
+ actions.clearViberAsset(0);
321
+ },
322
+ [viberVideoSrcAndPreview?.viberVideoSrc]
323
+ );
442
324
 
443
- const getGalleryDrawerContent = () => {
444
- const locationGallery = {
445
- pathname: `/assets`,
446
- search: '',
447
- query: !isFullMode ? {type: 'embedded', module: 'library'} : {},
448
- };
449
- return (
450
- <>
451
- <CapHeading type="h3">
452
- {formatMessage(messages.imageGallery)}
453
- </CapHeading>
454
- <Gallery
455
- location={locationGallery}
456
- isFullMode={isFullMode}
457
- isLineAsset
458
- onGalleryImageSelect={onGalleryImageSelect}
459
- />
460
- </>
461
- );
462
- };
325
+ const renderMediaSection = () => (
326
+ <>
327
+ <CapHeading type="h4" className="viber-render-heading">
328
+ {formatMessage(messages.mediaLabel)}
329
+ </CapHeading>
330
+ <CapRadioGroup
331
+ id="viber-media-radio"
332
+ options={mediaRadioOptions}
333
+ value={templateMediaType}
334
+ onChange={onTemplateMediaTypeChange}
335
+ className="viber-media-radio"
336
+ />
337
+ </>
338
+ );
463
339
 
464
- const onGalleryImageSelect = (imageTemplate) => {
465
- const image = get(imageTemplate, 'metaInfo.secure_file_path');
466
- const imageURL = get(imageTemplate, 'metaInfo.secure_file_path_preview');
467
- updateDrawerRequirement(false);
468
- if (!ALLOWED_EXTENSIONS_REGEX.test(image)) {
469
- updateImageErrorMessage(formatMessage(messages.viberImageIncorrectSize));
470
- } else {
471
- updateImageErrorMessage('');
472
- updateImageStatus(true);
473
- updateImageSrc(image);
474
- updateImagePreview(imageURL);
475
- }
476
- };
340
+ const renderImageComponent = () => (
341
+ <CapImageUpload
342
+ allowedExtensionsRegex={ALLOWED_IMAGE_EXTENSIONS_REGEX_VIBER}
343
+ imgSize={VIBER_IMG_SIZE}
344
+ imgWidth={VIBER_IMG_WIDTH}
345
+ imgHeight={VIBER_IMG_HEIGHT}
346
+ uploadAsset={uploadViberAsset}
347
+ isFullMode={isFullMode}
348
+ imageSrc={imageSrc}
349
+ updateImageSrc={setUpdateViberImageSrc}
350
+ updateOnReUpload={updateOnViberImageReUpload}
351
+ index={0}
352
+ className="cap-custom-image-upload"
353
+ key="viber-uploaded-image"
354
+ imageData={viber}
355
+ channel={VIBER}
356
+ />
357
+ );
477
358
 
478
- const WithLabel = LabelHOC(ImageComponent);
479
- const ImageViber = <>
480
- <WithLabel
481
- key={`viber-with-label`}
482
- errorMessage={isImageError} ifError={!!isImageError}
359
+ const renderVideoComonent = () => (
360
+ <CapVideoUpload
361
+ index={0}
362
+ allowedExtensionsRegex={ALLOWED_EXTENSIONS_VIDEO_REGEX_VIBER}
363
+ videoSize={VIBER_VIDEO_SIZE}
364
+ isFullMode={isFullMode}
365
+ uploadAsset={uploadViberAsset}
366
+ uploadedAssetList={assetList}
367
+ onVideoUploadUpdateAssestList={setUpdateViberVideoSrc}
368
+ videoData={viber}
369
+ className="cap-custom-video-upload"
370
+ formClassName={"viber-video-upload"}
371
+ channel={VIBER}
372
+ errorMessage={formatMessage(messages.videoErrorMessage)}
373
+ showVideoNameAndDuration={false}
483
374
  />
484
- <form encType="multipart/form-data" id={`viber_form`}>
485
- <input
486
- key={`viber_imgFile`}
487
- style={{ display: 'none' }}
488
- id="fileName"
489
- type="file"
490
- onChange={(e) => uploadImages(e, { files: e.target.files })}
491
- accept={supportedExtensions || "image/*"}
492
- />
493
- {getViberImageSection()}
494
- <CapDrawer
495
- content={getGalleryDrawerContent()}
496
- visible={isDrawerRequired}
497
- width={430}
498
- onClose={() => updateDrawerRequirement(false)}
499
- />
500
- </form>
501
- </>;
502
- // ******************** Image section End here ******************************
375
+ );
376
+
377
+ const renderMediaComponent = () => (
378
+ <>
379
+ {isMediaTypeImage && renderImageComponent()}
380
+ {isMediaTypeVideo && renderVideoComonent()}
381
+ </>
382
+ );
503
383
 
384
+ // template media code end here
504
385
 
505
- // ******************** Button Code start here ******************************
386
+ // Button Code start here
506
387
 
388
+ const isBtnTypeCta = buttonType === VIBER_BUTTON_TYPES.CTA;
507
389
  const onChangeButtonText = ({ target: { value } }) => {
508
390
  updateButtonText(value);
509
391
  };
@@ -516,50 +398,159 @@ const Viber = (props) => {
516
398
  }
517
399
  updateButtonURLErrorMessage(errorMessage);
518
400
  };
519
- const getPreviewSection = () =>
401
+ const getPreviewSection = () => (
520
402
  // const accountName = get(lineData, 'selectedLineAccount.name', '');
521
- (
522
- <TemplatePreview
523
- channel="VIBER"
524
- content={{imageURL: imagePreview, buttonText, messageContent}}
525
- viberAccountName={((accountName[0] || "")).toUpperCase()}
526
- viberBrandName={accountName}
527
- />
528
- );
529
-
530
- const ButtonViber = (<>
531
- <CapInput
532
- id="viber-button-text"
533
- type="input"
534
- onChange={onChangeButtonText}
535
- label={formatMessage(messages.buttonText)}
536
- defaultValue={buttonText}
537
- value={buttonText}
538
- style={{paddingBottom: '11px'}}
539
- maxLength={20}
403
+ <TemplatePreview
404
+ channel={VIBER}
405
+ content={{
406
+ viberPreviewContent: {
407
+ ...(isMediaTypeImage && { imageURL: imageSrc }),
408
+ ...(isMediaTypeVideo && { videoParams: viberVideoSrcAndPreview }),
409
+ buttonText,
410
+ messageContent,
411
+ },
412
+ }}
413
+ viberAccountName={(accountName[0] || "").toUpperCase()}
414
+ viberBrandName={accountName}
540
415
  />
541
- <CapInput
542
- id="viber-button-url"
543
- type="input"
544
- onChange={onChangeButtonUrl}
545
- defaultValue={buttonURL}
546
- value={buttonURL}
547
- label={formatMessage(messages.buttonUrl)}
548
- errorMessage={buttonURLErrorMessage}
416
+ );
417
+
418
+ const handleSaveCta = () => {
419
+ setCtadata({ buttonText, buttonURL });
420
+ setIsCtaSaved(true);
421
+ };
422
+
423
+ const handleEditCta = () => {
424
+ setIsCtaSaved(false);
425
+ updateButtonText(ctaData?.buttonText);
426
+ updateButtonUrl(ctaData?.buttonURL);
427
+ };
428
+
429
+ const handleCancelCta = () => {
430
+ if (isEmpty(ctaData)) {
431
+ setButtonType(NONE);
432
+ } else {
433
+ setIsCtaSaved(true);
434
+ }
435
+ };
436
+
437
+ const isCtaSaveDisabled =
438
+ isEmpty(buttonText.trim()) ||
439
+ isEmpty(buttonURL.trim()) ||
440
+ buttonURLErrorMessage;
441
+
442
+ const ButtonViber = !isCtaSaved ? (
443
+ <div className="cta-section">
444
+ <CapHeading type="h4" className="button-text">
445
+ {formatMessage(messages.buttonText)}{" "}
446
+ <CapTooltip title={formatMessage(messages.buttonTextTooltip)}>
447
+ <CapIcon type="info" size="s" />
448
+ </CapTooltip>
449
+ </CapHeading>
450
+ <CapInput
451
+ id="viber-button-text"
452
+ className="cta-text-input"
453
+ type="input"
454
+ onChange={onChangeButtonText}
455
+ defaultValue={buttonText}
456
+ value={buttonText}
457
+ maxLength={20}
458
+ placeholder={formatMessage(messages.enterButtonText)}
549
459
  />
550
- </>);
460
+ <CapInput
461
+ id="viber-button-url"
462
+ type="input"
463
+ onChange={onChangeButtonUrl}
464
+ defaultValue={buttonURL}
465
+ value={buttonURL}
466
+ label={formatMessage(messages.buttonUrl)}
467
+ errorMessage={buttonURLErrorMessage}
468
+ placeholder={formatMessage(messages.enterButtonUrl)}
469
+ />
470
+ <CapColumn className="cta-actions">
471
+ <CapButton
472
+ disabled={isCtaSaveDisabled}
473
+ className="cta-btn-action"
474
+ onClick={handleSaveCta}
475
+ >
476
+ {formatMessage(messages.save)}
477
+ </CapButton>
478
+ <CapButton className="cta-btn-action" onClick={handleCancelCta}>
479
+ {formatMessage(messages.cancel)}
480
+ </CapButton>
481
+ </CapColumn>
482
+ </div>
483
+ ) : (
484
+ <CapRow className="cta-section-saved">
485
+ <CapLabel type="label4" className="cta-text">
486
+ {ctaData?.buttonText}
487
+ </CapLabel>
488
+ <CapLabel type="label2" className="button-url">
489
+ {ctaData?.buttonURL}
490
+ </CapLabel>
491
+ <CapColumn className="button-edit-icon" onClick={handleEditCta}>
492
+ <CapIcon type="edit" size="s" aria-label="edit-cta-icon"></CapIcon>
493
+ </CapColumn>
494
+ </CapRow>
495
+ );
496
+
497
+ const onChangeButtonType = ({ target: { value } }) => {
498
+ setButtonType(value);
499
+ setCtadata({});
500
+ updateButtonText("");
501
+ updateButtonUrl("");
502
+ setIsCtaSaved(false);
503
+ };
504
+
505
+ const renderButtonsSection = () => (
506
+ <div className="button-section">
507
+ <CapHeader
508
+ className="viber-render-heading"
509
+ title={
510
+ <CapRow type="flex">
511
+ <CapHeading type="h4">
512
+ {formatMessage(messages.btnLabel)}
513
+ </CapHeading>
514
+ <CapHeading className="viber-optional-label">
515
+ {formatMessage(messages.optional)}
516
+ </CapHeading>
517
+ </CapRow>
518
+ }
519
+ description={
520
+ <CapLabel type="label3">{formatMessage(messages.btnDesc)}</CapLabel>
521
+ }
522
+ />
523
+ <CapRadioGroup
524
+ options={buttonRadioOptions}
525
+ value={buttonType}
526
+ onChange={onChangeButtonType}
527
+ className="viber-btn-radio-group"
528
+ />
529
+ {isBtnTypeCta && ButtonViber}
530
+ </div>
531
+ );
532
+ // Button Code End here
551
533
 
552
- // ******************** Button Code End here ******************************
553
534
  const formatSubmitPayload = () => {
554
535
  const messageData = {
555
536
  text: messageContent,
556
537
  };
557
- if (imageSrc) {
558
- messageData.imageURL = imageSrc;
538
+ if (isMediaTypeImage) {
539
+ messageData.image = {};
540
+ messageData.image.url = imageSrc;
559
541
  }
560
- if (buttonText && buttonURL) {
561
- messageData.buttonText = buttonText;
562
- messageData.buttonURL = buttonURL;
542
+ if (isMediaTypeVideo) {
543
+ const { viberVideoSrc, duration, viberVideoPreviewImg } =
544
+ viberVideoSrcAndPreview;
545
+ messageData.video = {};
546
+ messageData.video.url = viberVideoSrc;
547
+ messageData.video.thumbnailUrl = viberVideoPreviewImg;
548
+ messageData.video.duration = duration; // integer value in seconds
549
+ }
550
+ if (!isEmpty(ctaData)) {
551
+ messageData.button = {};
552
+ messageData.button.text = ctaData?.buttonText;
553
+ messageData.button.url = ctaData?.buttonURL;
563
554
  }
564
555
  return {
565
556
  versions: {
@@ -572,7 +563,7 @@ const Viber = (props) => {
572
563
  },
573
564
  },
574
565
  ],
575
- viber: {...messageData},
566
+ content: {...messageData},
576
567
  },
577
568
  },
578
569
  },
@@ -581,7 +572,7 @@ const Viber = (props) => {
581
572
  };
582
573
  };
583
574
 
584
- const createCallback = ({errorMessage, resp}, isEdit) => {
575
+ const createCallback = ({ errorMessage, resp }, isEdit) => {
585
576
  if (!errorMessage) {
586
577
  CapNotification.success({
587
578
  message: isEdit ? formatMessage(messages.viberEditNotification) : formatMessage(messages.viberCreateNotification),
@@ -601,7 +592,7 @@ const Viber = (props) => {
601
592
  channel: VIBER,
602
593
  timeTaken,
603
594
  content: messageContent,
604
- mode: isEdit ? EDIT : CREATE
595
+ mode: isEdit ? EDIT : CREATE,
605
596
  });
606
597
  } else {
607
598
  CapNotification.error({
@@ -615,7 +606,9 @@ const Viber = (props) => {
615
606
  formatSubmitPayload(),
616
607
  (resp, errorMessage) => {
617
608
  createCallback({resp, errorMessage});
618
- onCreateComplete();
609
+ if (!errorMessage) {
610
+ onCreateComplete();
611
+ }
619
612
  }
620
613
  );
621
614
  };
@@ -628,7 +621,9 @@ const Viber = (props) => {
628
621
  },
629
622
  (resp, errorMessage) => {
630
623
  createCallback({resp, errorMessage}, true);
631
- onCreateComplete();
624
+ if (!errorMessage) {
625
+ onCreateComplete();
626
+ }
632
627
  });
633
628
  };
634
629
 
@@ -652,22 +647,24 @@ const Viber = (props) => {
652
647
  if (messageContent?.trim() === '' || errorMessageTextarea) {
653
648
  return true;
654
649
  }
655
- // cannot send text + image only messages, Need to add button details or remove one of the components in order to proceed
656
- const trimedButtonText = buttonText.trim();
657
- const trimedButtonUrl = buttonURL.trim();
658
- if (messageContent !== '' && imageSrc && (trimedButtonUrl === '' && trimedButtonUrl === '')) {
659
- return true;
660
- }
661
- // if button is being added than button url and button Text both are mandatory
662
- if (( trimedButtonText === '' && trimedButtonUrl !== '') || ( trimedButtonText !== '' && trimedButtonUrl === '')) {
650
+ // // cannot send text + image only messages, Need to add button details or remove one of the components in order to proceed
651
+ // const trimedButtonText = buttonText.trim();
652
+ // const trimedButtonUrl = buttonURL.trim();
653
+ // if (messageContent !== '' && (trimedButtonText === '' && trimedButtonUrl === '')) {
654
+ // return true;
655
+ // }
656
+ //if template title is empty
657
+ if (messageTitle?.trim() === '') {
663
658
  return true;
664
659
  }
665
- // if button url is not valid url
666
- if (buttonURLErrorMessage) {
660
+ // if media type is image/video than image/video should be uploaded
661
+ if (
662
+ (isMediaTypeImage && !imageSrc) ||
663
+ (isMediaTypeVideo && !viberVideoSrcAndPreview.viberVideoSrc)
664
+ ) {
667
665
  return true;
668
666
  }
669
- //if template title is empty
670
- if (messageTitle?.trim() === '') {
667
+ if (isBtnTypeCta && !isCtaSaved) {
671
668
  return true;
672
669
  }
673
670
  return false;
@@ -678,32 +675,25 @@ const Viber = (props) => {
678
675
  <CapSpin spinning={isEditLoading}>
679
676
  <CapRow>
680
677
  <CapColumn span={14}>
681
- <StyledHeader
682
- title={formatMessage(messages.viberCreativeTitle)}
683
- size="regular"
684
- />
685
- {
686
- isFullMode
687
- ? (
688
- <CapInput
689
- id={`viber_input`}
690
- onChange={onTextTitleChange}
691
- errorMessage={errorMessageTitle}
692
- className="text-template-title"
693
- placeholder={formatMessage(messages.textMessageTitlePlaceholder)}
694
- defaultValue={messageTitle || ''}
695
- value={messageTitle || ''}
696
- size="default"
697
- label={formatMessage(messages.textMessageTitleLabel)}
698
- style={{marginBottom: 20}}
699
- data-testid="template_name"
700
- />
701
- )
702
- : null
703
- }
704
- {container("message", <FormattedMessage {...messages.message} />, TextAreaViber, false)}
705
- {container("image", <FormattedMessage {...messages.image} />, ImageViber, true)}
706
- {container("button", <FormattedMessage {...messages.button} />, ButtonViber, true)}
678
+ {isFullMode ? (
679
+ <CapInput
680
+ id={`viber_input`}
681
+ onChange={onTextTitleChange}
682
+ errorMessage={errorMessageTitle}
683
+ placeholder={formatMessage(
684
+ messages.textMessageTitlePlaceholder
685
+ )}
686
+ defaultValue={messageTitle || ""}
687
+ value={messageTitle || ""}
688
+ size="default"
689
+ label={formatMessage(messages.textMessageTitleLabel)}
690
+ data-testid="template_name"
691
+ />
692
+ ) : null}
693
+ {renderMediaSection()}
694
+ {renderMediaComponent()}
695
+ {renderTextAreaViber()}
696
+ {renderButtonsSection()}
707
697
  <div style={{marginBottom: '100px'}}/>
708
698
  </CapColumn>
709
699
  <CapColumn span={6}>
@@ -734,12 +724,11 @@ const Viber = (props) => {
734
724
  onClick={handleClose}
735
725
  className="cancel-msg"
736
726
  type="secondary"
737
- >
727
+ >
738
728
  <FormattedMessage {...messages.cancelButtonLabel} />
739
729
  </CapButton>
740
730
  </ViberFooter>
741
731
  </CapSpin>
742
-
743
732
  </>
744
733
  );
745
734
  };
@@ -755,10 +744,9 @@ const mapDispatchToProps = (dispatch) => ({
755
744
  actions: bindActionCreators(viberActions, dispatch),
756
745
  });
757
746
 
758
-
759
747
  export default withCreatives({
760
748
  WrappedComponent: injectIntl(Viber),
761
749
  mapStateToProps,
762
750
  mapDispatchToProps,
763
751
  userAuth: true,
764
- });
752
+ });