@capillarytech/creatives-library 3.9.0 → 3.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/TemplatePreview/WechatRichmediaTemplatePreview/index.js +7 -8
- package/components/TemplatePreview/_templatePreview.scss +279 -20
- package/components/TemplatePreview/assets/images/home-screen-android.svg +21 -0
- package/components/TemplatePreview/assets/images/home-screen-ios.svg +16 -0
- package/components/TemplatePreview/assets/images/sms_mobile_android.svg +22 -0
- package/components/TemplatePreview/assets/images/sms_mobile_ios.svg +16 -0
- package/components/TemplatePreview/assets/images/wechat_mobile_android.svg +20 -0
- package/components/TemplatePreview/index.js +180 -20
- package/components/TemplatePreview/messages.js +16 -0
- package/package-lock.json +3096 -0
- package/package.json +1 -1
- package/translations/en.json +5 -0
- package/translations/zh.json +5 -0
- package/v2Components/FormBuilder/index.js +24 -8
- package/v2Components/MobilePushPreviewV2/index.js +40 -32
- package/v2Components/MobilePushPreviewV2/messages.js +0 -8
- package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/_wechatRichmediaTemplatePrev.scss +64 -0
- package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/index.js +101 -19
- package/v2Components/TemplatePreview/WechatRichmediaTemplatePreview/messages.js +12 -0
- package/v2Components/TemplatePreview/_templatePreview.scss +13 -4
- package/v2Components/TemplatePreview/assets/images/home-screen-android.svg +21 -0
- package/v2Components/TemplatePreview/assets/images/home-screen-ios.svg +16 -0
- package/v2Components/TemplatePreview/assets/images/sms_mobile_android.svg +22 -0
- package/v2Components/TemplatePreview/assets/images/wechat-home-screen-android.svg +21 -0
- package/v2Components/TemplatePreview/assets/images/wechat_mobile_android.svg +20 -0
- package/v2Components/TemplatePreview/index.js +147 -20
- package/v2Components/TemplatePreview/messages.js +8 -0
- package/v2Containers/CreativesContainer/SlideBoxContent.js +15 -1
- package/v2Containers/CreativesContainer/SlideBoxHeader.js +1 -1
- package/v2Containers/CreativesContainer/index.js +3 -1
- package/v2Containers/CreativesContainer/messages.js +2 -2
- package/v2Containers/Email/_email.scss +7 -1
- package/v2Containers/Email/index.js +39 -13
- package/v2Containers/Email/messages.js +4 -0
- package/v2Containers/EmailWrapper/index.js +7 -5
- package/v2Containers/MobilePush/Create/index.js +5 -0
- package/v2Containers/MobilePush/Edit/index.js +5 -0
- package/v2Containers/MobilepushWrapper/index.js +4 -1
- package/v2Containers/Sms/Create/index.js +2 -1
- package/v2Containers/Sms/Edit/index.js +2 -0
- package/v2Containers/Templates/index.js +2 -2
package/package.json
CHANGED
package/translations/en.json
CHANGED
|
@@ -1091,6 +1091,9 @@
|
|
|
1091
1091
|
"creatives.containersV2.Line.Create.uploadSuccess": "Photo uploaded successfully",
|
|
1092
1092
|
"creatives.containersV2.Line.Create.uploadingImage": "Uploading image...",
|
|
1093
1093
|
"creatives.containersV2.Line.Create.valueCantEmpty": "value cannot be empty.",
|
|
1094
|
+
"creatives.containersV2.Line.CreateWrapper.accountLineListDescription": "Choose the account to send content",
|
|
1095
|
+
"creatives.containersV2.Line.CreateWrapper.accountLineListTitle": "Line accounts",
|
|
1096
|
+
"creatives.containersV2.Line.CreateWrapper.accountLineNoListTitle": "No line accounts present",
|
|
1094
1097
|
"creatives.containersV2.Line.CreateWrapper.continue": "Continue",
|
|
1095
1098
|
"creatives.containersV2.Line.CreateWrapper.hybridTemplateDescription": "Used to create combined text & image or video content",
|
|
1096
1099
|
"creatives.containersV2.Line.CreateWrapper.hybridTemplateTitle": "Hybrid",
|
|
@@ -1326,6 +1329,7 @@
|
|
|
1326
1329
|
"creatives.containersV2.Templates.imageTemplate": "Image",
|
|
1327
1330
|
"creatives.containersV2.Templates.invalidUploadFileError": "File cannot be uploaded. Please select another file with valid file format.",
|
|
1328
1331
|
"creatives.containersV2.Templates.layoutSelection": "Select layout",
|
|
1332
|
+
"creatives.containersV2.Templates.lineAccount": "Line account",
|
|
1329
1333
|
"creatives.containersV2.Templates.lineHeader": "Line",
|
|
1330
1334
|
"creatives.containersV2.Templates.mapTemplate": "Map template",
|
|
1331
1335
|
"creatives.containersV2.Templates.mapTemplates": "Map templates",
|
|
@@ -1338,6 +1342,7 @@
|
|
|
1338
1342
|
"creatives.containersV2.Templates.newTemplate": "New template",
|
|
1339
1343
|
"creatives.containersV2.Templates.noAccountMessage": "Please select an account to proceed",
|
|
1340
1344
|
"creatives.containersV2.Templates.noAccountsPresent": "Push notifications are not setup for your brand",
|
|
1345
|
+
"creatives.containersV2.Templates.noAccountsPresentLine": "Line accounts are not setup for your brand",
|
|
1341
1346
|
"creatives.containersV2.Templates.noAccountsPresentWeChat": "Wechat accounts are not setup for your brand",
|
|
1342
1347
|
"creatives.containersV2.Templates.noTemplatesFound": "No templates found",
|
|
1343
1348
|
"creatives.containersV2.Templates.noTemplatesMessage": "No templates available",
|
package/translations/zh.json
CHANGED
|
@@ -1091,6 +1091,9 @@
|
|
|
1091
1091
|
"creatives.containersV2.Line.Create.uploadSuccess": "",
|
|
1092
1092
|
"creatives.containersV2.Line.Create.uploadingImage": "",
|
|
1093
1093
|
"creatives.containersV2.Line.Create.valueCantEmpty": "",
|
|
1094
|
+
"creatives.containersV2.Line.CreateWrapper.accountLineListDescription": "",
|
|
1095
|
+
"creatives.containersV2.Line.CreateWrapper.accountLineListTitle": "",
|
|
1096
|
+
"creatives.containersV2.Line.CreateWrapper.accountLineNoListTitle": "",
|
|
1094
1097
|
"creatives.containersV2.Line.CreateWrapper.continue": "",
|
|
1095
1098
|
"creatives.containersV2.Line.CreateWrapper.hybridTemplateDescription": "",
|
|
1096
1099
|
"creatives.containersV2.Line.CreateWrapper.hybridTemplateTitle": "",
|
|
@@ -1326,6 +1329,7 @@
|
|
|
1326
1329
|
"creatives.containersV2.Templates.imageTemplate": "",
|
|
1327
1330
|
"creatives.containersV2.Templates.invalidUploadFileError": "",
|
|
1328
1331
|
"creatives.containersV2.Templates.layoutSelection": "",
|
|
1332
|
+
"creatives.containersV2.Templates.lineAccount": "",
|
|
1329
1333
|
"creatives.containersV2.Templates.lineHeader": "",
|
|
1330
1334
|
"creatives.containersV2.Templates.mapTemplate": "",
|
|
1331
1335
|
"creatives.containersV2.Templates.mapTemplates": "",
|
|
@@ -1338,6 +1342,7 @@
|
|
|
1338
1342
|
"creatives.containersV2.Templates.newTemplate": "",
|
|
1339
1343
|
"creatives.containersV2.Templates.noAccountMessage": "",
|
|
1340
1344
|
"creatives.containersV2.Templates.noAccountsPresent": "",
|
|
1345
|
+
"creatives.containersV2.Templates.noAccountsPresentLine": "",
|
|
1341
1346
|
"creatives.containersV2.Templates.noAccountsPresentWeChat": "",
|
|
1342
1347
|
"creatives.containersV2.Templates.noTemplatesFound": "",
|
|
1343
1348
|
"creatives.containersV2.Templates.noTemplatesMessage": "",
|
|
@@ -11,7 +11,7 @@ import PropTypes from 'prop-types';
|
|
|
11
11
|
import React from 'react';
|
|
12
12
|
import _ from 'lodash';
|
|
13
13
|
import { Tabs, Table, Modal} from 'antd';
|
|
14
|
-
import { CapDrawer, CapButton, CapInput, CapPopover, CapCheckbox, CapRadio, CapSelect, CapTable, CapRow, CapColumn, CapNotification, CapUploader, CapHeading, CapIcon} from '@capillarytech/cap-ui-library';
|
|
14
|
+
import { CapDrawer, CapButton, CapInput, CapPopover, CapImage, CapCheckbox, CapRadio, CapSelect, CapTable, CapRow, CapColumn, CapNotification, CapUploader, CapHeading, CapIcon} from '@capillarytech/cap-ui-library';
|
|
15
15
|
import { injectIntl, intlShape, FormattedMessage } from 'react-intl';
|
|
16
16
|
import LabelHOC from '@capillarytech/cap-ui-library/assets/HOCs/ComponentWithLabelHOC';
|
|
17
17
|
import { CAP_SPACE_12, CAP_SPACE_08, FONT_COLOR_05, FONT_COLOR_04 } from '@capillarytech/cap-ui-library/styled/variables';
|
|
@@ -2197,7 +2197,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2197
2197
|
//
|
|
2198
2198
|
const imgSrc = template && template.versions && template.versions.base ? template.versions.base.preview_http_url : '';
|
|
2199
2199
|
// const ifPreviewGenerated = template && template.versions && template.versions.base ? template.versions.base.isPreviewGenerated : 0;
|
|
2200
|
-
const content = <
|
|
2200
|
+
const content = <CapImage src={imgSrc || ''} alt="" />;
|
|
2201
2201
|
|
|
2202
2202
|
temp.content = (
|
|
2203
2203
|
<div
|
|
@@ -2382,8 +2382,10 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2382
2382
|
content={content}
|
|
2383
2383
|
charCounterEnabled={val.charCounterEnabled}
|
|
2384
2384
|
unicodeEnabled={unicodeEnabled}
|
|
2385
|
-
|
|
2386
|
-
|
|
2385
|
+
showTestAndPreviewIcon
|
|
2386
|
+
onPreviewContentClicked={this.props.onPreviewContentClicked}
|
|
2387
|
+
onTestContentClicked={this.props.onTestContentClicked}
|
|
2388
|
+
/>
|
|
2387
2389
|
</CapColumn>
|
|
2388
2390
|
);
|
|
2389
2391
|
break;
|
|
@@ -2823,7 +2825,7 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2823
2825
|
<div>
|
|
2824
2826
|
<div className={`image-container ${ifError ? 'error' : ''}`}>
|
|
2825
2827
|
{self.state && !!self.state.formData[`${self.state.currentTab - 1}`].image ?
|
|
2826
|
-
<
|
|
2828
|
+
<CapImage src={self.state.formData[`${self.state.currentTab - 1}`].image} alt={val.alt} style={val.style}/>
|
|
2827
2829
|
:
|
|
2828
2830
|
<div style={{width: "100%", textAlign: "center"}}><span className="image-placeholder">{val.placeholder}</span></div>
|
|
2829
2831
|
}
|
|
@@ -2846,9 +2848,10 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2846
2848
|
const ImageComponent = (props) => (
|
|
2847
2849
|
<div key={`${val.id}-${this.state.currentTab}`}>
|
|
2848
2850
|
<div className={`image-container ${props.ifError ? 'error' : ''}`}>
|
|
2851
|
+
|
|
2849
2852
|
{isImage ?
|
|
2850
|
-
<
|
|
2851
|
-
|
|
2853
|
+
<CapImage src={self.state.formData[`${self.state.currentTab - 1}`].image} alt={props.alt} style={props.style}/>
|
|
2854
|
+
:
|
|
2852
2855
|
<div style={{width: "100%", textAlign: "center"}}><span className="image-placeholder">{props.placeholder}</span></div>
|
|
2853
2856
|
}
|
|
2854
2857
|
</div>
|
|
@@ -2906,11 +2909,16 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2906
2909
|
);
|
|
2907
2910
|
break;
|
|
2908
2911
|
case "tag-list":
|
|
2912
|
+
let moduleFilterEnabled = this.props.location && this.props.location.query && this.props.location.query.type !== 'embedded';
|
|
2913
|
+
const channel = _.get(this.props, 'schema.channel', "");
|
|
2914
|
+
if (channel === 'EMAIL') {
|
|
2915
|
+
moduleFilterEnabled = this.props.isFullMode;
|
|
2916
|
+
}
|
|
2909
2917
|
columns.push(
|
|
2910
2918
|
<CapColumn key={`input-${val.id}`} offset={val.offset} span={val.width ? val.width : ''} style={val.style ? val.style : {marginBottom: '16px'}}>
|
|
2911
2919
|
<TagList
|
|
2912
2920
|
key={`input-${val.id}`}
|
|
2913
|
-
moduleFilterEnabled={
|
|
2921
|
+
moduleFilterEnabled={moduleFilterEnabled}
|
|
2914
2922
|
label={val.label ? val.label : ''}
|
|
2915
2923
|
onTagSelect={(data) => this.callChildEvent(data, val, 'onTagSelect')}
|
|
2916
2924
|
onContextChange={this.props.onContextChange}
|
|
@@ -2957,6 +2965,9 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
2957
2965
|
content={content}
|
|
2958
2966
|
charCounterEnabled={val.charCounterEnabled}
|
|
2959
2967
|
unicodeEnabled={unicodeEnabled}
|
|
2968
|
+
showTestAndPreviewIcon
|
|
2969
|
+
onPreviewContentClicked={this.props.onPreviewContentClicked}
|
|
2970
|
+
onTestContentClicked={this.props.onTestContentClicked}
|
|
2960
2971
|
>
|
|
2961
2972
|
</TemplatePreview>
|
|
2962
2973
|
</CapColumn>
|
|
@@ -3006,6 +3017,10 @@ class FormBuilder extends React.Component { // eslint-disable-line react/prefer-
|
|
|
3006
3017
|
],
|
|
3007
3018
|
appName: val.content.appName,
|
|
3008
3019
|
}}
|
|
3020
|
+
showTestAndPreviewIcon
|
|
3021
|
+
onPreviewContentClicked={this.props.onPreviewContentClicked}
|
|
3022
|
+
onTestContentClicked={this.props.onTestContentClicked}
|
|
3023
|
+
templateDataRaw={this.props.templateData}
|
|
3009
3024
|
>
|
|
3010
3025
|
</TemplatePreview>
|
|
3011
3026
|
</CapColumn>
|
|
@@ -3481,6 +3496,7 @@ FormBuilder.propTypes = {
|
|
|
3481
3496
|
selectedOfferDetails: PropTypes.array,
|
|
3482
3497
|
setDrawerVisibility: PropTypes.bool,
|
|
3483
3498
|
capDrawerContent: PropTypes.array,
|
|
3499
|
+
isFullMode: PropTypes.bool,
|
|
3484
3500
|
};
|
|
3485
3501
|
|
|
3486
3502
|
export default injectIntl(FormBuilder);
|
|
@@ -7,16 +7,10 @@
|
|
|
7
7
|
import PropTypes from 'prop-types';
|
|
8
8
|
|
|
9
9
|
import React from 'react';
|
|
10
|
-
import {
|
|
11
|
-
// import styled from 'styled-components';
|
|
12
|
-
|
|
13
|
-
import { FormattedMessage } from 'react-intl';
|
|
14
|
-
import { Button } from 'antd';
|
|
10
|
+
import { CapTab, CapIcon } from '@capillarytech/cap-ui-library';
|
|
15
11
|
import { get, map, isEmpty} from 'lodash';
|
|
16
12
|
import TemplatePreview from '../TemplatePreview';
|
|
17
13
|
import '../PreviewSideBar/_previewsidebar.scss';
|
|
18
|
-
import messages from './messages';
|
|
19
|
-
const ButtonGroup = Button.Group;
|
|
20
14
|
|
|
21
15
|
class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react/prefer-stateless-function
|
|
22
16
|
constructor(props) {
|
|
@@ -24,6 +18,9 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
24
18
|
this.goToEdit = this.goToEdit.bind(this);
|
|
25
19
|
this.goToDuplicate = this.goToDuplicate.bind(this);
|
|
26
20
|
this.changeDevice = this.changeDevice.bind(this);
|
|
21
|
+
this.getPreview = this.getPreview.bind(this);
|
|
22
|
+
this.setContent = this.setContent.bind(this);
|
|
23
|
+
this.goToDuplicate = this.goToDuplicate.bind(this);
|
|
27
24
|
const hasAndroid = get(props, 'templateData.versions.base.ANDROID') || get(props, 'templateData.androidContent');
|
|
28
25
|
const hasIos = get(props, 'templateData.versions.base.IOS') || get(props, 'templateData.iosContent');
|
|
29
26
|
let device = "android";
|
|
@@ -38,7 +35,7 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
38
35
|
};
|
|
39
36
|
}
|
|
40
37
|
|
|
41
|
-
setContent
|
|
38
|
+
setContent(templateData, device) {
|
|
42
39
|
const androidContent = get(templateData, 'versions.base.ANDROID') || get(templateData, 'androidContent');
|
|
43
40
|
const iosContent = get(templateData, 'versions.base.IOS') || get(templateData, 'iosContent');
|
|
44
41
|
|
|
@@ -59,12 +56,21 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
59
56
|
}
|
|
60
57
|
return content;
|
|
61
58
|
}
|
|
59
|
+
getPreview(device) {
|
|
60
|
+
return (
|
|
61
|
+
<TemplatePreview
|
|
62
|
+
device={device}
|
|
63
|
+
channel={this.props.channel}
|
|
64
|
+
content={this.state.content || ''}
|
|
65
|
+
templateData={this.props.templateData}
|
|
66
|
+
/>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
62
69
|
goToDuplicate() {
|
|
63
70
|
this.props.onDuplicateClick(this.props.templateData);
|
|
64
71
|
this.props.handleClose();
|
|
65
72
|
}
|
|
66
|
-
changeDevice(
|
|
67
|
-
const device = ev.target.value;
|
|
73
|
+
changeDevice(device) {
|
|
68
74
|
const content = this.setContent(this.props.templateData, device);
|
|
69
75
|
this.setState({device, content });
|
|
70
76
|
}
|
|
@@ -72,38 +78,40 @@ class MobilePushPreviewV2 extends React.Component { // eslint-disable-line react
|
|
|
72
78
|
this.props.onEditClick(e, this.props.templateData._id, this.props.templateData.modeType, path);
|
|
73
79
|
}
|
|
74
80
|
render() {
|
|
75
|
-
const {templateData
|
|
76
|
-
|
|
81
|
+
const {templateData} = this.props;
|
|
77
82
|
const hasAndroid = get(templateData, 'versions.base.ANDROID') || get(templateData, 'androidContent');
|
|
78
83
|
const hasIos = get(templateData, 'versions.base.IOS') || get(templateData, 'iosContent');
|
|
79
|
-
|
|
80
|
-
const {device, content} = this.state;
|
|
84
|
+
const hasBothAndroidAndIos = hasAndroid && hasIos;
|
|
81
85
|
|
|
82
86
|
return (
|
|
83
|
-
|
|
84
87
|
<div>
|
|
85
88
|
<div className="devices">
|
|
86
|
-
{!isEmpty(templateData) &&
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
89
|
+
{!isEmpty(templateData) &&
|
|
90
|
+
( hasBothAndroidAndIos ? (
|
|
91
|
+
<CapTab
|
|
92
|
+
panes={[
|
|
93
|
+
{
|
|
94
|
+
content: this.getPreview('android'),
|
|
95
|
+
tab: <CapIcon type="android" size="m" />,
|
|
96
|
+
key: 'android',
|
|
97
|
+
},
|
|
98
|
+
{
|
|
99
|
+
content: this.getPreview('iphone'),
|
|
100
|
+
tab: <CapIcon type="ios" size="m" />,
|
|
101
|
+
key: 'iphone',
|
|
102
|
+
},
|
|
103
|
+
]}
|
|
104
|
+
onChange={(activeKey) => this.changeDevice(activeKey)}
|
|
105
|
+
tabBarStyle={{margin: 'auto', width: '38%'}}
|
|
106
|
+
/>
|
|
107
|
+
) : (
|
|
108
|
+
(hasAndroid || hasIos) && this.getPreview(hasAndroid ? 'android' : 'ios')
|
|
109
|
+
))
|
|
110
|
+
}
|
|
91
111
|
</div>
|
|
92
|
-
<TemplatePreview
|
|
93
|
-
device={device === "android" ? "android" : "iphone"}
|
|
94
|
-
channel={channel}
|
|
95
|
-
content={content || ''}
|
|
96
|
-
templateData={templateData}
|
|
97
|
-
>
|
|
98
|
-
</TemplatePreview>
|
|
99
|
-
|
|
100
|
-
|
|
101
112
|
</div>
|
|
102
|
-
|
|
103
|
-
|
|
104
113
|
);
|
|
105
114
|
}
|
|
106
|
-
|
|
107
115
|
}
|
|
108
116
|
|
|
109
117
|
MobilePushPreviewV2.propTypes = {
|
|
@@ -10,12 +10,4 @@ export default defineMessages({
|
|
|
10
10
|
id: 'creatives.componentsv2.MobilePushPreviewV2.header',
|
|
11
11
|
defaultMessage: 'This is the MobilePushPreviewV2 component !',
|
|
12
12
|
},
|
|
13
|
-
android: {
|
|
14
|
-
id: 'creatives.componentsv2.MobilePushPreviewV2.android',
|
|
15
|
-
defaultMessage: 'Android',
|
|
16
|
-
},
|
|
17
|
-
ios: {
|
|
18
|
-
id: 'creatives.componentsv2.MobilePushPreviewV2.ios',
|
|
19
|
-
defaultMessage: 'IOS',
|
|
20
|
-
},
|
|
21
13
|
});
|
|
@@ -1,5 +1,69 @@
|
|
|
1
1
|
@import '~@capillarytech/cap-ui-library/styles/_variables.scss';
|
|
2
2
|
|
|
3
|
+
.shell-lock-screen-android .main-screen-preview .wechatMsgContainer{
|
|
4
|
+
position: absolute;
|
|
5
|
+
left: 53.5%;
|
|
6
|
+
top:28%;
|
|
7
|
+
background: white;
|
|
8
|
+
width: 19.5%;
|
|
9
|
+
text-align: left;
|
|
10
|
+
height: fit-content;
|
|
11
|
+
border-radius: 0.285rem;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.shell-lock-screen-android .lock-screen-preview{
|
|
15
|
+
.wechat-android-sender-id{
|
|
16
|
+
position: absolute;
|
|
17
|
+
top: 46%;
|
|
18
|
+
font-size: 10px;
|
|
19
|
+
left: 28%;
|
|
20
|
+
}
|
|
21
|
+
.wechat-android-title{
|
|
22
|
+
position: absolute;
|
|
23
|
+
top: 49%;
|
|
24
|
+
font-size: 10px;
|
|
25
|
+
left: 28%;
|
|
26
|
+
color: #5e6c84;
|
|
27
|
+
}
|
|
28
|
+
.wechat-android-action-buttons{
|
|
29
|
+
position: absolute;
|
|
30
|
+
left: 28%;
|
|
31
|
+
top: 53%;
|
|
32
|
+
font-size: 10px;
|
|
33
|
+
color: #3861ca;
|
|
34
|
+
font-weight: 500;
|
|
35
|
+
}
|
|
36
|
+
.wechat-ios-sender-id{
|
|
37
|
+
position: absolute;
|
|
38
|
+
top: 44%;
|
|
39
|
+
font-size: 10px;
|
|
40
|
+
left: 28.5%;
|
|
41
|
+
}
|
|
42
|
+
.wechat-ios-title{
|
|
43
|
+
position: absolute;
|
|
44
|
+
top: 47%;
|
|
45
|
+
font-size: 10px;
|
|
46
|
+
left: 28.5%;
|
|
47
|
+
color: #5e6c84;
|
|
48
|
+
}
|
|
49
|
+
.wechat-ios-action-reply{
|
|
50
|
+
position: absolute;
|
|
51
|
+
left: 35%;
|
|
52
|
+
top: 59%;
|
|
53
|
+
font-size: 12px;
|
|
54
|
+
color: #3861ca;
|
|
55
|
+
font-weight: 500;
|
|
56
|
+
}
|
|
57
|
+
.wechat-ios-action-cancel{
|
|
58
|
+
position: absolute;
|
|
59
|
+
left: 34.5%;
|
|
60
|
+
top: 66%;
|
|
61
|
+
font-size: 12px;
|
|
62
|
+
color: #3861ca;
|
|
63
|
+
font-weight: 500;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
3
67
|
.wechatMsgContainer{
|
|
4
68
|
position: absolute;
|
|
5
69
|
left: 30%;
|
|
@@ -7,14 +7,15 @@
|
|
|
7
7
|
import React from 'react';
|
|
8
8
|
import PropTypes from 'prop-types';
|
|
9
9
|
// import { connect } from 'react-redux';
|
|
10
|
-
import { CapRow, CapColumn, CapButton } from '@capillarytech/cap-react-ui-library/';
|
|
11
|
-
import { CapHeading, CapLabel } from '@capillarytech/cap-ui-library/';
|
|
10
|
+
import { CapRow, CapColumn, CapButton, CapImage } from '@capillarytech/cap-react-ui-library/';
|
|
11
|
+
import { CapHeading, CapLabel, CapTab, CapIcon } from '@capillarytech/cap-ui-library/';
|
|
12
12
|
import { FormattedMessage } from 'react-intl';
|
|
13
13
|
import _ from 'lodash';
|
|
14
14
|
import './_wechatRichmediaTemplatePrev.scss';
|
|
15
15
|
import messages from './messages';
|
|
16
|
-
const wechatBody = require('./../assets/images/
|
|
17
|
-
|
|
16
|
+
const wechatBody = require('./../assets/images/wechat_mobile_android.svg');
|
|
17
|
+
const wechatLockScreenAndroid = require('./../assets/images/wechat-home-screen-android.svg');
|
|
18
|
+
const wechatLockScreenIos = require('./../assets/images/home-screen-ios.svg');
|
|
18
19
|
class WechatRichmediaTemplatePreview extends React.PureComponent { // eslint-disable-line react/prefer-stateless-function
|
|
19
20
|
preparePreviewData = (mediaList) => {
|
|
20
21
|
const previewMsg = [];
|
|
@@ -23,7 +24,7 @@ class WechatRichmediaTemplatePreview extends React.PureComponent { // eslint-dis
|
|
|
23
24
|
const contentData = content[0];
|
|
24
25
|
previewMsg.push(
|
|
25
26
|
<div className="richmedia-image-container">
|
|
26
|
-
<
|
|
27
|
+
<CapImage alt="default" width="100%" height="102px" src={contentData.image_url} />
|
|
27
28
|
{mediaListLength !== 1 && (
|
|
28
29
|
<div className="name-container">
|
|
29
30
|
<CapHeading type="h4" style={{color: "white"}}>{contentData.title}</CapHeading>
|
|
@@ -43,7 +44,7 @@ class WechatRichmediaTemplatePreview extends React.PureComponent { // eslint-dis
|
|
|
43
44
|
previewMsg.push(
|
|
44
45
|
<div className="additional-richmedia-container">
|
|
45
46
|
<div><CapLabel type="label9" style={{width: '170px', top: '12px', position: 'relative'}}>{data.title}</CapLabel></div>
|
|
46
|
-
<
|
|
47
|
+
<CapImage alt="default" width="34px" height="34px" src={data.image_url} />
|
|
47
48
|
</div>
|
|
48
49
|
);
|
|
49
50
|
});
|
|
@@ -61,7 +62,7 @@ class WechatRichmediaTemplatePreview extends React.PureComponent { // eslint-dis
|
|
|
61
62
|
returnObj.push(
|
|
62
63
|
<div style={{ width: "100%", height: 116, position: "relative" }}>
|
|
63
64
|
<CapRow>
|
|
64
|
-
<
|
|
65
|
+
<CapImage alt="default" width="100%" height="110px" src={contentData.image_url} />
|
|
65
66
|
<div className="preview-overflow-wrap-fields" style={{ position: "absolute", bottom: "5%", left: "10%", width: "auto" }}>{contentData.title ? contentData.title : ""}</div>
|
|
66
67
|
</CapRow>
|
|
67
68
|
{Object.keys(mediaList).length === 1 ?
|
|
@@ -80,7 +81,7 @@ class WechatRichmediaTemplatePreview extends React.PureComponent { // eslint-dis
|
|
|
80
81
|
{contentData.title}
|
|
81
82
|
</CapColumn>
|
|
82
83
|
<CapColumn style={{ float: "right" }}>
|
|
83
|
-
<
|
|
84
|
+
<CapImage alt="default" width="60px" height="60px" src={contentData.image_url}/>
|
|
84
85
|
</CapColumn>
|
|
85
86
|
</CapRow>
|
|
86
87
|
);
|
|
@@ -91,21 +92,102 @@ class WechatRichmediaTemplatePreview extends React.PureComponent { // eslint-dis
|
|
|
91
92
|
goToEdit(e, path) {
|
|
92
93
|
this.props.onEditClick(e, this.props.templateId, this.props.modeType, path);
|
|
93
94
|
}
|
|
94
|
-
|
|
95
|
+
getWechatRichMediaAndroidPreview = (content) => (
|
|
96
|
+
<div className="preview-container">
|
|
97
|
+
<div className="shell-lock-screen-android align-center">
|
|
98
|
+
<div className="lock-screen-preview">
|
|
99
|
+
<CapImage className="preview-image" src={wechatLockScreenAndroid} alt="Preview is being generated"/>
|
|
100
|
+
<div className="wechat-android-sender-id">
|
|
101
|
+
Muji India
|
|
102
|
+
</div>
|
|
103
|
+
<div className="wechat-android-title">
|
|
104
|
+
{content[0].title}
|
|
105
|
+
</div>
|
|
106
|
+
<div className="wechat-android-action-buttons">
|
|
107
|
+
<FormattedMessage {...messages.MarkAsRead} /> <FormattedMessage {...messages.reply} />
|
|
108
|
+
</div>
|
|
109
|
+
</div>
|
|
110
|
+
<div className="main-screen-preview">
|
|
111
|
+
<CapImage className="preview-image" src={wechatBody} alt="Preview is being generated"/>
|
|
112
|
+
<div className={this.props.type === 'embedded' ? "wechatMsgContainerOutbound" : "wechatMsgContainer"}>
|
|
113
|
+
<div className={this.props.type === 'embedded' ? "overflow-handle-preview-outbound" : "overflow-handle-preview"}>
|
|
114
|
+
{this.preparePreviewData(content)}
|
|
115
|
+
</div>
|
|
116
|
+
</div>
|
|
117
|
+
</div>
|
|
118
|
+
</div>
|
|
119
|
+
</div>
|
|
120
|
+
);
|
|
121
|
+
|
|
122
|
+
getWechatRIchMediaIosPreview = (content) => (
|
|
123
|
+
<div className="preview-container">
|
|
124
|
+
<div className="shell-lock-screen-android align-center">
|
|
125
|
+
<div className="lock-screen-preview">
|
|
126
|
+
<CapImage className="preview-image" src={wechatLockScreenIos} alt="Preview is being generated"/>
|
|
127
|
+
<div className="wechat-ios-sender-id">
|
|
128
|
+
Muji India
|
|
129
|
+
</div>
|
|
130
|
+
<div className="wechat-ios-title">
|
|
131
|
+
{content[0].title}
|
|
132
|
+
</div>
|
|
133
|
+
<div className="wechat-ios-action-reply">
|
|
134
|
+
<FormattedMessage {...messages.reply} />
|
|
135
|
+
</div>
|
|
136
|
+
<div className="wechat-ios-action-cancel">
|
|
137
|
+
<FormattedMessage {...messages.cancel} />
|
|
138
|
+
</div>
|
|
139
|
+
</div>
|
|
140
|
+
<div className="main-screen-preview">
|
|
141
|
+
<CapImage className="preview-image" src={wechatBody} alt="Preview is being generated"/>
|
|
142
|
+
<div className={this.props.type === 'embedded' ? "wechatMsgContainerOutbound" : "wechatMsgContainer"}>
|
|
143
|
+
<div className={this.props.type === 'embedded' ? "overflow-handle-preview-outbound" : "overflow-handle-preview"}>
|
|
144
|
+
{this.preparePreviewData(content)}
|
|
145
|
+
</div>
|
|
146
|
+
</div>
|
|
147
|
+
</div>
|
|
148
|
+
</div>
|
|
149
|
+
</div>
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
getContentForSlidebox = (content) => {
|
|
95
153
|
return (
|
|
96
|
-
|
|
97
|
-
{this.props.
|
|
98
|
-
<div className=
|
|
99
|
-
<
|
|
100
|
-
|
|
101
|
-
<div className={this.props.type === 'embedded' ? "
|
|
102
|
-
|
|
103
|
-
{this.preparePreviewData(this.props.content)}
|
|
104
|
-
</div>
|
|
154
|
+
!this.props.showLockScreenPreview ? (
|
|
155
|
+
<div className={`preview-container ${this.props.type === 'embedded' ? 'embedded-preview' : ''}`}>
|
|
156
|
+
<div className="shell align-center" id="sms-preview">
|
|
157
|
+
<CapImage className="preview-image" src={wechatBody} alt="Preview is being generated"/>
|
|
158
|
+
<div className={this.props.type === 'embedded' ? "wechatMsgContainerOutbound" : "wechatMsgContainer"}>
|
|
159
|
+
<div className={this.props.type === 'embedded' ? "overflow-handle-preview-outbound" : "overflow-handle-preview"}>
|
|
160
|
+
{this.preparePreviewData(this.props.content)}
|
|
105
161
|
</div>
|
|
106
162
|
</div>
|
|
107
|
-
{this.props.showEdit ? <CapButton onClick={(e) => this.goToEdit(e, this.props.path)} className="preview-buttons" type="primary">{this.props.type === 'embedded' ? <FormattedMessage {...messages.select} /> : <FormattedMessage {...messages.edit} /> }</CapButton> : ""}
|
|
108
163
|
</div>
|
|
164
|
+
{this.props.showEdit ? <CapButton onClick={(e) => this.goToEdit(e, this.props.path)} className="preview-buttons" type="primary">{this.props.type === 'embedded' ? <FormattedMessage {...messages.select} /> : <FormattedMessage {...messages.edit} /> }</CapButton> : ""}
|
|
165
|
+
</div>
|
|
166
|
+
) : (
|
|
167
|
+
<CapTab
|
|
168
|
+
panes={[
|
|
169
|
+
{
|
|
170
|
+
content: this.getWechatRichMediaAndroidPreview(this.props.content),
|
|
171
|
+
tab: <CapIcon type="android" size='m' />,
|
|
172
|
+
key: 'android',
|
|
173
|
+
},
|
|
174
|
+
{
|
|
175
|
+
content: this.getWechatRIchMediaIosPreview(this.props.content),
|
|
176
|
+
tab: <CapIcon type="ios" size='m' />,
|
|
177
|
+
key: 'ios',
|
|
178
|
+
},
|
|
179
|
+
]}
|
|
180
|
+
tabBarStyle={{margin: 'auto', width: '14%'}}
|
|
181
|
+
/>
|
|
182
|
+
)
|
|
183
|
+
);
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
render() {
|
|
187
|
+
return (
|
|
188
|
+
<div>
|
|
189
|
+
{this.props.contentForSlideBox ?
|
|
190
|
+
this.getContentForSlidebox(this.props.content)
|
|
109
191
|
:
|
|
110
192
|
<div className={`preview-container ${this.props.type === 'embedded' ? 'embedded-preview' : ''}`}>
|
|
111
193
|
<div className="shell align-center" id="sms-preview">
|
|
@@ -18,4 +18,16 @@ export default defineMessages({
|
|
|
18
18
|
id: 'creatives.components.WechatRichmediaTemplatePreview.edit',
|
|
19
19
|
defaultMessage: 'Edit',
|
|
20
20
|
},
|
|
21
|
+
MarkAsRead: {
|
|
22
|
+
id: 'creatives.components.WechatRichmediaTemplatePreview.MarkAsRead',
|
|
23
|
+
defaultMessage: 'Mark as read',
|
|
24
|
+
},
|
|
25
|
+
reply: {
|
|
26
|
+
id: 'creatives.components.WechatRichmediaTemplatePreview.reply',
|
|
27
|
+
defaultMessage: 'Reply',
|
|
28
|
+
},
|
|
29
|
+
cancel: {
|
|
30
|
+
id: 'creatives.components.WechatRichmediaTemplatePreview.cancel',
|
|
31
|
+
defaultMessage: 'Cancel',
|
|
32
|
+
},
|
|
21
33
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
.shell {
|
|
1
|
+
.shell-v2 {
|
|
2
2
|
position: relative;
|
|
3
3
|
-webkit-transform: translate(-50%);
|
|
4
4
|
transform: translate(-50%);
|
|
@@ -15,8 +15,8 @@
|
|
|
15
15
|
|
|
16
16
|
.msgContainer {
|
|
17
17
|
position: absolute;
|
|
18
|
-
top:
|
|
19
|
-
left:
|
|
18
|
+
top: 20%;
|
|
19
|
+
left: 23%;
|
|
20
20
|
width: 42%;
|
|
21
21
|
height: 336px;
|
|
22
22
|
display: -webkit-box;
|
|
@@ -37,6 +37,9 @@
|
|
|
37
37
|
left: 14px;
|
|
38
38
|
}
|
|
39
39
|
}
|
|
40
|
+
&.wechat{
|
|
41
|
+
width: 52%;
|
|
42
|
+
}
|
|
40
43
|
|
|
41
44
|
.message-pop{
|
|
42
45
|
.unicode-disabled{
|
|
@@ -54,7 +57,7 @@
|
|
|
54
57
|
line-height: 14px;
|
|
55
58
|
padding: 0 8px 8px 8px;
|
|
56
59
|
font-size: 10px;
|
|
57
|
-
width:
|
|
60
|
+
width: 100%;
|
|
58
61
|
font-family: 'open-sans';
|
|
59
62
|
.message-pop-item{
|
|
60
63
|
padding: 4px;
|
|
@@ -359,3 +362,9 @@
|
|
|
359
362
|
font-size: 12px;
|
|
360
363
|
}
|
|
361
364
|
}
|
|
365
|
+
|
|
366
|
+
.test-and-preview-container{
|
|
367
|
+
display: flex;
|
|
368
|
+
margin-top: -12px;
|
|
369
|
+
margin-bottom: 12px;
|
|
370
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<svg xmlns="http://www.w3.org/2000/svg" width="220" height="472" viewBox="0 0 220 472">
|
|
2
|
+
<g fill="none" fill-rule="evenodd">
|
|
3
|
+
<rect width="220" height="472" fill="#101211" rx="26"/>
|
|
4
|
+
<rect width="52" height="5" x="84" y="14" fill="#2E2E2E" rx="2.5"/>
|
|
5
|
+
<rect width="52" height="5" x="84" y="455" fill="#2E2E2E" rx="2.5"/>
|
|
6
|
+
<circle cx="45.5" cy="19.5" r="5.5" fill="#2E2E2E"/>
|
|
7
|
+
<circle cx="65.5" cy="19.5" r="3.5" fill="#2E2E2E"/>
|
|
8
|
+
<rect width="202" height="404" x="9" y="36" fill="#E51FA3" rx="9"/>
|
|
9
|
+
<path fill="#F4F5F7" d="M20.692 152h178.616c2.675 0 3.645.278 4.623.801.977.523 1.745 1.29 2.268 2.268.523.978.801 1.948.801 4.623v78.616c0 2.675-.278 3.645-.801 4.623-.523.977-1.29 1.745-2.268 2.268-.978.523-1.948.801-4.623.801H20.692c-2.675 0-3.645-.278-4.623-.801-.977-.523-1.745-1.29-2.268-2.268-.523-.978-.801-1.948-.801-4.623v-78.616c0-2.675.278-3.645.801-4.623.523-.977 1.29-1.745 2.268-2.268.978-.523 1.948-.801 4.623-.801z"/>
|
|
10
|
+
<text fill="#5E5E5E" font-family="Roboto-Regular, Roboto" font-size="10">
|
|
11
|
+
<tspan x="25" y="169">Messages</tspan>
|
|
12
|
+
</text>
|
|
13
|
+
<text fill="#5E5E5E" font-family="Roboto-Regular, Roboto" font-size="10">
|
|
14
|
+
<tspan x="85.146" y="169">now</tspan>
|
|
15
|
+
</text>
|
|
16
|
+
<circle cx="78" cy="167" r="1" fill="#5E5E5E" fill-rule="nonzero"/>
|
|
17
|
+
<path fill="#5E5E5E" d="M116.725 163.048L113.424 166.342 110.123 163.048 109.109 164.062 113.424 168.377 117.739 164.062z"/>
|
|
18
|
+
<path fill="#FFF" fill-opacity=".6" d="M113.75 419.333h-.625v-1.238c0-1.708-1.4-3.095-3.125-3.095s-3.125 1.387-3.125 3.095v1.238h-.625c-.688 0-1.25.557-1.25 1.238v6.19c0 .682.563 1.239 1.25 1.239h7.5c.688 0 1.25-.557 1.25-1.238v-6.19c0-.682-.563-1.239-1.25-1.239zM110 425c-.55 0-1-.45-1-1s.45-1 1-1 1 .45 1 1-.45 1-1 1zm2-6h-4v-1.176c0-1.006.897-1.824 2-1.824s2 .818 2 1.824V419z"/>
|
|
19
|
+
<path fill="#FFF" fill-rule="nonzero" d="M86.325 111.884l6.192-8.676-.072-.072c-.84.576-1.908.864-3.204.864-1.248 0-2.472-.348-3.672-1.044-1.2-.696-2.172-1.65-2.916-2.862-.744-1.212-1.116-2.562-1.116-4.05 0-1.44.378-2.79 1.134-4.05.756-1.26 1.776-2.274 3.06-3.042 1.284-.768 2.682-1.152 4.194-1.152 1.632 0 3.09.396 4.374 1.188 1.284.792 2.28 1.818 2.988 3.078.708 1.26 1.062 2.586 1.062 3.978 0 1.32-.27 2.586-.81 3.798-.54 1.212-1.314 2.562-2.322 4.05l-6.444 9.684-2.448-1.692zm3.6-10.62c.96 0 1.854-.234 2.682-.702.828-.468 1.482-1.104 1.962-1.908.48-.804.72-1.686.72-2.646 0-.984-.24-1.878-.72-2.682s-1.134-1.44-1.962-1.908c-.828-.468-1.722-.702-2.682-.702s-1.848.234-2.664.702c-.816.468-1.464 1.104-1.944 1.908-.48.804-.72 1.698-.72 2.682 0 .96.24 1.842.72 2.646.48.804 1.128 1.44 1.944 1.908.816.468 1.704.702 2.664.702zm13.806-2.232c-.648 0-1.194-.222-1.638-.666-.444-.444-.666-.99-.666-1.638 0-.648.222-1.194.666-1.638.444-.444.99-.666 1.638-.666.624 0 1.158.222 1.602.666.444.444.666.99.666 1.638 0 .648-.222 1.194-.666 1.638-.444.444-.978.666-1.602.666zm0 14.184c-.648 0-1.194-.222-1.638-.666-.444-.444-.666-.99-.666-1.638 0-.624.222-1.158.666-1.602.444-.444.99-.666 1.638-.666.624 0 1.158.222 1.602.666.444.444.666.978.666 1.602 0 .648-.222 1.194-.666 1.638-.444.444-.978.666-1.602.666zm17.191-5.508h-11.808v-2.304l11.52-17.028h3.312v16.452h3.168v2.88h-3.168V113h-3.024v-5.292zm0-2.88V92.84h-.144l-8.172 11.988h8.316zm14.527-12.168l-4.32 3.096-1.584-2.34 7.02-5.04h1.944V113h-3.06V92.66zM90.177 134.16c-.56 0-1.074-.17-1.54-.51-.467-.34-.787-.817-.96-1.43l.81-.33c.113.427.323.777.63 1.05.306.273.666.41 1.08.41.413 0 .763-.112 1.05-.335.286-.223.43-.528.43-.915 0-.333-.122-.608-.365-.825-.244-.217-.642-.418-1.195-.605l-.45-.16c-.507-.18-.92-.417-1.24-.71-.32-.293-.48-.7-.48-1.22 0-.34.093-.655.28-.945.186-.29.446-.522.78-.695.333-.173.706-.26 1.12-.26.413 0 .773.077 1.08.23.306.153.551.34.735.56.183.22.311.437.385.65l-.8.34c-.067-.247-.219-.47-.455-.67-.237-.2-.549-.3-.935-.3-.367 0-.68.103-.94.31-.26.207-.39.467-.39.78 0 .28.11.508.33.685.22.177.553.342 1 .495l.47.16c.606.22 1.08.495 1.42.825.34.33.51.778.51 1.345 0 .46-.119.847-.355 1.16-.237.313-.535.543-.895.69-.36.147-.73.22-1.11.22zm4.995 0c-.614 0-1.082-.18-1.405-.54-.324-.36-.485-.863-.485-1.51v-3.21h.85v3.08c0 .487.11.843.33 1.07.22.227.516.34.89.34.286 0 .541-.077.765-.23.223-.153.396-.353.52-.6.123-.247.185-.507.185-.78v-2.88h.85v5.1h-.81v-.74h-.04c-.14.253-.364.467-.67.64-.307.173-.634.26-.98.26zm3.615-5.26h.81v.75h.04c.14-.253.363-.468.67-.645.307-.177.633-.265.98-.265.613 0 1.082.178 1.405.535.323.357.485.842.485 1.455V134h-.85v-3.14c0-.473-.113-.817-.34-1.03-.227-.213-.537-.32-.93-.32-.273 0-.518.077-.735.23-.217.153-.385.355-.505.605s-.18.512-.18.785V134h-.85v-5.1zm8.88 5.26c-.526 0-.986-.145-1.38-.435-.393-.29-.67-.698-.83-1.225l.8-.33c.24.787.71 1.18 1.41 1.18.394 0 .709-.137.945-.41.237-.273.355-.633.355-1.08v-5.02h.85v4.95c0 .5-.091.928-.275 1.285-.183.357-.436.627-.76.81-.323.183-.695.275-1.115.275zm5.065 0c-.613 0-1.081-.18-1.405-.54-.323-.36-.485-.863-.485-1.51v-3.21h.85v3.08c0 .487.11.843.33 1.07.22.227.517.34.89.34.287 0 .542-.077.765-.23.224-.153.397-.353.52-.6.124-.247.185-.507.185-.78v-2.88h.85v5.1h-.81v-.74h-.04c-.14.253-.363.467-.67.64-.306.173-.633.26-.98.26zm3.616-7.32h.85V134h-.85v-7.16zm2.525 7.22c-.18 0-.332-.062-.455-.185-.124-.123-.185-.275-.185-.455 0-.173.061-.322.185-.445.123-.123.275-.185.455-.185.173 0 .321.062.445.185.123.123.185.272.185.445 0 .18-.062.332-.185.455-.124.123-.272.185-.445.185zm3.67-.91c.207-.207.617-.622 1.23-1.245.613-.623 1.04-1.065 1.28-1.325.34-.367.57-.653.69-.86.12-.207.18-.457.18-.75 0-.2-.052-.388-.155-.565-.103-.177-.253-.32-.45-.43-.197-.11-.432-.165-.705-.165-.36 0-.648.105-.865.315-.217.21-.358.438-.425.685l-.78-.31c.067-.213.187-.435.36-.665.173-.23.407-.427.7-.59.293-.163.64-.245 1.04-.245.42 0 .792.09 1.115.27.323.18.575.42.755.72.18.3.27.623.27.97 0 .7-.367 1.423-1.1 2.17l-2.05 2.06h3.23v.81h-4.32v-.85zm6.435.54l1.72-2.41-.02-.02c-.233.16-.53.24-.89.24-.346 0-.686-.097-1.02-.29-.333-.193-.603-.458-.81-.795-.206-.337-.31-.712-.31-1.125 0-.4.105-.775.315-1.125.21-.35.494-.632.85-.845.357-.213.745-.32 1.165-.32.454 0 .859.11 1.215.33.357.22.634.505.83.855.197.35.295.718.295 1.105 0 .367-.075.718-.225 1.055-.15.337-.365.712-.645 1.125l-1.79 2.69-.68-.47zm1-2.95c.267 0 .515-.065.745-.195.23-.13.412-.307.545-.53.134-.223.2-.468.2-.735 0-.273-.066-.522-.2-.745-.133-.223-.315-.4-.545-.53-.23-.13-.478-.195-.745-.195-.266 0-.513.065-.74.195-.226.13-.406.307-.54.53-.133.223-.2.472-.2.745 0 .267.067.512.2.735.134.223.314.4.54.53.227.13.474.195.74.195z"/>
|
|
20
|
+
</g>
|
|
21
|
+
</svg>
|