diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js index 5fc1673a1..1c52fb68c 100644 --- a/client/coral-embed-stream/src/Embed.js +++ b/client/coral-embed-stream/src/Embed.js @@ -16,7 +16,7 @@ import {queryStream} from 'coral-framework/graphql/queries'; import {postComment, postFlag, postLike, postDontAgree, deleteAction, addCommentTag, removeCommentTag} from 'coral-framework/graphql/mutations'; import {editName} from 'coral-framework/actions/user'; import {updateCountCache} from 'coral-framework/actions/asset'; -import {Notification, notificationActions, authActions, assetActions, pym} from 'coral-framework'; +import {notificationActions, authActions, assetActions, pym} from 'coral-framework'; import Stream from './Stream'; import InfoBox from 'coral-plugin-infobox/InfoBox'; @@ -176,7 +176,7 @@ class Embed extends Component { refetch={refetch} setActiveReplyBox={this.setActiveReplyBox} activeReplyBox={this.state.activeReplyBox} - addNotification={addNotification} + addNotification={this.props.addNotification} depth={0} postItem={this.props.postItem} asset={asset} @@ -220,11 +220,6 @@ class Embed extends Component { showSignInDialog={this.props.showSignInDialog} comments={asset.comments} /> - - ); @@ -258,7 +248,6 @@ class Embed extends Component { } const mapStateToProps = state => ({ - notification: state.notification.toJS(), auth: state.auth.toJS(), userData: state.user.toJS(), asset: state.asset.toJS() @@ -267,13 +256,7 @@ const mapStateToProps = state => ({ const mapDispatchToProps = dispatch => ({ requestConfirmEmail: () => dispatch(requestConfirmEmail()), loadAsset: (asset) => dispatch(fetchAssetSuccess(asset)), - addNotification: (type, text) => { - pym.sendMessage('getPosition'); - - pym.onMessage('position', position => { - dispatch(addNotification(type, text, position)); - }); - }, + addNotification: (type, text) => dispatch(addNotification(type, text)), clearNotification: () => dispatch(clearNotification()), editName: (username) => dispatch(editName(username)), showSignInDialog: (offset) => dispatch(showSignInDialog(offset)), diff --git a/client/coral-embed-stream/style/default.css b/client/coral-embed-stream/style/default.css index 009246963..68bac3110 100644 --- a/client/coral-embed-stream/style/default.css +++ b/client/coral-embed-stream/style/default.css @@ -1,10 +1,16 @@ +* { + font-weight: inherit; + font-family: inherit; + font-style: inherit; + font-size: 100%; +} + html, body { width:auto; height:auto; } body { - font-family: 'Open Sans', sans-serif; font-family: 'Lato', sans-serif; width: 100%; font-size: 14px; @@ -81,6 +87,15 @@ hr { margin-bottom: 10px; display: block; box-sizing: border-box; + border-radius: 2px; +} + + +.commentStream .material-icons { + vertical-align: middle; + width: 1em; + font-size: 1em; + overflow: hidden; } /* Question Box Styles */ @@ -96,15 +111,41 @@ hr { font-weight: bold; font-size: 14px; display: block; + overflow: hidden; + height: 50px; } -.coral-plugin-questionbox-icon { +.coral-plugin-questionbox-icon.bubble{ + position: absolute; + top: 11px; + left: 15px; + color: #949393; + font-size: 20px; + z-index: 0; +} + +.coral-plugin-questionbox-icon.person{ + z-index: 2; + top: 20px; + left: 20px; + position: absolute; + font-size: 24px; + color: white; +} + +.coral-plugin-questionbox-box { + position: relative; border: 0; background: black; color: white; padding: 20px; margin-left: 0px !important; margin-right: 10px; + display: inline-block; + width: 15px; + height: 100%; + padding: 3px 20px; + vertical-align: middle; } .hidden { @@ -128,6 +169,8 @@ hr { flex: 1; padding: 5px; min-height: 100px; + margin-top: 10px; + font-size: 14px; } .coral-plugin-commentbox-button-container { @@ -238,13 +281,6 @@ button.comment__action-button[disabled], white-space: nowrap; } -.commentStream .material-icons { - vertical-align: middle; - width: 1em; - font-size: 1em; - overflow: hidden; -} - .likedButton { color: rgb(0,134,227); } @@ -324,14 +360,14 @@ button.comment__action-button[disabled], } .coral-plugin-flags-popup-counter { - float: left; - margin-top: 21px; - color: #999; + float: left; + margin-top: 21px; + color: #999; } .coral-plugin-flags-popup-button { - float: right; - margin-top: 10px; + float: right; + margin-top: 10px; } .coral-plugin-flags-reason-text { @@ -387,6 +423,8 @@ button.coral-load-more { color: #FFF; background-color: #2376D8; cursor: pointer; + padding: 10px; + border-radius: 2px; } button.coral-load-more:hover { diff --git a/client/coral-embed/src/index.js b/client/coral-embed/src/index.js index 8d8855aa7..db4cbf37e 100644 --- a/client/coral-embed/src/index.js +++ b/client/coral-embed/src/index.js @@ -1,5 +1,26 @@ import pym from 'pym.js'; +const snackbarStyles = { + position: 'fixed', + cursor: 'default', + userSelect: 'none', + backgroundColor: '#323232', + zIndex: 3, + willChange: 'transform, opacity', + transition: 'transform .35s cubic-bezier(.55,0,.1,1), opacity .35s', + pointerEvents: 'none', + padding: '12px 18px', + color: '#fff', + borderRadius: '3px 3px 0 0', + textAlign: 'center', + maxWidth: '300px', + left: '50%', + opacity: 0, + transform: 'translate(-50%, 20px)', + bottom: 0, + boxSizing: 'border-box' +}; + // This function should return value of window.Coral const Coral = {}; const Talk = Coral.Talk = {}; @@ -32,6 +53,14 @@ function configurePymParent(pymParent, asset_url) { let notificationOffset = 200; let ready = false; let cachedHeight; + const snackbar = document.createElement('div'); + snackbar.id = 'coral-notif'; + + for (let key in snackbarStyles) { + snackbar.style[key] = snackbarStyles[key]; + } + + window.document.body.appendChild(snackbar); // Resize parent iframe height when child height changes pymParent.onMessage('height', function(height) { @@ -41,6 +70,27 @@ function configurePymParent(pymParent, asset_url) { } }); + pymParent.onMessage('coral-clear-notification', function () { + snackbar.style.opacity = 0; + }); + + pymParent.onMessage('coral-alert', function (message) { + const [type, text] = message.split('|'); + snackbar.style.transform = 'translate(-50%, 20px)'; + snackbar.style.opacity = 0; + snackbar.className = `coral-notif-${type}`; + snackbar.textContent = text; + + setTimeout(() => { + snackbar.style.transform = 'translate(-50%, 0)'; + snackbar.style.opacity = 1; + }, 0); + + setTimeout(() => { + snackbar.style.opacity = 0; + }, 5000); + }); + // Helps child show notifications at the right scrollTop pymParent.onMessage('getPosition', function() { let position = viewport().height + document.body.scrollTop; diff --git a/client/coral-framework/actions/notification.js b/client/coral-framework/actions/notification.js index f0ac4d951..f2cc053ec 100644 --- a/client/coral-framework/actions/notification.js +++ b/client/coral-framework/actions/notification.js @@ -1,17 +1,9 @@ -export const ADD_NOTIFICATION = 'ADD_NOTIFICATION'; -export const CLEAR_NOTIFICATION = 'CLEAR_NOTIFICATION'; +import {pym} from 'coral-framework'; -export const addNotification = (notifType, text, position) => { - return { - type: ADD_NOTIFICATION, - notifType, - text, - position - }; +export const addNotification = (notifType, text) => { + pym.sendMessage('coral-alert', `${notifType}|${text}`); }; export const clearNotification = () => { - return { - type: CLEAR_NOTIFICATION - }; + pym.sendMessage('coral-clear-notification'); }; diff --git a/client/coral-framework/index.js b/client/coral-framework/index.js index 56a2e522c..2900466ee 100644 --- a/client/coral-framework/index.js +++ b/client/coral-framework/index.js @@ -4,7 +4,6 @@ import I18n from './modules/i18n/i18n'; import * as authActions from './actions/auth'; import * as assetActions from './actions/asset'; import * as notificationActions from './actions/notification'; -import Notification from './modules/notification/Notification'; export { pym, @@ -12,6 +11,5 @@ export { store, authActions, assetActions, - Notification, notificationActions }; diff --git a/client/coral-framework/modules/notification/Notification.js b/client/coral-framework/modules/notification/Notification.js deleted file mode 100644 index 709403976..000000000 --- a/client/coral-framework/modules/notification/Notification.js +++ /dev/null @@ -1,22 +0,0 @@ -import React from 'react'; -import {SnackBar} from 'coral-ui'; - -const Notification = (props) => { - if (props.notification.text) { - setTimeout(() => { - props.clearNotification(); - }, props.notifLength); - } - return ( -
- { - props.notification.text && - - {props.notification.text} - - } -
- ); -}; - -export default Notification; diff --git a/client/coral-framework/reducers/index.js b/client/coral-framework/reducers/index.js index 720f15232..9e98c901a 100644 --- a/client/coral-framework/reducers/index.js +++ b/client/coral-framework/reducers/index.js @@ -1,11 +1,9 @@ import auth from './auth'; import user from './user'; import asset from './asset'; -import notification from './notification'; export default { auth, user, asset, - notification }; diff --git a/client/coral-framework/reducers/notification.js b/client/coral-framework/reducers/notification.js deleted file mode 100644 index fbc58230f..000000000 --- a/client/coral-framework/reducers/notification.js +++ /dev/null @@ -1,24 +0,0 @@ -import * as actions from '../actions/notification'; -import {Map} from 'immutable'; - -const initialState = Map({ - text: '', - type: '', - position: 400 -}); - -export default (state = initialState, action) => { - switch (action.type) { - case actions.ADD_NOTIFICATION: - return state - .merge({ - type: action.notifType, - text: action.text, - position: action.position - }); - case actions.CLEAR_NOTIFICATION: - return initialState; - default: - return state; - } -}; diff --git a/client/coral-plugin-commentbox/translations.json b/client/coral-plugin-commentbox/translations.json index 83ed974e4..0f77fc334 100644 --- a/client/coral-plugin-commentbox/translations.json +++ b/client/coral-plugin-commentbox/translations.json @@ -3,7 +3,7 @@ "post": "Post", "cancel": "Cancel", "reply": "Reply", - "comment": "Comment", + "comment": "Post a Comment", "name": "Name", "comment-post-notif": "Your comment has been posted.", "comment-post-notif-premod": "Thank you for posting. Our moderation team will review your comment shortly.", @@ -14,7 +14,7 @@ "post": "Publicar", "cancel": "Cancelar", "reply": "Respuesta", - "comment": "Comentario", + "comment": "Escribe un Comentario", "name": "Nombre", "comment-post-notif": "Tu comentario ha sido publicado.", "comment-post-notif-premod": "Gracias por comentar. Nuestro equipo de moderación va a revisarlo muy pronto.", diff --git a/client/coral-plugin-questionbox/QuestionBox.js b/client/coral-plugin-questionbox/QuestionBox.js index 542cb8790..3c2410d44 100644 --- a/client/coral-plugin-questionbox/QuestionBox.js +++ b/client/coral-plugin-questionbox/QuestionBox.js @@ -2,9 +2,11 @@ import React from 'react'; const packagename = 'coral-plugin-questionbox'; const QuestionBox = ({enable, content}) => -
- chat_bubble person +
+
+ chat_bubble + person +
{content}
; diff --git a/client/coral-plugin-replies/ReplyBox.js b/client/coral-plugin-replies/ReplyBox.js index c50bca124..807ad6699 100644 --- a/client/coral-plugin-replies/ReplyBox.js +++ b/client/coral-plugin-replies/ReplyBox.js @@ -1,21 +1,29 @@ -import React, {PropTypes} from 'react'; +import React, {Component, PropTypes} from 'react'; import CommentBox from '../coral-plugin-commentbox/CommentBox'; const name = 'coral-plugin-replies'; -const ReplyBox = ({styles, postItem, assetId, authorId, addNotification, parentId, commentPostedHandler, setActiveReplyBox}) => ( -
- -
-); +class ReplyBox extends Component { + + componentDidMount() { + document.getElementById('replyText').focus(); + } + + render() { + const {styles, postItem, assetId, authorId, addNotification, parentId, commentPostedHandler, setActiveReplyBox} = this.props; + return
+ +
; + } +} ReplyBox.propTypes = { setActiveReplyBox: PropTypes.func.isRequired, diff --git a/client/coral-ui/components/Button.css b/client/coral-ui/components/Button.css index 9a2611630..14ed64aa2 100644 --- a/client/coral-ui/components/Button.css +++ b/client/coral-ui/components/Button.css @@ -9,7 +9,7 @@ min-width: 64px; padding: 0 8px; display: inline-block; - font-family: 'Roboto','Helvetica','Arial',sans-serif; + font-family: inherit; font-size: 14px; overflow: hidden; will-change: box-shadow,transform; diff --git a/test/client/coral-framework/reducers/notificationReducer.spec.js b/test/client/coral-framework/reducers/notificationReducer.spec.js deleted file mode 100644 index 40c50d11a..000000000 --- a/test/client/coral-framework/reducers/notificationReducer.spec.js +++ /dev/null @@ -1,35 +0,0 @@ -import {Map} from 'immutable'; -import {expect} from 'chai'; -import notificationReducer from '../../../../client/coral-framework/reducers/notification'; -import * as actions from '../../../../client/coral-framework/actions/notification'; - -describe ('notificationsReducer', () => { - describe('ADD_NOTIFICATION', () => { - it('should add a notification', () => { - const action = { - type: actions.ADD_NOTIFICATION, - text: 'Test notification', - notifType: 'test' - }; - const store = new Map({}); - const result = notificationReducer(store, action); - expect(result.get('text')).to.equal(action.text); - expect(result.get('type')).to.equal(action.notifType); - }); - }); - - describe('CLEAR_NOTIFICATION', () => { - it('should clear a notification', () => { - const action = { - type: actions.CLEAR_NOTIFICATION - }; - const store = new Map({ - text: 'Test notification', - type: 'test' - }); - const result = notificationReducer(store, action); - expect(result.get('text')).to.equal(''); - expect(result.get('type')).to.equal(''); - }); - }); -}); diff --git a/test/client/coral-framework/store/notificationReducer.spec.js b/test/client/coral-framework/store/notificationReducer.spec.js deleted file mode 100644 index 40c50d11a..000000000 --- a/test/client/coral-framework/store/notificationReducer.spec.js +++ /dev/null @@ -1,35 +0,0 @@ -import {Map} from 'immutable'; -import {expect} from 'chai'; -import notificationReducer from '../../../../client/coral-framework/reducers/notification'; -import * as actions from '../../../../client/coral-framework/actions/notification'; - -describe ('notificationsReducer', () => { - describe('ADD_NOTIFICATION', () => { - it('should add a notification', () => { - const action = { - type: actions.ADD_NOTIFICATION, - text: 'Test notification', - notifType: 'test' - }; - const store = new Map({}); - const result = notificationReducer(store, action); - expect(result.get('text')).to.equal(action.text); - expect(result.get('type')).to.equal(action.notifType); - }); - }); - - describe('CLEAR_NOTIFICATION', () => { - it('should clear a notification', () => { - const action = { - type: actions.CLEAR_NOTIFICATION - }; - const store = new Map({ - text: 'Test notification', - type: 'test' - }); - const result = notificationReducer(store, action); - expect(result.get('text')).to.equal(''); - expect(result.get('type')).to.equal(''); - }); - }); -});