@capillarytech/creatives-library 6.11.6 → 6.11.8

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 (69) hide show
  1. package/assets/rich-video-placeholder.svg +20 -0
  2. package/components/TemplatePreview/_templatePreview.scss +14 -0
  3. package/components/TemplatePreview/index.js +83 -3
  4. package/components/TemplatePreview/messages.js +8 -0
  5. package/index.js +0 -5
  6. package/package.json +3 -3
  7. package/services/getSchema.js +0 -3
  8. package/v2Components/BeeEditor/index.js +263 -0
  9. package/v2Components/BeeEditor/index.scss +11 -0
  10. package/v2Components/BeeEditor/messages.js +71 -0
  11. package/v2Components/BeeEditor/tests/index.test.js +10 -0
  12. package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/_wechatRichmediaTemplatePrev.scss +151 -151
  13. package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/messages.js +33 -33
  14. package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/tests/index.test.js +10 -10
  15. package/v2Components/TemplatePreview/_templatePreview.scss +14 -0
  16. package/v2Components/TemplatePreview/assets/images/androidPushMessage.svg +44 -44
  17. package/v2Components/TemplatePreview/assets/images/home-screen-android.svg +21 -21
  18. package/v2Components/TemplatePreview/assets/images/home-screen-ios.svg +16 -16
  19. package/v2Components/TemplatePreview/assets/images/iPhonePushMessage.svg +134 -134
  20. package/v2Components/TemplatePreview/assets/images/mobile.svg +23 -23
  21. package/v2Components/TemplatePreview/assets/images/sms_mobile_android.svg +22 -22
  22. package/v2Components/TemplatePreview/assets/images/user-icon.svg +18 -18
  23. package/v2Components/TemplatePreview/assets/images/wechat-home-screen-android.svg +21 -21
  24. package/v2Components/TemplatePreview/assets/images/wechat-mobile.svg +77 -77
  25. package/v2Components/TemplatePreview/assets/images/wechat_mobile_android.svg +20 -20
  26. package/v2Components/TemplatePreview/index.js +81 -2
  27. package/v2Components/TemplatePreview/messages.js +8 -0
  28. package/v2Components/TemplatePreview/tests/index.test.js +10 -10
  29. package/v2Containers/CreativesContainer/SlideBoxContent.js +11 -0
  30. package/v2Containers/CreativesContainer/actions.js +27 -27
  31. package/v2Containers/CreativesContainer/constants.js +17 -17
  32. package/v2Containers/CreativesContainer/index.scss +44 -44
  33. package/v2Containers/CreativesContainer/messages.js +305 -305
  34. package/v2Containers/CreativesContainer/reducer.js +29 -29
  35. package/v2Containers/CreativesContainer/sagas.js +11 -11
  36. package/v2Containers/CreativesContainer/selectors.js +30 -30
  37. package/v2Containers/CreativesContainer/tests/actions.test.js +18 -18
  38. package/v2Containers/CreativesContainer/tests/index.test.js +10 -10
  39. package/v2Containers/CreativesContainer/tests/reducer.test.js +9 -9
  40. package/v2Containers/CreativesContainer/tests/sagas.test.js +15 -15
  41. package/v2Containers/CreativesContainer/tests/selectors.test.js +10 -10
  42. package/v2Containers/Line/Container/ImageMap/index.js +2 -1
  43. package/v2Containers/Line/Container/Video/constants.js +10 -0
  44. package/v2Containers/Line/Container/Video/index.js +768 -0
  45. package/v2Containers/Line/Container/Video/messages.js +142 -0
  46. package/v2Containers/Line/Container/Video/style.js +61 -0
  47. package/v2Containers/Line/Container/Wrapper/index.js +2 -0
  48. package/v2Containers/Line/Container/Wrapper/messages.js +4 -0
  49. package/v2Containers/Line/Container/Wrapper/utils.js +8 -3
  50. package/v2Containers/Line/Container/constants.js +2 -0
  51. package/v2Containers/Line/Container/index.js +109 -2
  52. package/v2Containers/Line/Container/messages.js +4 -0
  53. package/v2Containers/Templates/index.js +15 -1
  54. package/v2Containers/Templates/messages.js +4 -0
  55. package/v2Containers/Templates/tests/actions.test.js +18 -18
  56. package/v2Containers/Templates/tests/index.test.js +10 -10
  57. package/v2Containers/Templates/tests/reducer.test.js +9 -9
  58. package/v2Containers/Templates/tests/sagas.test.js +15 -15
  59. package/v2Containers/Templates/tests/selectors.test.js +10 -10
  60. package/v2Containers/TemplatesV2/TemplatesV2.style.js +29 -29
  61. package/v2Containers/TemplatesV2/actions.js +16 -16
  62. package/v2Containers/TemplatesV2/constants.js +10 -10
  63. package/v2Containers/TemplatesV2/messages.js +61 -61
  64. package/v2Containers/TemplatesV2/selectors.js +25 -25
  65. package/v2Containers/TemplatesV2/tests/actions.test.js +18 -18
  66. package/v2Containers/TemplatesV2/tests/index.test.js +10 -10
  67. package/v2Containers/TemplatesV2/tests/reducer.test.js +9 -9
  68. package/v2Containers/TemplatesV2/tests/sagas.test.js +15 -15
  69. package/v2Containers/TemplatesV2/tests/selectors.test.js +10 -10
@@ -0,0 +1,768 @@
1
+ import React, { Fragment, useState, useEffect, useRef, useCallback } from 'react';
2
+ import { injectIntl, FormattedMessage } from 'react-intl';
3
+ import get from 'lodash/get';
4
+ import moment from 'moment';
5
+ import CapInput from '@capillarytech/cap-ui-library/CapInput';
6
+ import CapUploader from '@capillarytech/cap-ui-library/CapUploader';
7
+ import CapHeading from '@capillarytech/cap-ui-library/CapHeading';
8
+ import CapButton from '@capillarytech/cap-ui-library/CapButton';
9
+ import CapDrawer from '@capillarytech/cap-ui-library/CapDrawer';
10
+ import CapHeader from '@capillarytech/cap-ui-library/CapHeader';
11
+ import CapError from '@capillarytech/cap-ui-library/CapError';
12
+ import CapRadioGroup from '@capillarytech/cap-ui-library/CapRadioGroup';
13
+ import { isUrl } from '../Wrapper/utils';
14
+ import LineDrawer from '../Drawer';
15
+ import { CAP_SPACE_12, CAP_SPACE_08, FONT_COLOR_05, CAP_SPACE_24, CAP_SPACE_04 } from '@capillarytech/cap-ui-library/styled/variables';
16
+ import style from './style';
17
+ import { CAP_G06, CAP_G09 } from '@capillarytech/cap-ui-library/styled/variables';
18
+ import withStyles from '../../../../hoc/withStyles';
19
+
20
+ import messages from './messages';
21
+ import {
22
+ ALLOWED_EXTENSIONS_REGEX,
23
+ LINE_VIDEO_SIZE,
24
+ MAX_ALLOWED_TITLE_LENGTH,
25
+ HIDE_ACTION_BUTTON,
26
+ DISPLAY_ACTION_BUTTON,
27
+ MAX_ACTION_LABEL_LENGTH,
28
+ } from './constants';
29
+
30
+ export const LineVideo = ({
31
+ className,
32
+ id,
33
+ intl: { formatMessage },
34
+ isFullMode,
35
+ inheritedTitleStyle,
36
+ supportedExtensions,
37
+ actions = {},
38
+ Line,
39
+ index,
40
+ updateMessageState,
41
+ content,
42
+ activeKey,
43
+ Templates,
44
+ getAllTemplates,
45
+ uploadedAssetList,
46
+ updateUploadedAssetList,
47
+ deleteUploadedImgList,
48
+ }) => {
49
+
50
+ if (activeKey !== 'video') {
51
+ return null;
52
+ }
53
+
54
+ const videoEl = useRef(null);
55
+
56
+ const [errorMessageTitle, updateErrorMessageTitle] = useState(false);
57
+ const [isCreateNew, updateCreateNew] = useState(isFullMode);
58
+ const [messageTitle, updateTextMessageTitle] = useState('');
59
+ const [isTemplateDrawerRequired, updateTemplateDrawerRequirement] = useState(false);
60
+ const [selectedTemplate, updateSelectedTemplate] = useState();
61
+
62
+ const [videoSrc, updateVideoSrc] = useState('');
63
+ const [videoName, updateVideoName] = useState('');
64
+ const [isVideo, updateVideoStatus] = useState(false);
65
+ const [isVideoError, updateVideoErrorMessage] = useState(false);
66
+ const [imagePreview, updateImagePreview] = useState();
67
+ const [altText, updateTitle] = useState('');
68
+ const [errorTitle, updateErrorTitle] = useState(false);
69
+ const [selectedAction, updateSelectedAction] = useState(HIDE_ACTION_BUTTON);
70
+ const [actionLabel, updateActionLabel] = useState('');
71
+ const [actionLabelErrorMessage, updateActionLabelErrorMessage] = useState(false);
72
+ const [actionUrl, updateActionUrl] = useState('');
73
+ const [actionUrlErrorMessage, updateActionUrlErrorMessage] = useState(false);
74
+ const [videoDuration, updateVideoDuration] = useState('');
75
+ const [videoHeight, updateVideoHeight] = useState();
76
+ const [videoWidth, updateVideoWidth] = useState();
77
+
78
+
79
+ useEffect(() => {
80
+ const {
81
+ messageTitle = '',
82
+ type,
83
+ actionLabel,
84
+ actionUrl,
85
+ previewImageUrl: rootPreviewImageUrl,
86
+ video: {
87
+ originalContentUrl = '',
88
+ previewImageUrl = '',
89
+ externalLink: {
90
+ label = '',
91
+ linkUri = '',
92
+ } = {},
93
+ area: {
94
+ height,
95
+ width,
96
+ } = {},
97
+ } = {},
98
+ videoName = '',
99
+ videoDuration = '',
100
+ altText,
101
+ videoSrc,
102
+ videoHeight,
103
+ videoWidth,
104
+ selectedAction,
105
+ } = content;
106
+ const videoUrl = originalContentUrl || videoSrc;
107
+ const videoActionLabel = label || actionLabel;
108
+ if (videoUrl && type === 'video') {
109
+ updateVideoStatus(true);
110
+ updateCreateNew(true);
111
+ updateVideoSrc(videoUrl);
112
+ updateTextMessageTitle(messageTitle);
113
+ updateImagePreview(previewImageUrl || rootPreviewImageUrl);
114
+ updateVideoName(videoName);
115
+ updateVideoWidth(width || videoWidth);
116
+ updateVideoHeight(height || videoHeight);
117
+ updateVideoDuration(videoDuration);
118
+ updateActionUrl(linkUri || actionUrl);
119
+ updateActionLabel(videoActionLabel);
120
+ updateSelectedAction(selectedAction || (!!videoActionLabel ? DISPLAY_ACTION_BUTTON : HIDE_ACTION_BUTTON));
121
+ updateTitle(altText);
122
+ }
123
+ }, [content]);
124
+
125
+ useEffect(() => {
126
+ if (videoSrc && (isFullMode ? messageTitle : true) && imagePreview) {
127
+ updateMessageState({
128
+ isError: !videoSrc || !imagePreview || !altText || !checkAction() || !(isFullMode ? messageTitle : true),
129
+ videoSrc,
130
+ previewImageUrl: imagePreview,
131
+ videoName,
132
+ messageTitle,
133
+ altText,
134
+ index,
135
+ type: 'video',
136
+ actionLabel,
137
+ actionUrl,
138
+ videoHeight,
139
+ videoWidth,
140
+ videoDuration,
141
+ selectedAction,
142
+ messageType: 'videoSrc',
143
+ });
144
+ }
145
+ }, [errorMessageTitle, videoSrc, messageTitle, isVideoError]);
146
+
147
+ useEffect(() => {
148
+ if (Line[`uploadedAssetDataVideo_${index}`] && Object.keys(Line[`uploadedAssetDataVideo_${index}`]).length) {
149
+ const videoSrc = get(Line, `uploadedAssetDataVideo_${index}.metaInfo.secure_file_path`, '');
150
+ const imgPreview = get(Line, `uploadedAssetDataVideo_${index}.metaInfo.video_file_path_preview`, '');
151
+ const videoName = get(Line, `uploadedAssetDataVideo_${index}.metaInfo.name`, '');
152
+ actions.clearAsset(`Video_${index}`);
153
+ if (videoSrc) {
154
+ updateUploadedAssetList({
155
+ ...uploadedAssetList,
156
+ [index]: {
157
+ imgPreview,
158
+ videoSrc,
159
+ videoName,
160
+ },
161
+ });
162
+ }
163
+ }
164
+ }, [Line[`uploadedAssetDataVideo_${index}`]]);
165
+
166
+ useEffect(() => {
167
+ const videoSrc = get(uploadedAssetList[index], 'videoSrc', '');
168
+ const imgPreview = get(uploadedAssetList[index], 'imgPreview', '');
169
+ const videoName = get(uploadedAssetList[index], 'videoName', '');
170
+ const { type } = content;
171
+
172
+ if (videoSrc && type === 'video') {
173
+ updateVideoSrc(videoSrc);
174
+ updateVideoName(videoName);
175
+ updateVideoStatus(true);
176
+ updateImagePreview(imgPreview);
177
+
178
+ updateMessageState({
179
+ isError: !videoSrc || !imagePreview || !altText || !checkAction() || !(isFullMode ? messageTitle : true),
180
+ videoSrc,
181
+ previewImageUrl: imagePreview,
182
+ videoName,
183
+ messageTitle,
184
+ altText,
185
+ index,
186
+ type: 'video',
187
+ actionLabel,
188
+ actionUrl,
189
+ videoHeight,
190
+ videoWidth,
191
+ videoDuration,
192
+ selectedAction,
193
+ messageType: 'videoSrc',
194
+ });
195
+ }
196
+ }, [uploadedAssetList]);
197
+
198
+ const updateMetadataLoaded = () => {
199
+ const { current: { duration, videoHeight, videoWidth } = {} } = videoEl;
200
+ if (duration) {
201
+ const value = moment('1900-01-01 00:00:00').add(duration, 'seconds').format("HH.mm.ss");
202
+ updateVideoDuration(value);
203
+ updateVideoHeight(videoHeight);
204
+ updateVideoWidth(videoWidth);
205
+ updateMessageState({
206
+ isError: !videoSrc || !imagePreview || !altText || !checkAction() || !(isFullMode ? messageTitle : true),
207
+ videoSrc,
208
+ previewImageUrl: imagePreview,
209
+ videoName,
210
+ messageTitle,
211
+ altText,
212
+ index,
213
+ type: 'video',
214
+ actionLabel,
215
+ actionUrl,
216
+ videoHeight,
217
+ videoWidth,
218
+ videoDuration: value,
219
+ selectedAction,
220
+ messageType: 'videoSrc',
221
+ });
222
+ }
223
+ }
224
+
225
+ const checkAction = useCallback((label = actionLabel, url = actionUrl, type = selectedAction) => {
226
+ return type === DISPLAY_ACTION_BUTTON ? (url && label && !updateActionLabelError(label) && !updateActionUrlError(url)) : true;
227
+ }, [actionLabel, actionUrl, selectedAction]);
228
+
229
+ const submitVideoAction = useCallback((data, incorrectFile) => {
230
+ const {
231
+ file: {
232
+ size,
233
+ },
234
+ file,
235
+ fileParams,
236
+ type,
237
+ } = data;
238
+ if (incorrectFile || size > LINE_VIDEO_SIZE) {
239
+ updateVideoErrorMessage(formatMessage(messages.lineVideoIncorrectSize));
240
+ } else {
241
+ updateVideoErrorMessage('');
242
+ actions.uploadAsset(
243
+ file,
244
+ type,
245
+ fileParams,
246
+ `Video_${index}`,
247
+ );
248
+ }
249
+ }, []);
250
+
251
+ const uploadVideo = useCallback((e, { files }) => {
252
+ if (e) {
253
+ e.preventDefault();
254
+ }
255
+ const _URL = window.URL || window.webkitURL;
256
+ let incorrectFile = false;
257
+ const file = files[0];
258
+ if (!ALLOWED_EXTENSIONS_REGEX.test(file.name)) {
259
+ incorrectFile = true;
260
+ }
261
+ const video = new FileReader();
262
+ video.src = _URL.createObjectURL(file);
263
+ const fileParams = {
264
+ width: video.width,
265
+ height: video.height,
266
+ error: false,
267
+ isGenerateVideoThumbnail: true,
268
+ };
269
+ submitVideoAction({ file, type: 'video', fileParams }, incorrectFile);
270
+ if (e) {
271
+ const event = e;
272
+ event.target.value = null;
273
+ }
274
+ }, []);
275
+
276
+ const capUploaderCustomVideoRequest = useCallback((uploadData) => {
277
+ uploadVideo(undefined, { files: [uploadData.file] });
278
+ }, []);
279
+
280
+ const onTextTitleChange = ({ target: { value } }) => {
281
+ updateTextMessageTitle(value);
282
+ let errorMessage = false;
283
+ if (value === '') {
284
+ errorMessage = formatMessage(messages.emptyTitleErrorMessage);
285
+ }
286
+ updateErrorMessageTitle(errorMessage);
287
+ updateMessageState({
288
+ isError: !videoSrc || !imagePreview || !altText || !checkAction() || !(isFullMode ? value : true),
289
+ videoSrc,
290
+ previewImageUrl: imagePreview,
291
+ videoName,
292
+ messageTitle: value,
293
+ altText,
294
+ index,
295
+ type: 'video',
296
+ actionLabel,
297
+ actionUrl,
298
+ videoHeight,
299
+ videoWidth,
300
+ videoDuration,
301
+ selectedAction,
302
+ messageType: 'videoSrc',
303
+ });
304
+ }
305
+
306
+ const onReUpload = () => {
307
+ updateVideoStatus(false);
308
+ if (!isFullMode) {
309
+ updateCreateNew(false);
310
+ }
311
+ deleteUploadedImgList(index);
312
+ updateVideoSrc('');
313
+ updateImagePreview('');
314
+ updateMessageState({
315
+ isError: true,
316
+ videoSrc: '',
317
+ previewImageUrl: '',
318
+ videoName: '',
319
+ messageTitle,
320
+ altText,
321
+ index,
322
+ type: 'video',
323
+ actionLabel,
324
+ actionUrl,
325
+ videoHeight,
326
+ videoWidth,
327
+ videoDuration,
328
+ selectedAction,
329
+ messageType: 'videoSrc',
330
+ });
331
+ }
332
+
333
+ const onSelectTemplate = useCallback((event) => {
334
+ event.stopPropagation();
335
+ updateTemplateDrawerRequirement(true);
336
+ }, [])
337
+
338
+ const getVideoSection = () => {
339
+ if (!isVideo) {
340
+ return (
341
+ (
342
+ <>
343
+ <CapHeading type="h4" style={{ marginBotton: 20, color: 'unset' }}>
344
+ <FormattedMessage {...messages.uploadVideoLabel} />
345
+ </CapHeading>
346
+ <CapUploader.CapDragger
347
+ customRequest={(data) => capUploaderCustomVideoRequest(data)}
348
+ className="form-builder-dragger"
349
+ >
350
+ <CapHeading className="dragger-title" type="h7">
351
+ <FormattedMessage {...messages.dragAndDrop} />
352
+ </CapHeading>
353
+ <CapHeading className="dragger-or" type="label6">
354
+ <FormattedMessage {...messages.or} />
355
+ </CapHeading>
356
+ <CapButton className="dragger-button" type="secondary" style={{ marginRight: CAP_SPACE_08 }}>
357
+ <FormattedMessage {...messages.uploadComputer} />
358
+ </CapButton>
359
+ </CapUploader.CapDragger>
360
+ <CapError type="error" style={{ marginTop: CAP_SPACE_04 }}>
361
+ {isVideoError}
362
+ </CapError>
363
+ <CapHeading type="h6" style={{ marginTop: CAP_SPACE_12 }} className="video-description">
364
+ <FormattedMessage {...messages.videoFormatDescription} />
365
+ <FormattedMessage {...messages.videoSizeDescription} />
366
+ </CapHeading>
367
+ </>
368
+ )
369
+ );
370
+ }
371
+ return (
372
+ <Fragment key={videoSrc}>
373
+ <div style={{ overflow: 'hidden' }}>
374
+ <CapButton
375
+ className="dragger-button"
376
+ type="flat"
377
+ style={{
378
+ float: 'right',
379
+ color: FONT_COLOR_05,
380
+ padding: 0,
381
+ }}
382
+ onClick={onReUpload}
383
+ >
384
+ <FormattedMessage {...messages.imageReUpload} />
385
+ </CapButton>
386
+ </div>
387
+ <div style={{ display: 'flex' }}>
388
+ <video
389
+ width="230"
390
+ poster={imagePreview}
391
+ className="line-image-src"
392
+ onLoadedMetadata={() => updateMetadataLoaded(true)}
393
+ onMouseOver={e => e.target.play()}
394
+ onMouseOut={e => e.target.pause()}
395
+ ref={videoEl}
396
+ >
397
+ <source src={videoSrc} type="video/mp4" />
398
+ </video>
399
+ <div style={{ marginLeft: CAP_SPACE_24 }}>
400
+ <CapHeading type="h6">
401
+ {videoName}
402
+ </CapHeading>
403
+ <CapHeading type="h6">
404
+ {videoDuration}
405
+ </CapHeading>
406
+ </div>
407
+ </div>
408
+ </Fragment>
409
+ );
410
+ }
411
+
412
+ const onTitleChange = ({ target: { value } }) => {
413
+ updateTitle(value);
414
+ let errorMessage;
415
+ if (value === '') {
416
+ errorMessage = formatMessage(messages.emptyAltTextErrorMessage);
417
+ }
418
+ updateErrorTitle(errorMessage);
419
+ updateMessageState({
420
+ isError: !videoSrc || !imagePreview || !value || !checkAction() || !(isFullMode ? messageTitle : true),
421
+ videoSrc,
422
+ previewImageUrl: imagePreview,
423
+ videoName,
424
+ messageTitle,
425
+ altText: value,
426
+ index,
427
+ type: 'video',
428
+ actionLabel,
429
+ actionUrl,
430
+ videoHeight,
431
+ videoWidth,
432
+ videoDuration,
433
+ selectedAction,
434
+ messageType: 'videoSrc',
435
+ });
436
+ }
437
+
438
+ const onChangeSelectedAction = () => {
439
+ event.stopPropagation();
440
+ const { target: { value } } = event;
441
+ updateSelectedAction(value);
442
+ updateMessageState({
443
+ isError: !videoSrc || !imagePreview || !altText || !checkAction(undefined, undefined, value) || !(isFullMode ? messageTitle : true),
444
+ videoSrc,
445
+ previewImageUrl: imagePreview,
446
+ videoName,
447
+ messageTitle,
448
+ altText,
449
+ index,
450
+ type: 'video',
451
+ actionLabel: value === HIDE_ACTION_BUTTON ? '' : actionLabel,
452
+ actionUrl: value === HIDE_ACTION_BUTTON ? '' : actionUrl,
453
+ videoHeight,
454
+ videoWidth,
455
+ videoDuration,
456
+ selectedAction: value,
457
+ messageType: 'videoSrc',
458
+ });
459
+ }
460
+
461
+ const updateActionLabelError = (value = '') => {
462
+ if (value.length > MAX_ACTION_LABEL_LENGTH) {
463
+ updateActionLabelErrorMessage(formatMessage(messages.maxActionLabelErrorMessage));
464
+ return formatMessage(messages.maxActionLabelErrorMessage);
465
+ } else if (value === '') {
466
+ updateActionLabelErrorMessage(formatMessage(messages.emptyLabelErrorMessage));
467
+ return formatMessage(messages.emptyLabelErrorMessage);
468
+ } else {
469
+ updateActionLabelErrorMessage();
470
+ }
471
+ }
472
+
473
+ const updateActionUrlError = (value) => {
474
+ if (value === '') {
475
+ updateActionUrlErrorMessage(formatMessage(messages.emptyUrlErrorMessage));
476
+ return formatMessage(messages.emptyUrlErrorMessage);
477
+ } else if (!isUrl(value)) {
478
+ updateActionUrlErrorMessage(formatMessage(messages.inValidUrlErrorMessage));
479
+ return formatMessage(messages.inValidUrlErrorMessage);
480
+ } else {
481
+ updateActionUrlErrorMessage();
482
+ }
483
+ }
484
+
485
+ const onActionLabelChange = ({ target: { value } }) => {
486
+ updateActionLabel(value);
487
+ updateActionLabelError(value);
488
+ updateMessageState({
489
+ isError: !videoSrc || !imagePreview || !altText || !checkAction(value) || !(isFullMode ? messageTitle : true),
490
+ videoSrc,
491
+ previewImageUrl: imagePreview,
492
+ videoName,
493
+ messageTitle,
494
+ altText,
495
+ index,
496
+ type: 'video',
497
+ actionLabel: value,
498
+ actionUrl,
499
+ videoHeight,
500
+ videoWidth,
501
+ videoDuration,
502
+ selectedAction,
503
+ messageType: 'videoSrc',
504
+ });
505
+ }
506
+
507
+ const onActionUrlChange = ({ target: { value } }) => {
508
+ updateActionUrl(value);
509
+ updateActionUrlError(value);
510
+ updateMessageState({
511
+ isError: !videoSrc || !imagePreview || !altText || !checkAction(undefined, value) || !(isFullMode ? messageTitle : true),
512
+ videoSrc,
513
+ previewImageUrl: imagePreview,
514
+ videoName,
515
+ messageTitle,
516
+ altText,
517
+ index,
518
+ type: 'video',
519
+ actionLabel,
520
+ actionUrl: value,
521
+ videoHeight,
522
+ videoWidth,
523
+ videoDuration,
524
+ selectedAction,
525
+ messageType: 'videoSrc',
526
+ });
527
+ }
528
+
529
+ const getActionSection = () => {
530
+ return (
531
+ <>
532
+ <CapHeading type="h6" style={{ marginTop: CAP_SPACE_12 }}>
533
+ <FormattedMessage {...messages.actionButtonLabel} />
534
+ </CapHeading>
535
+ <CapRadioGroup
536
+ name="actionButton"
537
+ defaultValue={HIDE_ACTION_BUTTON}
538
+ onChange={onChangeSelectedAction}
539
+ value={selectedAction}
540
+ options={[
541
+ {
542
+ label: 'Hide',
543
+ value: HIDE_ACTION_BUTTON
544
+ },
545
+ {
546
+ label: 'Display',
547
+ value: DISPLAY_ACTION_BUTTON
548
+ }
549
+ ]}
550
+ />
551
+ {
552
+ selectedAction === DISPLAY_ACTION_BUTTON
553
+ ? (
554
+ <>
555
+ <CapInput
556
+ onChange={onActionUrlChange}
557
+ placeholder={formatMessage(messages.actionUrlPlaceholder)}
558
+ value={actionUrl}
559
+ errorMessage={actionUrlErrorMessage}
560
+ label={formatMessage(messages.actionUrlTitle)}
561
+ className="action-url-section"
562
+ />
563
+ <CapInput
564
+ onChange={onActionLabelChange}
565
+ placeholder={formatMessage(messages.actionLabelPlaceholder)}
566
+ value={actionLabel}
567
+ errorMessage={actionLabelErrorMessage}
568
+ label={formatMessage(messages.actionLabelTitle)}
569
+ inductiveText={formatMessage(messages.actionLabelInductiveTitle)}
570
+ addonAfter={<span>{(actionLabel || '').length} / ({MAX_ACTION_LABEL_LENGTH})</span>}
571
+ className="action-label-section"
572
+ />
573
+ </>
574
+ )
575
+ : null
576
+ }
577
+ </>
578
+ )
579
+ }
580
+
581
+ const getLineVideoSection = () => {
582
+ if (!isCreateNew) {
583
+ return (
584
+ <div className="form-builder-dragger" style={{
585
+ textAlign: 'center',
586
+ border: `1px dashed ${CAP_G06}`,
587
+ minHeight: 120,
588
+ padding: 60
589
+ }}>
590
+ <CapHeader
591
+ className="choice-title"
592
+ size="regular"
593
+ title={formatMessage(messages.textMessageAddLabel)}
594
+ style={{ marginBottom: 12 }}
595
+ />
596
+
597
+ <CapButton
598
+ className="dragger-button create-button"
599
+ type="secondary"
600
+ style={{ marginRight: CAP_SPACE_08 }}
601
+ onClick={setNewContent}
602
+ isAddBtn
603
+ >
604
+ <FormattedMessage {...messages.textMessageCreateNew} />
605
+ </CapButton>
606
+
607
+ <CapHeading className="dragger-or" type="label6" style={{ display: 'inline-block' }}>
608
+ <FormattedMessage {...messages.textMessageORLabel} />
609
+ </CapHeading>
610
+
611
+ <CapButton
612
+ className="dragger-button select-template-button"
613
+ type="secondary"
614
+ style={{ marginLeft: CAP_SPACE_08 }}
615
+ onClick={onSelectTemplate}
616
+ >
617
+ <FormattedMessage {...messages.textMessageSelectTemplate} />
618
+ </CapButton>
619
+ </div>);
620
+ } else {
621
+ return (
622
+ <>
623
+ <CapInput.TextArea
624
+ maxLength={MAX_ALLOWED_TITLE_LENGTH}
625
+ label={<FormattedMessage {...messages.titleLabel} />}
626
+ inductiveText={<FormattedMessage {...messages.titleDescription} />}
627
+ onChange={onTitleChange}
628
+ value={altText}
629
+ errorMessage={errorTitle}
630
+ className="title-textarea"
631
+ />
632
+ {getVideoSection()}
633
+ {getActionSection()}
634
+ </>
635
+ );
636
+ }
637
+ }
638
+
639
+ const setNewContent = useCallback(() => updateCreateNew(true), []);
640
+
641
+ const onTemplateSelection = (template) => {
642
+ const {
643
+ video: {
644
+ originalContentUrl = '',
645
+ previewImageUrl = '',
646
+ externalLink: {
647
+ label = '',
648
+ linkUri = '',
649
+ } = {},
650
+ area: {
651
+ height,
652
+ width,
653
+ } = {},
654
+ } = {},
655
+ videoName = '',
656
+ videoDuration = '',
657
+ altText,
658
+ } = get(template, 'versions.base.content.messages[0]', {});
659
+
660
+ updateSelectedTemplate(template);
661
+ updateVideoStatus(true);
662
+ updateTemplateDrawerRequirement(false);
663
+ updateCreateNew(true);
664
+ updateVideoSrc(originalContentUrl);
665
+ updateTextMessageTitle(messageTitle);
666
+ updateImagePreview(previewImageUrl);
667
+ updateVideoName(videoName);
668
+ updateVideoWidth(width);
669
+ updateVideoHeight(height);
670
+ updateVideoDuration(videoDuration);
671
+ updateActionUrl(linkUri);
672
+ updateActionLabel(label);
673
+ updateSelectedAction(!!label ? DISPLAY_ACTION_BUTTON : HIDE_ACTION_BUTTON);
674
+ updateTitle(altText);
675
+ }
676
+
677
+ const getLineVideoDrawerContent = () => {
678
+ const lineTextTemplates = Templates.templates;
679
+ if (!lineTextTemplates) {
680
+ return null;
681
+ }
682
+
683
+ const cardDataList = [];
684
+ lineTextTemplates.forEach(template => {
685
+ let templateData = {};
686
+ const {
687
+ content: {
688
+ messages: [{
689
+ video: {
690
+ originalContentUrl = '',
691
+ } = {},
692
+ }] = [{}],
693
+ } = {},
694
+ } = template.versions.base;
695
+ templateData.content = (
696
+ <video height="279">
697
+ <source src={originalContentUrl} type="video/mp4" />
698
+ </video>
699
+ );
700
+ templateData.title = template.name;
701
+ templateData.key = template.name;
702
+ templateData.hoverOption = (
703
+ <CapButton onClick={() => onTemplateSelection(template)}>
704
+ <FormattedMessage {...messages.select} />
705
+ </CapButton>
706
+ );
707
+ if (originalContentUrl) {
708
+ cardDataList.push(templateData);
709
+ }
710
+ });
711
+ return (
712
+ <>
713
+ <CapHeading type="h3" className="drawer-head">
714
+ {formatMessage(messages.lineTemplateImage)}
715
+ </CapHeading>
716
+ <LineDrawer
717
+ getAllTemplates={getAllTemplates}
718
+ cardDataList={cardDataList}
719
+ isDrawer={isTemplateDrawerRequired}
720
+ Templates={Templates}
721
+ searchPlaceholder={formatMessage(messages.searchImages)}
722
+ />
723
+ </>
724
+ );
725
+ };
726
+
727
+ return (
728
+ <div className={className}>
729
+ {
730
+ isFullMode
731
+ ? (
732
+ <CapInput
733
+ id={`${id}_input`}
734
+ onChange={onTextTitleChange}
735
+ errorMessage={errorMessageTitle}
736
+ className="image-template-title"
737
+ style={inheritedTitleStyle || {}}
738
+ placeholder={formatMessage(messages.textMessageTitlePlaceholder)}
739
+ defaultValue={messageTitle || ''}
740
+ value={messageTitle || ''}
741
+ size="default"
742
+ label={formatMessage(messages.textMessageTitleLabel)}
743
+ />
744
+ )
745
+ : null
746
+ }
747
+ <form encType="multipart/form-data" id={`${id}_form`}>
748
+ <input
749
+ key={`${id}_videoFile`}
750
+ style={{ display: 'none' }}
751
+ id="fileName"
752
+ type="file"
753
+ onChange={(e) => uploadVideo(e, { files: e.target.files })}
754
+ accept={supportedExtensions ? supportedExtensions : "video/*"}
755
+ />
756
+ {getLineVideoSection()}
757
+ <CapDrawer
758
+ content={getLineVideoDrawerContent()}
759
+ visible={isTemplateDrawerRequired}
760
+ width={624}
761
+ onClose={() => updateTemplateDrawerRequirement(false)}
762
+ />
763
+ </form>
764
+ </div>
765
+ )
766
+ }
767
+
768
+ export default injectIntl(withStyles(LineVideo, style));