Skip to content

Commit

Permalink
Initial addition of send a message block into Jetpack block scaffolding
Browse files Browse the repository at this point in the history
  • Loading branch information
apeatling committed Mar 19, 2020
1 parent 59ca951 commit 3f31510
Show file tree
Hide file tree
Showing 12 changed files with 774 additions and 1 deletion.
31 changes: 31 additions & 0 deletions extensions/blocks/send-a-message/attributes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* External dependencies
*/
import { __ } from '@wordpress/i18n';

export default {
countryCode: {
type: 'string',
},
phoneNumber: {
type: 'string',
},
firstMessage: {
type: 'string',
default: __( 'Hi, I got your WhatsApp information from your website.', 'jetpack' ),
},
buttonText: {
type: 'array',
source: 'children',
selector: 'a.whatsapp-block__button',
default: __( 'Chat on WhatsApp', 'jetpack' ),
},
backgroundColor: {
type: 'string',
default: '#25D366',
},
colorClass: {
type: 'string',
default: 'dark',
},
};
241 changes: 241 additions & 0 deletions extensions/blocks/send-a-message/countrycodes.js

Large diffs are not rendered by default.

250 changes: 250 additions & 0 deletions extensions/blocks/send-a-message/edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
/**
* External dependencies
*/

import { Component } from '@wordpress/element';
import { __, _x } from '@wordpress/i18n';
import {
Button,
Placeholder,
TextControl,
TextareaControl,
SelectControl,
Toolbar,
Popover,
Icon,
PanelBody,
PanelRow,
} from '@wordpress/components';
import {
BlockControls,
InspectorControls,
RichText,
PanelColorSettings,
ContrastChecker,
} from '@wordpress/block-editor';

/**
* Internal dependencies
*/

import { countryCodes } from './countrycodes.js';
import { WhatsAppIcon } from './icon.js';
import { title } from './index';
import './view.scss';

export default class SendAMessageEdit extends Component {
constructor() {
super( ...arguments );

this.setDefaultCountryCode();

const isValidPhoneNumber = this.isValidPhoneNumber();
this.state = {
editing: ! isValidPhoneNumber,
isValidPhoneNumber: isValidPhoneNumber,
};

this.onSubmitURL = this.onSubmitURL.bind( this );
}

async setDefaultCountryCode() {
const { countryCode } = this.props.attributes;
const { setAttributes } = this.props;

if ( undefined === countryCode ) {
setAttributes( { countryCode: '1' } );

const geoFetch = await fetch( 'http://ip-api.com/json/?fields=countryCode' )
.then( response => {
if ( ! response.ok ) {
return false;
}

return response;
} )
.catch( () => {
return false;
} );

if ( geoFetch ) {
const geo = await geoFetch.json();

countryCodes.forEach( item => {
if ( item.code === geo.countryCode ) {
setAttributes( { countryCode: item.value } );
}
} );
}
}
}

onSubmitURL( e ) {
e.preventDefault();

if ( this.isValidPhoneNumber() ) {
this.setState( {
editing: false,
isValidPhoneNumber: true,
} );
} else {
this.setState( {
isValidPhoneNumber: false,
} );
}
}

isValidPhoneNumber() {
const { countryCode, phoneNumber } = this.props.attributes;
const phoneNumberRegEx = RegExp( /^[+]?[\s./0-9]*[(]?[0-9]{1,4}[)]?[-\s./0-9]*$/, 'g' );

if ( undefined === phoneNumber || phoneNumber.length < 1 ) {
return false;
}

return phoneNumberRegEx.test( countryCode.replace( /\D/g, '' ) + phoneNumber );
}

render() {
const {
countryCode,
phoneNumber,
buttonText,
firstMessage,
colorClass,
backgroundColor,
} = this.props.attributes;

const { setAttributes, className } = this.props;

const onFocusPhoneNumber = () => {
this.setState( { isValidPhoneNumber: true } );
};

if ( this.state.editing ) {
return (
<Placeholder
icon={ WhatsAppIcon }
label={ title }
instructions={ __( 'Enter the phone number for your WhatsApp account:', 'jetpack' ) }
className={ className }
>
<form onSubmit={ this.onSubmitURL }>
<SelectControl
value={ countryCode }
onChange={ value => setAttributes( { countryCode: value } ) }
options={ countryCodes }
/>
<TextControl
placeholder={ __( 'Your phone number…', 'jetpack' ) }
onChange={ value => setAttributes( { phoneNumber: value } ) }
onFocus={ onFocusPhoneNumber }
value={ phoneNumber }
/>
{ ! this.state.isValidPhoneNumber && (
<Popover position="top center" className="whatsapp-phonenumber-invalid">
<Icon icon="info" />
{ __( 'Please enter a valid phone number', 'jetpack' ) }
</Popover>
) }
<Button isLarge type="submit">
{ _x( 'Insert', 'block insert button', 'jetpack' ) }
</Button>
</form>
</Placeholder>
);
}

const toolbarControls = [
{
icon: 'edit',
title: __( 'Edit WhatsApp phone number', 'jetpack' ),
onClick: () => this.setState( { editing: true } ),
},
];

const setBackgroundColor = color => {
setAttributes( { backgroundColor: color } );

if ( color === undefined || color === '#25D366' || color === '#465B64' ) {
return setAttributes( { colorClass: 'dark' } );
}

setAttributes( { colorClass: 'light' } );
};

return (
<div className={ className + ' is-color-' + colorClass }>
<BlockControls>
<Toolbar controls={ toolbarControls } />
</BlockControls>

<InspectorControls>
<PanelBody title="Message Settings" initialOpen={ true }>
<PanelRow>
<TextareaControl
label={ __( 'Default First Message', 'jetpack' ) }
help={ __(
'The default first message that will be sent by visitors when using this button.',
'jetpack'
) }
value={ firstMessage }
onChange={ text => setAttributes( { firstMessage: text } ) }
/>
</PanelRow>
</PanelBody>
<PanelColorSettings
title={ __( 'Color Settings', 'jetpack' ) }
initialOpen={ false }
colorSettings={ [
{
value: backgroundColor,
onChange: color => setBackgroundColor( color ),
label: __( 'Background Color', 'jetpack' ),
disableCustomColors: true,
colors: [
{
name: _x( 'WhatsApp Green', 'background color name', 'jetpack' ),
slug: 'whatsapp-green',
color: '#25D366',
},
{
name: _x( 'WhatsApp Dark', 'background color name', 'jetpack' ),
slug: 'whatsapp-dark',
color: '#465B64',
},
{
name: _x( 'WhatsApp Light', 'background color name', 'jetpack' ),
slug: 'whatsapp-light',
color: '#F4F4F4',
},
{
name: _x( 'White', 'background color name', 'jetpack' ),
slug: 'whatsapp-white',
color: '#FFFFFF',
},
],
},
] }
>
<ContrastChecker />
</PanelColorSettings>
</InspectorControls>

<RichText
placeholder={ buttonText.default }
keepPlaceholderOnFocus={ true }
value={ buttonText }
onChange={ value => setAttributes( { buttonText: value } ) }
withoutInteractiveFormatting
allowedFormats={ [] }
className="whatsapp-block__button"
tagName="a"
style={ {
backgroundColor: backgroundColor,
} }
/>
</div>
);
}
}
7 changes: 7 additions & 0 deletions extensions/blocks/send-a-message/editor.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/**
* Internal dependencies
*/
import registerJetpackBlock from '../../shared/register-jetpack-block';
import { name, settings } from '.';

registerJetpackBlock( name, settings );
44 changes: 44 additions & 0 deletions extensions/blocks/send-a-message/editor.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/**
* Editor styles for Send A Message
*/

.wp-block-jetpack-send-a-message {
input.components-text-control__input {
padding: 5px 8px;
margin-left: 3px;
}

select.components-select-control__input {
width: 95px;
min-height: 30px;
padding-left: 10px;
}

button.components-button.is-large {
margin-left: 7px;
}

.components-placeholder__label svg {
margin-right: 6px;
}
}

.whatsapp-phonenumber-invalid {
.components-popover__content {
background: #B40000;
color: white;
padding: 6px 10px;
border-radius: 6px;
border: none;
}

&:not(.is-without-arrow):not(.is-mobile):after {
border-color: #B40000;
}

svg.dashicon {
vertical-align: top;
margin-right: 4px;
margin-top: -1px;
}
}
10 changes: 10 additions & 0 deletions extensions/blocks/send-a-message/icon.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3f31510

Please sign in to comment.