diff --git a/blocks/library/chat/block.scss b/blocks/library/chat/block.scss new file mode 100644 index 00000000000000..165980af9fae44 --- /dev/null +++ b/blocks/library/chat/block.scss @@ -0,0 +1,48 @@ +.wp-block-chat { + font-family: $editor-html-font; + + > p { + margin: 0; + + &:first-child .chat-author { + margin-top: 0; + } + } + + .chat-author { + display: block; + margin-top: 1em; + color: $blue-wordpress; + } + + .chat-message { + margin-left: 1em; + } + + &.is-compact { + .chat-author { + display: inline; + margin: 0 .5em 0 0; + } + + .chat-message { + margin-left: 0; + } + } + + .chat-author-1 .chat-author { + color: $alert-yellow; + } + + .chat-author-2 .chat-author { + color: $alert-red; + } + + .chat-author-3 .chat-author { + color: $alert-green; + } + + .chat-author-4 .chat-author { + color: $dark-gray-800; + } +} diff --git a/blocks/library/chat/chat-transcript.js b/blocks/library/chat/chat-transcript.js new file mode 100644 index 00000000000000..db19f96b0a6b80 --- /dev/null +++ b/blocks/library/chat/chat-transcript.js @@ -0,0 +1,69 @@ +/** + * External dependencies + */ +import { uniq } from 'lodash'; + +/** + * WordPress dependencies + */ +import classnames from 'classnames'; + +export function normalizeTranscript( value ) { + const transcript = { + authors: [], + messages: [], + }; + + if ( ! value ) { + return transcript; + } + + let authorIndex = -1; + + value.split( '\n' ).map( ( line ) => { + line = line.trim(); + + const messageParts = line.split( ':' ); + let message; + + if ( 1 === messageParts.length ) { + message = messageParts.shift(); + } else { + const author = messageParts.shift().trim(); + message = messageParts.join( ':' ).trim(); + + transcript.authors.push( author ); + transcript.authors = uniq( transcript.authors ); + authorIndex = transcript.authors.indexOf( author ); + } + + transcript.messages.push( { + message: message, + authorIndex: authorIndex, + } ); + } ); + + return transcript; +} + +export default function ChatTranscript( { value, compact, className } ) { + // Normalize data + const transcript = normalizeTranscript( value ); + + const classes = classnames( className, { 'is-compact': compact } ); + + return ( +
+ {value && transcript.messages.map( ( entry, index ) => { + const author = -1 !== entry.authorIndex ? transcript.authors[ entry.authorIndex ] : undefined; + + return ( + entry.message &&

+ { author && { `${ author }:` } } + { entry.message } +

+ ); + } ) } +
+ ); +} diff --git a/blocks/library/chat/index.js b/blocks/library/chat/index.js new file mode 100644 index 00000000000000..2d2538e0d06744 --- /dev/null +++ b/blocks/library/chat/index.js @@ -0,0 +1,83 @@ +/** + * External dependencies + */ +import TextareaAutosize from 'react-autosize-textarea'; + +/** + * WordPress dependencies + */ +import { Placeholder } from 'components'; +import { __ } from 'i18n'; + +/** + * Internal dependencies + */ +import './block.scss'; +import './style.scss'; +import { registerBlockType, query } from '../../api'; +import InspectorControls from '../../inspector-controls'; +import ToggleControl from '../../inspector-controls/toggle-control'; +import ChatTranscript from './chat-transcript'; + +const { html } = query; + +registerBlockType( 'core/chat', { + title: __( 'Chat' ), + + icon: 'format-chat', + + category: 'formatting', + + attributes: { + content: html(), + }, + + defaultAttributes: { + compact: false, + }, + + edit( { attributes, setAttributes, focus, setFocus, className } ) { + const { compact, content } = attributes; + + const toggleCompact = () => setAttributes( { compact: ! compact } ); + + return [ + focus && ( + + + + ), + focus && ( + + setAttributes( { content: event.target.value } ) } + placeholder={ __( 'Paste transcript here…' ) } + /> + + ), + ! focus && ( + + ), + ]; + }, + + save( { attributes } ) { + const { compact, content } = attributes; + + return ; + }, +} ); diff --git a/blocks/library/chat/style.scss b/blocks/library/chat/style.scss new file mode 100644 index 00000000000000..4dc8672ff029ab --- /dev/null +++ b/blocks/library/chat/style.scss @@ -0,0 +1,20 @@ +.wp-block-chat { + .components-placeholder__fieldset { + max-width: none; + } + + textarea { + box-shadow: none; + background: $white; + font-family: $editor-html-font; + font-size: $text-editor-font-size; + color: $dark-gray-800; + border: 1px solid $light-gray-500; + border-radius: 4px; + margin: 0; + overflow-x: auto; + width: 100%; + min-height: 10em; + text-align: left; + } +} diff --git a/blocks/library/index.js b/blocks/library/index.js index 93a71f0cc3accb..a45d643bb3ef0c 100644 --- a/blocks/library/index.js +++ b/blocks/library/index.js @@ -15,3 +15,4 @@ import './html'; import './freeform'; import './latest-posts'; import './cover-image'; +import './chat'; diff --git a/blocks/test/fixtures/core__chat.html b/blocks/test/fixtures/core__chat.html new file mode 100644 index 00000000000000..aef0439d8ab238 --- /dev/null +++ b/blocks/test/fixtures/core__chat.html @@ -0,0 +1,13 @@ + +Pascal: Alexa, open the window +Alexa: I'm not quite sure how to help you with +Pascal: Siri, tell me a joke +Siri: Pascal, get Siri-ous. Ha ha! +Pascal: OK, Google. Now it's your turn! +Google Home: Alexa, tell Siri to tell Pascal a better joke. +Pascal: Ugh! +Okay, that's enough. No internet for you anymore! +Alexa: πŸ’” +Google Home: πŸ˜” +Siri: πŸ“΄ + diff --git a/blocks/test/fixtures/core__chat.json b/blocks/test/fixtures/core__chat.json new file mode 100644 index 00000000000000..f283196f235a92 --- /dev/null +++ b/blocks/test/fixtures/core__chat.json @@ -0,0 +1,10 @@ +[ + { + "uid": "_uid_0", + "name": "core/chat", + "attributes": { + "compact": false, + "content": "Pascal: Alexa, open the window\nAlexa: I'm not quite sure how to help you with\nPascal: Siri, tell me a joke\nSiri: Pascal, get Siri-ous. Ha ha!\nPascal: OK, Google. Now it's your turn!\nGoogle Home: Alexa, tell Siri to tell Pascal a better joke.\nPascal: Ugh!\nOkay, that's enough. No internet for you anymore!\nAlexa: πŸ’”\nGoogle Home: πŸ˜”\nSiri: πŸ“΄" + } + } +] diff --git a/blocks/test/fixtures/core__chat.parsed.json b/blocks/test/fixtures/core__chat.parsed.json new file mode 100644 index 00000000000000..5b05da21b3321c --- /dev/null +++ b/blocks/test/fixtures/core__chat.parsed.json @@ -0,0 +1,13 @@ +[ + { + "blockName": "core/chat", + "attrs": { + "compact": false + }, + "rawContent": "\nPascal: Alexa, open the window\nAlexa: I'm not quite sure how to help you with\nPascal: Siri, tell me a joke\nSiri: Pascal, get Siri-ous. Ha ha!\nPascal: OK, Google. Now it's your turn!\nGoogle Home: Alexa, tell Siri to tell Pascal a better joke.\nPascal: Ugh!\nOkay, that's enough. No internet for you anymore!\nAlexa: πŸ’”\nGoogle Home: πŸ˜”\nSiri: πŸ“΄\n" + }, + { + "attrs": {}, + "rawContent": "\n" + } +] diff --git a/blocks/test/fixtures/core__chat.serialized.html b/blocks/test/fixtures/core__chat.serialized.html new file mode 100644 index 00000000000000..1e48052c810761 --- /dev/null +++ b/blocks/test/fixtures/core__chat.serialized.html @@ -0,0 +1,15 @@ + +
+

Pascal: Alexa, open the window

+

Alexa: I'm not quite sure how to help you with

+

Pascal: Siri, tell me a joke

+

Siri: Pascal, get Siri-ous. Ha ha!

+

Pascal: OK, Google. Now it's your turn!

+

Google Home: Alexa, tell Siri to tell Pascal a better joke.

+

Pascal: Ugh!

+

Okay, that's enough. No internet for you anymore!

+

Alexa: πŸ’”

+

Google Home: πŸ˜”

+

Siri: πŸ“΄

+
+