diff --git a/client/.babelrc b/client/.babelrc index 60be246eb..2af1a3dad 100644 --- a/client/.babelrc +++ b/client/.babelrc @@ -9,6 +9,7 @@ "transform-object-assign", "transform-object-rest-spread", "transform-async-to-generator", - "transform-react-jsx" + "transform-react-jsx", + "syntax-dynamic-import" ] } \ No newline at end of file diff --git a/client/coral-admin/src/routes/Configure/components/StreamSettings.js b/client/coral-admin/src/routes/Configure/components/StreamSettings.js index 1bd7534af..9c216a853 100644 --- a/client/coral-admin/src/routes/Configure/components/StreamSettings.js +++ b/client/coral-admin/src/routes/Configure/components/StreamSettings.js @@ -4,7 +4,7 @@ import t from 'coral-framework/services/i18n'; import styles from './Configure.css'; import {Checkbox, Textfield} from 'react-mdl'; import {Card, Icon, TextArea} from 'coral-ui'; -import MarkdownEditor from 'coral-admin/src/components/MarkdownEditor'; +import MarkdownEditor from 'coral-framework/components/MarkdownEditor'; const TIMESTAMPS = { weeks: 60 * 60 * 24 * 7, diff --git a/client/coral-configure/components/ConfigureCommentStream.css b/client/coral-configure/components/ConfigureCommentStream.css index a8cbc36cb..5575e073b 100644 --- a/client/coral-configure/components/ConfigureCommentStream.css +++ b/client/coral-configure/components/ConfigureCommentStream.css @@ -12,10 +12,6 @@ padding: 0; } -.wrapper ul ul { - padding-left: 20px -} - .checkbox { vertical-align: top; margin: 12px 12px 12px 0; @@ -36,4 +32,4 @@ .hidden { display: none; -} +} \ No newline at end of file diff --git a/client/coral-configure/components/ConfigureCommentStream.js b/client/coral-configure/components/ConfigureCommentStream.js index 5ee9b706f..726b54e19 100644 --- a/client/coral-configure/components/ConfigureCommentStream.js +++ b/client/coral-configure/components/ConfigureCommentStream.js @@ -1,5 +1,6 @@ import React from 'react'; -import {Button, Checkbox, TextField} from 'coral-ui'; +import {Button, Checkbox} from 'coral-ui'; +import QuestionBoxBuilder from './QuestionBoxBuilder'; import styles from './ConfigureCommentStream.css'; @@ -55,17 +56,14 @@ export default ({handleChange, handleApply, changed, ...props}) => ( title: t('configure.enable_questionbox'), description: t('configure.enable_questionbox_description') }} /> -
- -
+ { + props.questionBoxEnable && + } - diff --git a/client/coral-configure/components/DefaultIcon.css b/client/coral-configure/components/DefaultIcon.css new file mode 100644 index 000000000..6125d2f6a --- /dev/null +++ b/client/coral-configure/components/DefaultIcon.css @@ -0,0 +1,27 @@ +.iconBubble{ + position: absolute; + top: 8px; + left: 10px; + color: #9E9E9E; + font-size: 24px; + z-index: 0; +} + +.iconPerson{ + z-index: 2; + top: 12px; + left: 12px; + position: absolute; + font-size: 33px; + color: #262626; +} + +.qbIconContainer { + position: relative; + border: 0; + color: white; + display: inline-block; + padding: 5px 20px; + vertical-align: middle; + width: 10px; +} \ No newline at end of file diff --git a/client/coral-configure/components/DefaultIcon.js b/client/coral-configure/components/DefaultIcon.js new file mode 100644 index 000000000..5f6f4876c --- /dev/null +++ b/client/coral-configure/components/DefaultIcon.js @@ -0,0 +1,13 @@ +import React from 'react'; +import cn from 'classnames'; +import styles from './DefaultIcon.css'; +import {Icon} from 'coral-ui'; + +const DefaultIcon = ({className}) => ( +
+ + +
+); + +export default DefaultIcon; diff --git a/client/talk-plugin-infobox/Markdown.js b/client/coral-configure/components/Markdown.js similarity index 100% rename from client/talk-plugin-infobox/Markdown.js rename to client/coral-configure/components/Markdown.js diff --git a/client/coral-configure/components/QuestionBoxBuilder.css b/client/coral-configure/components/QuestionBoxBuilder.css new file mode 100644 index 000000000..758f350b9 --- /dev/null +++ b/client/coral-configure/components/QuestionBoxBuilder.css @@ -0,0 +1,45 @@ +.qbBuilder { + margin-left: 50px; +} + +.qbItemIconList { + padding: 0; + margin: 10px 0; +} + +.qbItemIcon { + background: #F0F0F0; + width: 45px; + height: 45px; + font-size: 24px; + text-align: center; + line-height: 45px; + color: #252525; + border-radius: 3px; + display: inline-block; + overflow: hidden; + margin-right: 10px; + position: relative; + border: solid 2px #F0F0F0; + transition: border 0.3s cubic-bezier(.4,0,.2,1); +} + +.qbItemIcon:hover { + cursor: pointer; +} + +.qbItemIconActive { + border: solid 2px #00796B; +} + +.defaultIcon { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +} + +.qb { + margin: 10px 0; +} \ No newline at end of file diff --git a/client/coral-configure/components/QuestionBoxBuilder.js b/client/coral-configure/components/QuestionBoxBuilder.js new file mode 100644 index 000000000..8ccc6ba31 --- /dev/null +++ b/client/coral-configure/components/QuestionBoxBuilder.js @@ -0,0 +1,98 @@ +import React from 'react'; +import QuestionBox from 'talk-plugin-questionbox/QuestionBox'; +import {Icon, Spinner} from 'coral-ui'; +import DefaultIcon from './DefaultIcon'; +import cn from 'classnames'; +import styles from './QuestionBoxBuilder.css'; + +class QuestionBoxBuilder extends React.Component { + constructor() { + super(); + + this.state = { + loading: true + }; + } + + componentWillMount() { + this.loadEditor(); + } + + async loadEditor() { + const MarkdownEditor = await import('coral-framework/components/MarkdownEditor'); + + return this.setState({ + loading : false, + MarkdownEditor + }); + } + + render() { + const {handleChange, questionBoxIcon, questionBoxContent} = this.props; + const {loading, MarkdownEditor} = this.state; + + if (loading) { + return ; + } + + return ( +
+

Include an Icon

+ +
    +
  • + +
  • +
  • + +
  • +
  • + +
  • +
  • + +
  • +
+ + + + handleChange({}, {questionBoxContent: value})} + /> + +
+ ); + } +} + +export default QuestionBoxBuilder; diff --git a/client/coral-configure/containers/ConfigureStreamContainer.js b/client/coral-configure/containers/ConfigureStreamContainer.js index 1d6d46ace..2d4a16795 100644 --- a/client/coral-configure/containers/ConfigureStreamContainer.js +++ b/client/coral-configure/containers/ConfigureStreamContainer.js @@ -27,10 +27,9 @@ class ConfigureStreamContainer extends Component { handleApply (e) { e.preventDefault(); const {elements} = e.target; + const {questionBoxIcon, questionBoxContent} = this.state.dirtySettings; const premod = elements.premod.checked; const questionBoxEnable = elements.qboxenable.checked; - const questionBoxContent = elements.qboxcontent.value; - const premodLinksEnable = elements.plinksenable.checked; const {changed} = this.state; @@ -38,6 +37,7 @@ class ConfigureStreamContainer extends Component { moderation: premod ? 'PRE' : 'POST', questionBoxEnable, questionBoxContent, + questionBoxIcon, premodLinksEnable }; @@ -51,14 +51,18 @@ class ConfigureStreamContainer extends Component { } } - handleChange (e) { - const changes = {}; + handleChange (e, newChanges) { + let changes = {}; + + if (changes) { + changes = {...newChanges}; + } if (e.target && e.target.id === 'qboxenable') { changes.questionBoxEnable = e.target.checked; } - if (e.target && e.target.id === 'qboxcontent') { - changes.questionBoxContent = e.target.value; + if (e.currentTarget && e.currentTarget.id === 'qboxicon') { + changes.questionBoxIcon = e.currentTarget.dataset.icon; } if (e.target && e.target.id === 'plinksenable') { changes.premodLinksEnable = e.target.value; @@ -105,6 +109,7 @@ class ConfigureStreamContainer extends Component { changed={this.state.changed} premodLinksEnable={dirtySettings.premodLinksEnable} premod={premod} + questionBoxIcon={dirtySettings.questionBoxIcon} questionBoxEnable={dirtySettings.questionBoxEnable} questionBoxContent={dirtySettings.questionBoxContent} /> diff --git a/client/coral-embed-stream/src/components/Stream.js b/client/coral-embed-stream/src/components/Stream.js index a51b999d6..c75c31296 100644 --- a/client/coral-embed-stream/src/components/Stream.js +++ b/client/coral-embed-stream/src/components/Stream.js @@ -129,6 +129,7 @@ class Stream extends React.Component { {!banned && temporarilySuspended && diff --git a/client/coral-embed-stream/src/containers/Stream.js b/client/coral-embed-stream/src/containers/Stream.js index 7be3d09d5..43be9018c 100644 --- a/client/coral-embed-stream/src/containers/Stream.js +++ b/client/coral-embed-stream/src/containers/Stream.js @@ -247,6 +247,7 @@ const fragments = { premodLinksEnable questionBoxEnable questionBoxContent + questionBoxIcon closeTimeout closedMessage charCountEnable diff --git a/client/coral-embed-stream/style/default.css b/client/coral-embed-stream/style/default.css index d4078bf27..010a65ab1 100644 --- a/client/coral-embed-stream/style/default.css +++ b/client/coral-embed-stream/style/default.css @@ -79,6 +79,12 @@ body { } /* Info Box Styles */ + +.hidden { + visibility: hidden; + display: none; +} + .talk-plugin-infobox-info { top: 0; border: 0; @@ -93,7 +99,6 @@ body { border-radius: 2px; } - .talk-plugin-infobox-info em{ font-style: italic; } @@ -113,66 +118,6 @@ body { } /* Question Box Styles */ -.talk-plugin-questionbox-info { - top: 0; - border: 0; - background: #F0F0F0; - color: black; - width: 100%; - text-align: left; - padding-left: 0px; - margin-bottom: 0px; - font-weight: bold; - font-size: 14px; - overflow: hidden; - min-height: 50px; - display: flex; -} - -.talk-plugin-questionbox-icon.bubble{ - position: absolute; - top: 8px; - left: 10px; - color: #9E9E9E; - font-size: 24px; - z-index: 0; -} - -.talk-plugin-questionbox-icon.person{ - z-index: 2; - top: 12px; - left: 12px; - position: absolute; - font-size: 33px; - color: #262626; -} - -.talk-plugin-questionbox-box { - position: relative; - border: 0; - color: white; - padding: 20px; - margin-left: 0px !important; - margin-right: 10px; - display: inline-block; - width: 10px; - min-height: 100%; - padding: 5px 20px; - vertical-align: middle; -} - -.talk-plugin-questionbox-content { - padding: 5px; - display: flex; - align-items: center; - justify-content: center; - font-weight: 400; -} - -.hidden { - visibility: hidden; - display: none; -} .talk-stream-comments-container { position: relative; diff --git a/client/coral-framework/components/Markdown.js b/client/coral-framework/components/Markdown.js new file mode 100644 index 000000000..482467987 --- /dev/null +++ b/client/coral-framework/components/Markdown.js @@ -0,0 +1,23 @@ +import React, {PureComponent, PropTypes} from 'react'; +import marked from 'marked'; + +const renderer = new marked.Renderer(); + +// Set link target to `_parent` to work properly in an embed. +renderer.link = (href, title, text) => + `${text}`; + +marked.setOptions({renderer}); + +export default class Markdown extends PureComponent { + render() { + const {content, ...rest} = this.props; + const __html = marked(content); + return
; + } +} + +Markdown.propTypes = { + content: PropTypes.string, +}; + diff --git a/client/coral-admin/src/components/MarkdownEditor.css b/client/coral-framework/components/MarkdownEditor.css similarity index 99% rename from client/coral-admin/src/components/MarkdownEditor.css rename to client/coral-framework/components/MarkdownEditor.css index 93bf7a9dd..201ba10bc 100644 --- a/client/coral-admin/src/components/MarkdownEditor.css +++ b/client/coral-framework/components/MarkdownEditor.css @@ -467,7 +467,6 @@ $fullscreenZIndex: 10; text-align: center; text-decoration: none!important; color: #2c3e50!important; - width: 30px; height: 30px; margin: 0; border: 1px solid transparent; @@ -475,6 +474,8 @@ $fullscreenZIndex: 10; cursor: pointer; outline: 0; margin-right: 2px; + font-size: 1.5em; + width: 25px; &.active { background: #fcfcfc; border-color: #95a5a6; diff --git a/client/coral-admin/src/components/MarkdownEditor.js b/client/coral-framework/components/MarkdownEditor.js similarity index 100% rename from client/coral-admin/src/components/MarkdownEditor.js rename to client/coral-framework/components/MarkdownEditor.js diff --git a/client/talk-plugin-infobox/InfoBox.js b/client/talk-plugin-infobox/InfoBox.js index 3b9d7da75..658f4ffcc 100644 --- a/client/talk-plugin-infobox/InfoBox.js +++ b/client/talk-plugin-infobox/InfoBox.js @@ -1,5 +1,5 @@ import React from 'react'; -import Markdown from './Markdown'; +import Markdown from 'coral-framework/components/Markdown'; const packagename = 'talk-plugin-infobox'; diff --git a/client/talk-plugin-questionbox/QuestionBox.css b/client/talk-plugin-questionbox/QuestionBox.css new file mode 100644 index 000000000..cb9902ade --- /dev/null +++ b/client/talk-plugin-questionbox/QuestionBox.css @@ -0,0 +1,70 @@ +.qbInfo { + top: 0; + border: 0; + background: #F0F0F0; + color: black; + width: 100%; + text-align: left; + padding-left: 0px; + margin-bottom: 0px; + font-weight: bold; + font-size: 14px; + overflow: hidden; + min-height: 50px; + display: flex; + border-radius: 3px; +} + +.icon { + z-index: 2; + top: 12px; + left: 12px; + position: absolute; + font-size: 33px; + color: #262626; +} + +.iconBubble{ + position: absolute; + top: 8px; + left: 10px; + color: #9E9E9E; + font-size: 24px; + z-index: 0; +} + +.iconPerson{ + z-index: 2; + top: 12px; + left: 12px; + position: absolute; + font-size: 33px; + color: #262626; +} + +.qbIconContainer { + position: relative; + border: 0; + color: white; + padding: 20px; + margin-left: 0px !important; + margin-right: 10px; + display: inline-block; + width: 10px; + min-height: 100%; + padding: 5px 20px; + vertical-align: middle; +} + +.qbContent { + padding: 5px; + display: flex; + align-items: center; + justify-content: center; + font-weight: 400; +} + +.hidden { + visibility: hidden; + display: none; +} \ No newline at end of file diff --git a/client/talk-plugin-questionbox/QuestionBox.js b/client/talk-plugin-questionbox/QuestionBox.js index d22801bae..f15549b7c 100644 --- a/client/talk-plugin-questionbox/QuestionBox.js +++ b/client/talk-plugin-questionbox/QuestionBox.js @@ -1,17 +1,31 @@ import React from 'react'; -const packagename = 'talk-plugin-questionbox'; +import cn from 'classnames'; +import styles from './QuestionBox.css'; +import {Icon} from 'coral-ui'; +import Markdown from 'coral-framework/components/Markdown'; + import Slot from 'coral-framework/components/Slot'; -const QuestionBox = ({enable, content}) => -
-
- chat_bubble - person +const QuestionBox = ({content, enable, icon = '', className = ''}) => ( +
+ { + icon === 'default' ? ( +
+ + +
+ ) : ( +
+ +
+ ) + } +
+ +
+ +
-
- {content} -
- -
; +); export default QuestionBox; diff --git a/graph/typeDefs.graphql b/graph/typeDefs.graphql index 0e430cd84..9d1376372 100644 --- a/graph/typeDefs.graphql +++ b/graph/typeDefs.graphql @@ -545,6 +545,7 @@ type Settings { premodLinksEnable: Boolean questionBoxEnable: Boolean questionBoxContent: String + questionBoxIcon: String closeTimeout: Int closedMessage: String charCountEnable: Boolean diff --git a/models/setting.js b/models/setting.js index ca8dfa456..222541df6 100644 --- a/models/setting.js +++ b/models/setting.js @@ -33,6 +33,10 @@ const SettingSchema = new Schema({ type: Boolean, default: false }, + questionBoxIcon: { + type: String, + default: 'default' + }, questionBoxContent: { type: String, default: '' diff --git a/package.json b/package.json index 4402a797a..1dfb6987b 100644 --- a/package.json +++ b/package.json @@ -144,6 +144,7 @@ "babel-jest": "^19.0.0", "babel-loader": "^6.4.1", "babel-plugin-add-module-exports": "^0.2.1", + "babel-plugin-syntax-dynamic-import": "^6.18.0", "babel-plugin-transform-async-to-generator": "^6.16.0", "babel-plugin-transform-class-properties": "^6.23.0", "babel-plugin-transform-decorators-legacy": "^1.3.4",