diff --git a/.eslintignore b/.eslintignore
index 6cb6a3bc3..1521c8b76 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -1,2 +1 @@
-client
dist
diff --git a/client/.eslintrc.json b/client/.eslintrc.json
new file mode 100644
index 000000000..a935eaec6
--- /dev/null
+++ b/client/.eslintrc.json
@@ -0,0 +1,23 @@
+{
+ "env": {
+ "browser": true,
+ "es6": true,
+ "mocha": true
+ },
+ "extends": "../.eslintrc.json",
+ "parserOptions": {
+ "ecmaFeatures": {
+ "experimentalObjectRestSpread": true,
+ "jsx": true
+ },
+ "sourceType": "module"
+ },
+ "parser": "babel-eslint",
+ "plugins": [
+ "react"
+ ],
+ "rules": {
+ "react/jsx-uses-react": "error",
+ "react/jsx-uses-vars": "error"
+ }
+}
diff --git a/client/coral-admin/src/AppRouter.js b/client/coral-admin/src/AppRouter.js
index 40465bd19..d00caa6c5 100644
--- a/client/coral-admin/src/AppRouter.js
+++ b/client/coral-admin/src/AppRouter.js
@@ -1,12 +1,12 @@
-import React from 'react'
-import { Router, Route, Redirect, IndexRoute, browserHistory } from 'react-router'
+import React from 'react';
+import {Router, Route, IndexRoute, browserHistory} from 'react-router';
-import ModerationQueue from 'containers/ModerationQueue'
-import CommentStream from 'containers/CommentStream'
-import EmbedLink from 'components/EmbedLink'
-import Configure from 'containers/Configure'
-import CommunityContainer from 'containers/CommunityContainer'
-import LayoutContainer from 'containers/LayoutContainer'
+import ModerationQueue from 'containers/ModerationQueue';
+import CommentStream from 'containers/CommentStream';
+import EmbedLink from 'components/EmbedLink';
+import Configure from 'containers/Configure';
+import CommunityContainer from 'containers/CommunityContainer';
+import LayoutContainer from 'containers/LayoutContainer';
const routes = (
@@ -16,8 +16,8 @@ const routes = (
-)
+);
-const AppRouter = () =>
+const AppRouter = () => ;
-export default AppRouter
+export default AppRouter;
diff --git a/client/coral-admin/src/actions/comments.js b/client/coral-admin/src/actions/comments.js
index 04751276e..e4a55a893 100644
--- a/client/coral-admin/src/actions/comments.js
+++ b/client/coral-admin/src/actions/comments.js
@@ -4,15 +4,15 @@
*/
export const updateStatus = (status, id) => (dispatch, getState) => {
- dispatch({ type: 'COMMENT_STATUS_UPDATE', id, status })
- dispatch({ type: 'COMMENT_UPDATE', comment: getState().comments.get('byId').get(id) })
-}
+ dispatch({type: 'COMMENT_STATUS_UPDATE', id, status});
+ dispatch({type: 'COMMENT_UPDATE', comment: getState().comments.get('byId').get(id)});
+};
export const flagComment = id => (dispatch, getState) => {
- dispatch({ type: 'COMMENT_FLAG', id })
- dispatch({ type: 'COMMENT_UPDATE', comment: getState().comments.get('byId').get(id) })
-}
+ dispatch({type: 'COMMENT_FLAG', id});
+ dispatch({type: 'COMMENT_UPDATE', comment: getState().comments.get('byId').get(id)});
+};
export const createComment = (name, body) => dispatch => {
- dispatch({ type: 'COMMENT_CREATE', name, body })
-}
+ dispatch({type: 'COMMENT_CREATE', name, body});
+};
diff --git a/client/coral-admin/src/components/App.js b/client/coral-admin/src/components/App.js
index 1fbbe1448..3c6e88a14 100644
--- a/client/coral-admin/src/components/App.js
+++ b/client/coral-admin/src/components/App.js
@@ -1,17 +1,16 @@
-import React from 'react'
-import { Provider } from 'react-redux'
-import 'material-design-lite'
-import { Layout } from 'react-mdl'
-import store from 'services/store'
+import React from 'react';
+import {Provider} from 'react-redux';
+import 'material-design-lite';
+import store from 'services/store';
-import AppRouter from '../AppRouter'
+import AppRouter from '../AppRouter';
export default class App extends React.Component {
- render (props) {
+ render () {
return (
- )
+ );
}
}
diff --git a/client/coral-admin/src/components/Comment.js b/client/coral-admin/src/components/Comment.js
index 7406d42db..da08945a9 100644
--- a/client/coral-admin/src/components/Comment.js
+++ b/client/coral-admin/src/components/Comment.js
@@ -1,10 +1,10 @@
-import React from 'react'
-import { Button, Icon } from 'react-mdl'
-import timeago from 'timeago.js'
-import styles from './CommentList.css'
-import I18n from 'coral-framework/i18n/i18n'
-import translations from '../translations'
+import React from 'react';
+import {Button, Icon} from 'react-mdl';
+import timeago from 'timeago.js';
+import styles from './CommentList.css';
+import I18n from 'coral-framework/i18n/i18n';
+import translations from '../translations';
// Render a single comment for the list
export default props => (
@@ -30,17 +30,17 @@ export default props => (
{props.comment.get('body')}
-)
+);
// Check if an action can be performed over a comment
const canShowAction = (action, comment) => {
- const status = comment.get('status')
- const flagged = comment.get('flagged')
+ const status = comment.get('status');
+ const flagged = comment.get('flagged');
if (action === 'flag' && (status || flagged === true)) {
- return false
+ return false;
}
- return true
-}
+ return true;
+};
-const lang = new I18n(translations)
+const lang = new I18n(translations);
diff --git a/client/coral-admin/src/components/CommentBox.js b/client/coral-admin/src/components/CommentBox.js
index f0f0adbf2..ce3438960 100644
--- a/client/coral-admin/src/components/CommentBox.js
+++ b/client/coral-admin/src/components/CommentBox.js
@@ -1,23 +1,23 @@
-import React from 'react'
-import styles from './CommentBox.css'
-import { Button } from 'react-mdl'
+import React from 'react';
+import styles from './CommentBox.css';
+import {Button} from 'react-mdl';
// Renders a comment box for creating a new comment
export default class CommentBox extends React.Component {
constructor (props) {
- super(props)
- this.state = { name: '', body: '' }
- this.onSubmit = this.onSubmit.bind(this)
+ super(props);
+ this.state = {name: '', body: ''};
+ this.onSubmit = this.onSubmit.bind(this);
}
onSubmit () {
- const { name, body } = this.state
- this.props.onSubmit({ name, body })
- this.setState({ body: '', name: '' })
+ const {name, body} = this.state;
+ this.props.onSubmit({name, body});
+ this.setState({body: '', name: ''});
}
- render (props, { name, body }) {
+ render (props, {name, body}) {
return (
@@ -30,6 +30,6 @@ export default class CommentBox extends React.Component {
- )
+ );
}
}
diff --git a/client/coral-admin/src/components/CommentList.js b/client/coral-admin/src/components/CommentList.js
index 02367911f..ae74272e7 100644
--- a/client/coral-admin/src/components/CommentList.js
+++ b/client/coral-admin/src/components/CommentList.js
@@ -1,99 +1,99 @@
-import React from 'react'
-import styles from './CommentList.css'
-import key from 'keymaster'
-import Hammer from 'hammerjs'
-import Comment from 'components/Comment'
+import React from 'react';
+import styles from './CommentList.css';
+import key from 'keymaster';
+import Hammer from 'hammerjs';
+import Comment from 'components/Comment';
// Each action has different meaning and configuration
const actions = {
- 'reject': { status: 'Rejected', icon: 'close', key: 'r' },
- 'approve': { status: 'Approved', icon: 'done', key: 't' },
- 'flag': { status: 'flagged', icon: 'flag', filter: 'Untouched' }
-}
+ 'reject': {status: 'Rejected', icon: 'close', key: 'r'},
+ 'approve': {status: 'Approved', icon: 'done', key: 't'},
+ 'flag': {status: 'flagged', icon: 'flag', filter: 'Untouched'}
+};
// Renders a comment list and allow performing actions
export default class CommentList extends React.Component {
constructor (props) {
- super(props)
+ super(props);
- this.state = { active: null }
- this.onClickAction = this.onClickAction.bind(this)
+ this.state = {active: null};
+ this.onClickAction = this.onClickAction.bind(this);
}
// remove key handlers before leaving
componentWillUnmount () {
- this.unbindKeyHandlers()
+ this.unbindKeyHandlers();
}
// add key handlers and gestures
componentDidMount () {
- this.bindKeyHandlers()
+ this.bindKeyHandlers();
// this.bindGestures() // need to check whether we're on a mobile device or this throws an Error
}
// If entering to singleview and no active, active is the first eleement
componentWillReceiveProps (nextProps) {
if (nextProps.singleView && !this.state.active) {
- this.setState({ active: nextProps.commentIds.get(0) })
+ this.setState({active: nextProps.commentIds.get(0)});
}
}
// Add swipe to approve or reject
bindGestures () {
- const { actions } = this.props
- this._hammer = new Hammer(this.base)
- this._hammer.get('swipe').set({ direction: Hammer.DIRECTION_HORIZONTAL })
+ const {actions} = this.props;
+ this._hammer = new Hammer(this.base);
+ this._hammer.get('swipe').set({direction: Hammer.DIRECTION_HORIZONTAL});
if (actions.indexOf('reject') !== -1) {
- this._hammer.on('swipeleft', () => this.props.singleView && this.actionKeyHandler('Rejected'))
+ this._hammer.on('swipeleft', () => this.props.singleView && this.actionKeyHandler('Rejected'));
}
if (actions.indexOf('approve') !== -1) {
- this._hammer.on('swiperight', () => this.props.singleView && this.actionKeyHandler('Approved'))
+ this._hammer.on('swiperight', () => this.props.singleView && this.actionKeyHandler('Approved'));
}
}
// Add key handlers. Each action has one and added j/k for moving around
bindKeyHandlers () {
this.props.actions.filter(action => actions[action].key).forEach(action => {
- key(actions[action].key, 'commentList', () => this.props.isActive && this.actionKeyHandler(actions[action].status))
- })
- key('j', 'commentList', () => this.props.isActive && this.moveKeyHandler('down'))
- key('k', 'commentList', () => this.props.isActive && this.moveKeyHandler('up'))
- key.setScope('commentList')
+ key(actions[action].key, 'commentList', () => this.props.isActive && this.actionKeyHandler(actions[action].status));
+ });
+ key('j', 'commentList', () => this.props.isActive && this.moveKeyHandler('down'));
+ key('k', 'commentList', () => this.props.isActive && this.moveKeyHandler('up'));
+ key.setScope('commentList');
}
// Perform an action using the keys only if the comment is active
actionKeyHandler (action) {
if (this.props.isActive && this.state.active) {
- this.onClickAction(action, this.state.active)
+ this.onClickAction(action, this.state.active);
}
}
// move around with j/k
moveKeyHandler (direction) {
if (!this.props.isActive) {
- return
+ return;
}
- const { commentIds } = this.props
- const { active } = this.state
+ const {commentIds} = this.props;
+ const {active} = this.state;
// check boundaries
- if (active == null || !commentIds.size) {
- this.setState({ active: commentIds.get(0) })
+ if (active === null || !commentIds.size) {
+ this.setState({active: commentIds.get(0)});
} else if (direction === 'up' && active !== commentIds.first()) {
- this.setState({ active: commentIds.get(commentIds.indexOf(active) - 1) })
+ this.setState({active: commentIds.get(commentIds.indexOf(active) - 1)});
} else if (direction === 'down' && active !== commentIds.last()) {
- this.setState({ active: commentIds.get(commentIds.indexOf(active) + 1) })
+ this.setState({active: commentIds.get(commentIds.indexOf(active) + 1)});
}
// scroll to the position
- const index = Math.max(commentIds.indexOf(this.state.active), 0)
- this.base.childNodes[index] && this.base.childNodes[index].focus()
+ const index = Math.max(commentIds.indexOf(this.state.active), 0);
+ this.base.childNodes[index] && this.base.childNodes[index].focus();
}
unbindKeyHandlers () {
- key.deleteScope('commentList')
+ key.deleteScope('commentList');
}
// If we are performing an action over a comment (aka removing from the list) we need to select a new active.
@@ -101,26 +101,26 @@ export default class CommentList extends React.Component {
// resolve since the content of the list could change externally. For now it works as expected
onClickAction (action, id) {
if (id === this.state.active) {
- const { commentIds } = this.props
+ const {commentIds} = this.props;
if (commentIds.last() === this.state.active) {
- this.setState({ active: commentIds.get(commentIds.size - 2) })
+ this.setState({active: commentIds.get(commentIds.size - 2)});
} else {
- this.setState({ active: commentIds.get(Math.min(commentIds.indexOf(this.state.active) + 1, commentIds.size - 1)) })
+ this.setState({active: commentIds.get(Math.min(commentIds.indexOf(this.state.active) + 1, commentIds.size - 1))});
}
}
- this.props.onClickAction(action, id)
+ this.props.onClickAction(action, id);
}
render () {
- const {singleView, commentIds, comments, hideActive} = this.props
- const {active} = this.state
+ const {singleView, commentIds, comments, hideActive} = this.props;
+ const {active} = this.state;
return (
{commentIds.map((commentId, index) => (
{ if (el && commentId === active) { this._active = el } }}
- key={index + 'comment'}
+ ref={el => { if (el && commentId === active) { this._active = el; } }}
+ key={`${index }comment`}
index={index}
onClickAction={this.onClickAction}
actions={this.props.actions}
@@ -129,6 +129,6 @@ export default class CommentList extends React.Component {
hideActive={hideActive} />
)).toArray()}
- )
+ );
}
}
diff --git a/client/coral-admin/src/components/EmbedLink.js b/client/coral-admin/src/components/EmbedLink.js
index 21fe52f3f..41cbdf170 100644
--- a/client/coral-admin/src/components/EmbedLink.js
+++ b/client/coral-admin/src/components/EmbedLink.js
@@ -1,22 +1,22 @@
-import React from 'react'
-import styles from './EmbedLink.css'
-import I18n from 'coral-framework/i18n/i18n'
-import translations from '../translations'
-import { Button } from 'react-mdl'
+import React from 'react';
+import styles from './EmbedLink.css';
+import I18n from 'coral-framework/i18n/i18n';
+import translations from '../translations';
+import {Button} from 'react-mdl';
const embedText =
-``
+``;
-const copyToClipBoard = event => {
- const copyTextarea = document.querySelector('.' + styles.embedTextarea)
- copyTextarea.select()
+const copyToClipBoard = () => {
+ const copyTextarea = document.querySelector(`.${ styles.embedTextarea}`);
+ copyTextarea.select();
try {
- document.execCommand('copy')
+ document.execCommand('copy');
} catch (err) {
- console.error('Unable to copy')
+ console.error('Unable to copy');
}
-}
+};
const EmbedLink = () =>
Embed Comment Stream
@@ -30,8 +30,8 @@ const EmbedLink = () =>
{lang.t('embedlink.copy')}
-
+;
-export default EmbedLink
+export default EmbedLink;
-const lang = new I18n(translations)
+const lang = new I18n(translations);
diff --git a/client/coral-admin/src/components/Header.js b/client/coral-admin/src/components/Header.js
new file mode 100644
index 000000000..1a89da513
--- /dev/null
+++ b/client/coral-admin/src/components/Header.js
@@ -0,0 +1,23 @@
+import React from 'react';
+import {Layout, Navigation, Drawer, Header} from 'react-mdl';
+import {Link} from 'react-router';
+import styles from './Header.css';
+
+// App header. If we add a navbar it should be here
+export default (props) => (
+
+
+
+ Moderate
+ Configure
+
+
+
+
+ Moderate
+ Configure
+
+
+ {props.children}
+
+);
diff --git a/client/coral-admin/src/components/Modal.js b/client/coral-admin/src/components/Modal.js
index 44535eda7..99c27c3a1 100644
--- a/client/coral-admin/src/components/Modal.js
+++ b/client/coral-admin/src/components/Modal.js
@@ -1,13 +1,13 @@
-import React from 'react'
-import { Button, Icon } from 'react-mdl'
-import styles from './Modal.css'
+import React from 'react';
+import {Button, Icon} from 'react-mdl';
+import styles from './Modal.css';
-export default ({ open, children, onClose }) => (
+export default ({open, children, onClose}) => (
-)
+);
diff --git a/client/coral-admin/src/components/ModerationKeysModal.js b/client/coral-admin/src/components/ModerationKeysModal.js
index efe235df7..5cf9fe17e 100644
--- a/client/coral-admin/src/components/ModerationKeysModal.js
+++ b/client/coral-admin/src/components/ModerationKeysModal.js
@@ -1,9 +1,8 @@
-import I18n from 'coral-framework/i18n/i18n'
-import translations from '../translations'
-import React from 'react'
-import Modal from 'components/Modal'
-import styles from './ModerationKeysModal.css'
-import { Map } from 'immutable'
+import I18n from 'coral-framework/i18n/i18n';
+import translations from '../translations';
+import React from 'react';
+import Modal from 'components/Modal';
+import styles from './ModerationKeysModal.css';
const shortcuts = [
{
@@ -22,9 +21,9 @@ const shortcuts = [
'r': 'modqueue.reject'
}
}
-]
+];
-export default ({ open, onClose }) => (
+export default ({open, onClose}) => (
{lang.t('modqueue.shortcuts')}
@@ -37,7 +36,7 @@ export default ({ open, onClose }) => (
{Object.keys(shortcut.shortcuts).map(key => (
-
+
| {key} |
{lang.t(shortcut.shortcuts[key])} |
@@ -47,6 +46,6 @@ export default ({ open, onClose }) => (
))}
-)
+);
-const lang = new I18n(translations)
+const lang = new I18n(translations);
diff --git a/client/coral-admin/src/components/Page.js b/client/coral-admin/src/components/Page.js
new file mode 100644
index 000000000..845c10cb8
--- /dev/null
+++ b/client/coral-admin/src/components/Page.js
@@ -0,0 +1,12 @@
+import React from 'react';
+import {Layout} from 'react-mdl';
+import 'material-design-lite';
+import Header from 'components/Header';
+
+export default (props) => (
+
+
+
+);
diff --git a/client/coral-admin/src/components/ui/Drawer.js b/client/coral-admin/src/components/ui/Drawer.js
index b1c87baaf..9ea727911 100644
--- a/client/coral-admin/src/components/ui/Drawer.js
+++ b/client/coral-admin/src/components/ui/Drawer.js
@@ -1,7 +1,7 @@
-import React from 'react'
-import { Navigation, Drawer } from 'react-mdl'
-import { Link } from 'react-router'
-import styles from './Header.css'
+import React from 'react';
+import {Navigation, Drawer} from 'react-mdl';
+import {Link} from 'react-router';
+import styles from './Header.css';
export default () => (
@@ -11,4 +11,4 @@ export default () => (
Configure
-)
+);
diff --git a/client/coral-admin/src/components/ui/Header.js b/client/coral-admin/src/components/ui/Header.js
index 1455721d8..b7c654bd4 100644
--- a/client/coral-admin/src/components/ui/Header.js
+++ b/client/coral-admin/src/components/ui/Header.js
@@ -1,7 +1,7 @@
-import React from 'react'
-import { Navigation, Header } from 'react-mdl'
-import { Link } from 'react-router'
-import styles from './Header.css'
+import React from 'react';
+import {Navigation, Header} from 'react-mdl';
+import {Link} from 'react-router';
+import styles from './Header.css';
export default () => (
@@ -11,4 +11,4 @@ export default () => (
Configure
-)
+);
diff --git a/client/coral-admin/src/components/ui/Layout.js b/client/coral-admin/src/components/ui/Layout.js
index fd963b667..e80d55c30 100644
--- a/client/coral-admin/src/components/ui/Layout.js
+++ b/client/coral-admin/src/components/ui/Layout.js
@@ -1,12 +1,12 @@
-import React from 'react'
-import { Layout as LayoutMDL} from 'react-mdl'
-import Header from './Header'
-import Drawer from './Drawer'
+import React from 'react';
+import {Layout as LayoutMDL} from 'react-mdl';
+import Header from './Header';
+import Drawer from './Drawer';
-export const Layout = ({ children }) => (
+export const Layout = ({children}) => (
{children}
-)
\ No newline at end of file
+);
diff --git a/client/coral-admin/src/containers/CommentStream.js b/client/coral-admin/src/containers/CommentStream.js
index 33963f422..da4d03a22 100644
--- a/client/coral-admin/src/containers/CommentStream.js
+++ b/client/coral-admin/src/containers/CommentStream.js
@@ -1,11 +1,10 @@
-
-import React from 'react'
-import styles from './CommentStream.css'
-import { Snackbar } from 'react-mdl'
-import { connect } from 'react-redux'
-import { createComment, flagComment } from 'actions/comments'
-import CommentList from 'components/CommentList'
-import CommentBox from 'components/CommentBox'
+import React from 'react';
+import styles from './CommentStream.css';
+import {Snackbar} from 'react-mdl';
+import {connect} from 'react-redux';
+import {createComment, flagComment} from 'actions/comments';
+import CommentList from 'components/CommentList';
+import CommentBox from 'components/CommentBox';
/**
* Renders a comment stream using a CommentList component
@@ -14,34 +13,34 @@ import CommentBox from 'components/CommentBox'
class CommentStream extends React.Component {
constructor (props) {
- super(props)
- this.state = { snackbar: false, snackbarMsg: '' }
- this.onSubmit = this.onSubmit.bind(this)
- this.onClickAction = this.onClickAction.bind(this)
+ super(props);
+ this.state = {snackbar: false, snackbarMsg: ''};
+ this.onSubmit = this.onSubmit.bind(this);
+ this.onClickAction = this.onClickAction.bind(this);
}
// Fetch the comments before mounting
componentWillMount () {
- this.props.dispatch({ type: 'COMMENT_STREAM_FETCH' })
+ this.props.dispatch({type: 'COMMENT_STREAM_FETCH'});
}
// Submit the new comment
onSubmit (comment) {
- this.props.dispatch(createComment(comment.name, comment.body))
+ this.props.dispatch(createComment(comment.name, comment.body));
}
// The only action for now is flagging
onClickAction (action, id) {
if (action === 'flagged') {
- this.props.dispatch(flagComment(id))
- clearTimeout(this._snackTimeout)
- this.setState({ snackbar: true, snackbarMsg: 'Thank you for reporting this comment. Our moderation team has been notified and will review it shortly.' })
- this._snackTimeout = setTimeout(() => this.setState({ snackbar: false }), 30000)
+ this.props.dispatch(flagComment(id));
+ clearTimeout(this._snackTimeout);
+ this.setState({snackbar: true, snackbarMsg: 'Thank you for reporting this comment. Our moderation team has been notified and will review it shortly.'});
+ this._snackTimeout = setTimeout(() => this.setState({snackbar: false}), 30000);
}
}
// Render the comment box along with the CommentList
- render ({ comments }, { snackbar, snackbarMsg }) {
+ render ({comments}, {snackbar, snackbarMsg}) {
return (
@@ -54,8 +53,8 @@ class CommentStream extends React.Component {
loading={comments.loading} />
{snackbarMsg}
- )
+ );
}
}
-export default connect(({ comments }) => ({ comments }))(CommentStream)
+export default connect(({comments}) => ({comments}))(CommentStream);
diff --git a/client/coral-admin/src/containers/CommunityContainer.js b/client/coral-admin/src/containers/CommunityContainer.js
index bd13ca04b..b936edcec 100644
--- a/client/coral-admin/src/containers/CommunityContainer.js
+++ b/client/coral-admin/src/containers/CommunityContainer.js
@@ -1,7 +1,4 @@
-import React, { Component } from 'react'
-import { connect } from 'react-redux'
-import I18n from 'coral-framework/i18n/i18n'
-import translations from '../translations'
+import React, {Component} from 'react';
export default class CommunityContainer extends Component {
render() {
@@ -9,6 +6,6 @@ export default class CommunityContainer extends Component {
Community
- )
+ );
}
-}
\ No newline at end of file
+}
diff --git a/client/coral-admin/src/containers/Configure.css b/client/coral-admin/src/containers/Configure.css
index 2c65fd5bc..18f12cacd 100644
--- a/client/coral-admin/src/containers/Configure.css
+++ b/client/coral-admin/src/containers/Configure.css
@@ -25,10 +25,19 @@
.configSettingEmbed {
border: 1px solid #ccc;
border-radius: 4px;
- height: 90px;
margin-bottom: 10px;
display: block;
- height: 170px;
+}
+
+.copiedText {
+ color: #008000;
+ float: right;
+ padding: 12px;
+ font-size: 14px;
+}
+
+.copyButton {
+ float: right;
}
.embedInput {
@@ -40,6 +49,6 @@
margin-bottom: 10px;
color: #555;
padding: 14px;
- font-size: 16px;
+ font-size: 14px;
letter-spacing: 0.03em;
}
diff --git a/client/coral-admin/src/containers/Configure.js b/client/coral-admin/src/containers/Configure.js
index 5c86019c8..4c6253eaf 100644
--- a/client/coral-admin/src/containers/Configure.js
+++ b/client/coral-admin/src/containers/Configure.js
@@ -1,5 +1,5 @@
-import React from 'react'
-import {connect} from 'react-redux'
+import React from 'react';
+import {connect} from 'react-redux';
import {
List,
ListItem,
@@ -9,15 +9,16 @@ import {
Checkbox,
Button,
Icon
-} from 'react-mdl'
-import styles from './Configure.css'
-import I18n from 'coral-framework/i18n/i18n'
-import translations from '../translations'
+} from 'react-mdl';
+import styles from './Configure.css';
+import I18n from 'coral-framework/i18n/i18n';
+import translations from '../translations';
class Configure extends React.Component {
constructor (props) {
- super(props)
- this.state = {activeSection: 'comments'}
+ super(props);
+ this.state = {activeSection: 'comments', copied: false};
+ this.copyToClipBoard = this.copyToClipBoard.bind(this);
}
getCommentSettings () {
@@ -38,43 +39,45 @@ class Configure extends React.Component {
error='Input is not a number!'
label='Maximum Characters' />
-
+ ;
}
- copyToClipBoard (event) {
- const copyTextarea = document.querySelector('.' + styles.embedInput)
- copyTextarea.select()
+ copyToClipBoard () {
+ const copyTextarea = document.querySelector(`.${ styles.embedInput}`);
+ copyTextarea.select();
try {
- document.execCommand('copy')
+ document.execCommand('copy');
+ this.setState({copied: true});
} catch (err) {
- console.error('Unable to copy')
+ console.error('Unable to copy', err);
}
}
getEmbed () {
const embedText =
- ``
+ ``;
return
Copy and paste code below into your CMS to embed your comment box in your articles
-
-
+
-
+ ;
}
changeSection (activeSection) {
- this.setState({activeSection})
+ this.setState({activeSection});
}
render () {
const pageTitle = this.state.activeSection === 'comments'
? 'Comment Settings'
- : 'Embed Comment Stream'
+ : 'Embed Comment Stream';
return (
@@ -104,10 +107,10 @@ class Configure extends React.Component {
}
- )
+ );
}
}
-export default connect(x => x)(Configure)
+export default connect(x => x)(Configure);
-const lang = new I18n(translations)
+const lang = new I18n(translations);
diff --git a/client/coral-admin/src/containers/LayoutContainer.js b/client/coral-admin/src/containers/LayoutContainer.js
index 7373c30c2..50f54a631 100644
--- a/client/coral-admin/src/containers/LayoutContainer.js
+++ b/client/coral-admin/src/containers/LayoutContainer.js
@@ -1,19 +1,18 @@
-import React, { Component }from 'react'
-import { connect } from 'react-redux'
+import React, {Component}from 'react';
+import {connect} from 'react-redux';
-import { Layout } from '../components/ui/Layout'
+import {Layout} from '../components/ui/Layout';
class LayoutContainer extends Component {
render () {
- return
+ return ;
}
}
-LayoutContainer.propTypes = {}
+LayoutContainer.propTypes = {};
-const mapStateToProps = state => ({ data: {} })
+const mapStateToProps = () => ({data: {}});
-const mapDispatchToProps = (dispatch, ownProps) => ({ dispatch })
-
-export default connect(mapStateToProps, mapDispatchToProps)(LayoutContainer)
+const mapDispatchToProps = (dispatch) => ({dispatch});
+export default connect(mapStateToProps, mapDispatchToProps)(LayoutContainer);
diff --git a/client/coral-admin/src/containers/ModerationQueue.js b/client/coral-admin/src/containers/ModerationQueue.js
index d051e5639..6cd9f46fc 100644
--- a/client/coral-admin/src/containers/ModerationQueue.js
+++ b/client/coral-admin/src/containers/ModerationQueue.js
@@ -1,13 +1,12 @@
-
-import React from 'react'
-import { connect } from 'react-redux'
-import ModerationKeysModal from 'components/ModerationKeysModal'
-import CommentList from 'components/CommentList'
-import { updateStatus } from 'actions/comments'
-import styles from './ModerationQueue.css'
-import key from 'keymaster'
-import I18n from 'coral-framework/i18n/i18n'
-import translations from '../translations'
+import React from 'react';
+import {connect} from 'react-redux';
+import ModerationKeysModal from 'components/ModerationKeysModal';
+import CommentList from 'components/CommentList';
+import {updateStatus} from 'actions/comments';
+import styles from './ModerationQueue.css';
+import key from 'keymaster';
+import I18n from 'coral-framework/i18n/i18n';
+import translations from '../translations';
/*
* Renders the moderation queue as a tabbed layout with 3 moderation
@@ -17,46 +16,47 @@ import translations from '../translations'
class ModerationQueue extends React.Component {
constructor (props) {
- super(props)
+ super(props);
- this.state = { activeTab: 'pending', singleView: false, modalOpen: false }
+ this.state = {activeTab: 'pending', singleView: false, modalOpen: false};
}
// Fetch comments and bind singleView key before render
componentWillMount () {
- this.props.dispatch({ type: 'COMMENTS_MODERATION_QUEUE_FETCH' })
- key('s', () => this.setState({ singleView: !this.state.singleView }))
- key('shift+/', () => this.setState({ modalOpen: true }))
- key('esc', () => this.setState({ modalOpen: false }))
+ this.props.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH'});
+ key('s', () => this.setState({singleView: !this.state.singleView}));
+ key('shift+/', () => this.setState({modalOpen: true}));
+ key('esc', () => this.setState({modalOpen: false}));
}
// Unbind singleView key before unmount
componentWillUnmount () {
- key.unbind('s')
- key.unbind('shift+/')
- key.unbind('esc')
+ key.unbind('s');
+ key.unbind('shift+/');
+ key.unbind('esc');
}
// Hack for dynamic mdl tabs
componentDidMount () {
if (typeof componentHandler !== 'undefined') {
- componentHandler.upgradeAllRegistered()
+ // FIXME: fix this hack
+ componentHandler.upgradeAllRegistered(); // eslint-disable-line no-undef
}
}
// Dispatch the update status action
onCommentAction (status, id) {
- this.props.dispatch(updateStatus(status, id))
+ this.props.dispatch(updateStatus(status, id));
}
onTabClick (activeTab) {
- this.setState({ activeTab })
+ this.setState({activeTab});
}
// Render the tabbed lists moderation queues
render () {
- const { comments } = this.props
- const { activeTab, singleView, modalOpen } = this.state
+ const {comments} = this.props;
+ const {activeTab, singleView, modalOpen} = this.state;
return (
@@ -94,8 +94,8 @@ class ModerationQueue extends React.Component {
isActive={activeTab === 'rejected'}
singleView={singleView}
commentIds={comments.get('ids').filter(id => {
- const data = comments.get('byId').get(id)
- return !data.get('status') && data.get('flagged') === true
+ const data = comments.get('byId').get(id);
+ return !data.get('status') && data.get('flagged') === true;
})}
comments={comments.get('byId')}
onClickAction={(action, id) => this.onCommentAction(action, id)}
@@ -103,13 +103,13 @@ class ModerationQueue extends React.Component {
loading={comments.loading} />
this.setState({ modalOpen: false })} />
+ onClose={() => this.setState({modalOpen: false})} />
- )
+ );
}
}
-export default connect(({ comments }) => ({ comments }))(ModerationQueue)
+export default connect(({comments}) => ({comments}))(ModerationQueue);
-const lang = new I18n(translations)
+const lang = new I18n(translations);
diff --git a/client/coral-admin/src/index.js b/client/coral-admin/src/index.js
index d15367dd0..aed9d5748 100644
--- a/client/coral-admin/src/index.js
+++ b/client/coral-admin/src/index.js
@@ -1,7 +1,7 @@
-import React from 'react'
-import ReactDOM from 'react-dom'
-import App from './components/App'
+import React from 'react';
+import ReactDOM from 'react-dom';
+import App from './components/App';
// Render the application into the DOM
-ReactDOM.render(, document.querySelector('#root'))
+ReactDOM.render(, document.querySelector('#root'));
diff --git a/client/coral-admin/src/reducers/comments.js b/client/coral-admin/src/reducers/comments.js
index 4fd14673a..2842e2289 100644
--- a/client/coral-admin/src/reducers/comments.js
+++ b/client/coral-admin/src/reducers/comments.js
@@ -1,5 +1,5 @@
-import { Map, List, fromJS } from 'immutable'
+import {Map, List, fromJS} from 'immutable';
/**
* Comments state is stored using 2 structures:
@@ -12,48 +12,48 @@ const initialState = Map({
byId: Map(),
ids: List(),
loading: false
-})
+});
// Handle the comment actions
export default (state = initialState, action) => {
switch (action.type) {
- case 'COMMENTS_MODERATION_QUEUE_FETCH': return state.set('loading', true)
- case 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS': return replaceComments(action, state)
- case 'COMMENTS_MODERATION_QUEUE_FAILED': return state.set('loading', false)
- case 'COMMENT_STATUS_UPDATE': return updateStatus(state, action)
- case 'COMMENT_FLAG': return flag(state, action)
- case 'COMMENT_CREATE_SUCCESS': return addComment(state, action)
- case 'COMMENT_STREAM_FETCH_SUCCESS': return replaceComments(action, state)
- default: return state
+ case 'COMMENTS_MODERATION_QUEUE_FETCH': return state.set('loading', true);
+ case 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS': return replaceComments(action, state);
+ case 'COMMENTS_MODERATION_QUEUE_FAILED': return state.set('loading', false);
+ case 'COMMENT_STATUS_UPDATE': return updateStatus(state, action);
+ case 'COMMENT_FLAG': return flag(state, action);
+ case 'COMMENT_CREATE_SUCCESS': return addComment(state, action);
+ case 'COMMENT_STREAM_FETCH_SUCCESS': return replaceComments(action, state);
+ default: return state;
}
-}
+};
// Update a comment status
const updateStatus = (state, action) => {
- const byId = state.get('byId')
- const data = byId.get(action.id).get('data').set('status', action.status)
- const comment = byId.get(action.id).set('data', data)
- return state.set('byId', byId.set(action.id, comment))
-}
+ const byId = state.get('byId');
+ const data = byId.get(action.id).get('data').set('status', action.status);
+ const comment = byId.get(action.id).set('data', data);
+ return state.set('byId', byId.set(action.id, comment));
+};
// Flag a comment
const flag = (state, action) => {
- const byId = state.get('byId')
- const data = byId.get(action.id).get('data').set('flagged', true)
- const comment = byId.get(action.id).set('data', data)
- return state.set('byId', byId.set(action.id, comment))
-}
+ const byId = state.get('byId');
+ const data = byId.get(action.id).get('data').set('flagged', true);
+ const comment = byId.get(action.id).set('data', data);
+ return state.set('byId', byId.set(action.id, comment));
+};
// Replace the comment list with a new one
const replaceComments = (action, state) => {
- const comments = fromJS(action.comments.reduce((prev, curr) => { prev[curr._id] = curr; return prev }, {}))
+ const comments = fromJS(action.comments.reduce((prev, curr) => { prev[curr._id] = curr; return prev; }, {}));
return state.set('byId', comments).set('loading', false)
- .set('ids', List(comments.keys()))
-}
+ .set('ids', List(comments.keys()));
+};
// Add a new comment
const addComment = (state, action) => {
- const comment = fromJS(action.comment)
+ const comment = fromJS(action.comment);
return state.set('byId', state.get('byId').set(comment.get('item_id'), comment))
- .set('ids', state.get('ids').unshift(comment.get('item_id')))
-}
+ .set('ids', state.get('ids').unshift(comment.get('item_id')));
+};
diff --git a/client/coral-admin/src/reducers/index.js b/client/coral-admin/src/reducers/index.js
index 5c99e3bb2..3c0ddc924 100644
--- a/client/coral-admin/src/reducers/index.js
+++ b/client/coral-admin/src/reducers/index.js
@@ -1,8 +1,8 @@
-import { combineReducers } from 'redux'
-import comments from 'reducers/comments'
+import {combineReducers} from 'redux';
+import comments from 'reducers/comments';
// Combine all reducers into a main one
export default combineReducers({
comments
-})
+});
diff --git a/client/coral-admin/src/services/config.js b/client/coral-admin/src/services/config.js
index 56e96222f..05cf0ecb8 100644
--- a/client/coral-admin/src/services/config.js
+++ b/client/coral-admin/src/services/config.js
@@ -5,10 +5,10 @@
*/
try {
- module.exports = require('../../config.json')
+ module.exports = require('../../config.json');
} catch (error) {
const message = `The config.json file under the root directory is missing
-or invalid Please add one to use this app. You can use config.sample.json as a guide.`
- window.alert(message)
- throw new Error(message)
+or invalid Please add one to use this app. You can use config.sample.json as a guide.`;
+ window.alert(message);
+ throw new Error(message);
}
diff --git a/client/coral-admin/src/services/store.js b/client/coral-admin/src/services/store.js
index c11728de0..88b2650e0 100644
--- a/client/coral-admin/src/services/store.js
+++ b/client/coral-admin/src/services/store.js
@@ -1,8 +1,8 @@
-import { createStore, applyMiddleware } from 'redux'
-import thunk from 'redux-thunk'
-import mainReducer from 'reducers'
-import talkAdapter from 'services/talk-adapter'
+import {createStore, applyMiddleware} from 'redux';
+import thunk from 'redux-thunk';
+import mainReducer from 'reducers';
+import talkAdapter from 'services/talk-adapter';
/**
* Create the store by merging the app reducers with
@@ -15,4 +15,4 @@ export default createStore(
mainReducer,
window.devToolsExtension && window.devToolsExtension(),
applyMiddleware(thunk, talkAdapter)
-)
+);
diff --git a/client/coral-admin/src/services/talk-adapter.js b/client/coral-admin/src/services/talk-adapter.js
index 2336e0cfd..ce2e2692a 100644
--- a/client/coral-admin/src/services/talk-adapter.js
+++ b/client/coral-admin/src/services/talk-adapter.js
@@ -10,44 +10,44 @@
// Intercept redux actions and act over the ones we are interested
export default store => next => action => {
switch (action.type) {
- case 'COMMENTS_MODERATION_QUEUE_FETCH':
- fetchModerationQueueComments(store)
- break
- case 'COMMENT_STREAM_FETCH':
- fetchCommentStream(store)
- break
- case 'COMMENT_UPDATE':
- updateComment(store, action.comment)
- break
- case 'COMMENT_CREATE':
- createComment(store, action.name, action.body)
- break
+ case 'COMMENTS_MODERATION_QUEUE_FETCH':
+ fetchModerationQueueComments(store);
+ break;
+ // case 'COMMENT_STREAM_FETCH':
+ // fetchCommentStream(store);
+ // break;
+ case 'COMMENT_UPDATE':
+ updateComment(store, action.comment);
+ break;
+ case 'COMMENT_CREATE':
+ createComment(store, action.name, action.body);
+ break;
}
- next(action)
-}
+ next(action);
+};
// Get comments to fill each of the three lists on the mod queue
const fetchModerationQueueComments = store =>
-fetch(`/api/v1/queue`)
+fetch('/api/v1/queue')
.then(res => res.json())
-.then(res => store.dispatch({ type: 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS',
- comments: res }))
-.catch(error => store.dispatch({ type: 'COMMENTS_MODERATION_QUEUE_FETCH_FAILED', error }))
+.then(res => store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_SUCCESS',
+ comments: res}))
+.catch(error => store.dispatch({type: 'COMMENTS_MODERATION_QUEUE_FETCH_FAILED', error}));
// Update a comment. Now to update a comment we need to send back the whole object
const updateComment = (store, comment) =>
fetch(`/api/v1/comments/${comment._id}/status`, {
method: 'POST',
- body: JSON.stringify({ status: comment.status })
+ body: JSON.stringify({status: comment.status})
})
.then(res => res.json())
-.then(res => store.dispatch({ type: 'COMMENT_UPDATE_SUCCESS', res }))
-.catch(error => store.dispatch({ type: 'COMMENT_UPDATE_FAILED', error }))
+.then(res => store.dispatch({type: 'COMMENT_UPDATE_SUCCESS', res}))
+.catch(error => store.dispatch({type: 'COMMENT_UPDATE_FAILED', error}));
// Create a new comment
const createComment = (store, name, comment) =>
-fetch(`/api/v1/comments`, {
+fetch('/api/v1/comments', {
method: 'POST',
body: JSON.stringify({
status: 'Untouched',
@@ -56,5 +56,5 @@ fetch(`/api/v1/comments`, {
createdAt: Date.now()
})
}).then(res => res.json())
-.then(res => store.dispatch({ type: 'COMMENT_CREATE_SUCCESS', comment: res }))
-.catch(error => store.dispatch({ type: 'COMMENT_CREATE_FAILED', error }))
+.then(res => store.dispatch({type: 'COMMENT_CREATE_SUCCESS', comment: res}))
+.catch(error => store.dispatch({type: 'COMMENT_CREATE_FAILED', error}));
diff --git a/client/coral-admin/src/translations.js b/client/coral-admin/src/translations.js
index ce5bf7718..5302c1221 100644
--- a/client/coral-admin/src/translations.js
+++ b/client/coral-admin/src/translations.js
@@ -1,39 +1,39 @@
export default {
en: {
- "modqueue": {
- "pending": "pending",
- "rejected": "rejected",
- "flagged": "flagged",
- "shortcuts": "Shortcuts",
- "close": "Close",
- "actions": "Actions",
- "navigation": "Navigation",
- "approve": "Approve comment",
- "reject": "Reject comment",
- "nextcomment": "Go to the next comment",
- "prevcomment": "Go to the previous comment",
- "singleview": "Toggle single comment edit view",
- "thismenu": "Open this menu"
+ 'modqueue': {
+ 'pending': 'pending',
+ 'rejected': 'rejected',
+ 'flagged': 'flagged',
+ 'shortcuts': 'Shortcuts',
+ 'close': 'Close',
+ 'actions': 'Actions',
+ 'navigation': 'Navigation',
+ 'approve': 'Approve comment',
+ 'reject': 'Reject comment',
+ 'nextcomment': 'Go to the next comment',
+ 'prevcomment': 'Go to the previous comment',
+ 'singleview': 'Toggle single comment edit view',
+ 'thismenu': 'Open this menu'
},
- "comment": {
- "flagged": "flagged",
- "anon": "Anonymous"
+ 'comment': {
+ 'flagged': 'flagged',
+ 'anon': 'Anonymous'
},
- "embedlink": {
- "copy": "Copy to Clipboard"
+ 'embedlink': {
+ 'copy': 'Copy to Clipboard'
}
},
es: {
- "modqueue": {
- "pending": "pendiente",
- "rejected": "rechazado",
- "flagged": "marcado",
- "shortcuts": "Atajos de teclado",
- "close": "Cerrar"
+ 'modqueue': {
+ 'pending': 'pendiente',
+ 'rejected': 'rechazado',
+ 'flagged': 'marcado',
+ 'shortcuts': 'Atajos de teclado',
+ 'close': 'Cerrar'
},
- "comment": {
- "flagged": "marcado",
- "anon": "Anónimo"
+ 'comment': {
+ 'flagged': 'marcado',
+ 'anon': 'Anónimo'
}
}
-}
+};
diff --git a/client/coral-embed-stream/src/CommentStream.js b/client/coral-embed-stream/src/CommentStream.js
index cda7ffd57..76d5a0e9b 100644
--- a/client/coral-embed-stream/src/CommentStream.js
+++ b/client/coral-embed-stream/src/CommentStream.js
@@ -1,63 +1,62 @@
-import React, {Component, PropTypes} from 'react'
+import React, {Component, PropTypes} from 'react';
import {
itemActions,
Notification,
notificationActions,
authActions
-} from '../../coral-framework'
-import {connect} from 'react-redux'
-import CommentBox from '../../coral-plugin-commentbox/CommentBox'
-import Content from '../../coral-plugin-commentcontent/CommentContent'
-import PubDate from '../../coral-plugin-pubdate/PubDate'
-import Count from '../../coral-plugin-comment-count/CommentCount'
-import Flag from '../../coral-plugin-flags/FlagButton'
-import AuthorName from '../../coral-plugin-author-name/AuthorName'
-import {ReplyBox, ReplyButton} from '../../coral-plugin-replies'
-import Pym from 'pym.js'
+} from '../../coral-framework';
+import {connect} from 'react-redux';
+import CommentBox from '../../coral-plugin-commentbox/CommentBox';
+import Content from '../../coral-plugin-commentcontent/CommentContent';
+import PubDate from '../../coral-plugin-pubdate/PubDate';
+import Count from '../../coral-plugin-comment-count/CommentCount';
+import AuthorName from '../../coral-plugin-author-name/AuthorName';
+import {ReplyBox, ReplyButton} from '../../coral-plugin-replies';
+import Pym from 'pym.js';
-const {addItem, updateItem, postItem, getStream, postAction, appendItemArray} = itemActions
-const {addNotification, clearNotification} = notificationActions
-const {setLoggedInUser} = authActions
+const {addItem, updateItem, postItem, getStream, postAction, appendItemArray} = itemActions;
+const {addNotification, clearNotification} = notificationActions;
+const {setLoggedInUser} = authActions;
@connect(
(state) => {
- return {
+ return {
config: state.config.toJS(),
items: state.items.toJS(),
notification: state.notification.toJS(),
auth: state.auth.toJS()
- }
+ };
},
(dispatch) => {
return {
addItem: (item) => {
- return dispatch(addItem(item))
+ return dispatch(addItem(item));
},
updateItem: (id, property, value) => {
- return dispatch(updateItem(id, property, value))
+ return dispatch(updateItem(id, property, value));
},
postItem: (data, type, id) => {
- return dispatch(postItem(data, type, id))
+ return dispatch(postItem(data, type, id));
},
getStream: (rootId) => {
- return dispatch(getStream(rootId))
+ return dispatch(getStream(rootId));
},
addNotification: (type, text) => {
- return dispatch(addNotification(type, text))
+ return dispatch(addNotification(type, text));
},
clearNotification: () => {
- return dispatch(clearNotification())
+ return dispatch(clearNotification());
},
setLoggedInUser: (user_id) => {
- return dispatch(setLoggedInUser(user_id))
+ return dispatch(setLoggedInUser(user_id));
},
postAction: (item, action, user) => {
- return dispatch(postAction(item, action, user))
+ return dispatch(postAction(item, action, user));
},
appendItemArray: (item, property, value, addToFront) => {
- return dispatch(appendItemArray(item, property, value, addToFront))
+ return dispatch(appendItemArray(item, property, value, addToFront));
}
- }
+ };
}
)
@@ -72,33 +71,30 @@ class CommentStream extends Component {
componentDidMount () {
// Set up messaging between embedded Iframe an parent component
// Using recommended Pym init code which violates .eslint standards
- new Pym.Child({ polling: 500 })
- this.props.getStream('assetTest')
+ new Pym.Child({polling: 500});
+ this.props.getStream('assetTest');
}
render () {
- if (Object.keys(this.props.items).length === 0) {
+ if (Object.keys(this.props.items).length === 0) {
// Loading mock asset
- this.props.postItem({
- comments: [],
- url: 'http://coralproject.net'
- }, 'asset', 'assetTest')
+ this.props.postItem({
+ comments: [],
+ url: 'http://coralproject.net'
+ }, 'asset', 'assetTest');
// Loading mock user
- this.props.postItem({name: 'Ban Ki-Moon'}, 'user', 'user_8989')
+ this.props.postItem({name: 'Ban Ki-Moon'}, 'user', 'user_8989')
.then((id) => {
- this.props.setLoggedInUser(id)
- })
- }
-
+ this.props.setLoggedInUser(id);
+ });
+ }
// TODO: Replace teststream id with id from params
-
-
- const rootItemId = 'assetTest'
- const rootItem = this.props.items[rootItemId]
- return
+ const rootItemId = 'assetTest';
+ const rootItem = this.props.items[rootItemId];
+ return
{
rootItem ?
@@ -116,7 +112,7 @@ class CommentStream extends Component {
{
rootItem.comments.map((commentId) => {
- const comment = this.props.items[commentId]
+ const comment = this.props.items[commentId];
return
@@ -146,8 +142,8 @@ class CommentStream extends Component {
{
comment.children &&
comment.children.map((replyId) => {
- let reply = this.props.items[replyId]
- return
+ let reply = this.props.items[replyId];
+ return
@@ -165,10 +161,10 @@ class CommentStream extends Component {
updateItem={this.props.updateItem}
parent_id={reply.parent_id}/>
-
- })
+ ;
+ })
}
-
+
;
})
}
- :'Loading'
+ : 'Loading'
}
-
-
+ ;
}
}
-export default CommentStream
+export default CommentStream;
diff --git a/client/coral-embed-stream/src/index.js b/client/coral-embed-stream/src/index.js
index 189427e23..f2a584ed1 100644
--- a/client/coral-embed-stream/src/index.js
+++ b/client/coral-embed-stream/src/index.js
@@ -1,13 +1,13 @@
-import React from 'react'
-import { render } from 'react-dom'
-import CommentStream from './CommentStream'
-import { Provider } from 'react-redux'
-import { fetchConfig, store } from '../../coral-framework'
+import React from 'react';
+import {render} from 'react-dom';
+import CommentStream from './CommentStream';
+import {Provider} from 'react-redux';
+import {fetchConfig, store} from '../../coral-framework';
-store.dispatch(fetchConfig())
+store.dispatch(fetchConfig());
render(
- , document.querySelector('#coralStream'))
+ , document.querySelector('#coralStream'));
diff --git a/client/coral-framework/__tests__/store/authReducer.js b/client/coral-framework/__tests__/store/authReducer.js
index dd9f58501..90138f8f2 100644
--- a/client/coral-framework/__tests__/store/authReducer.js
+++ b/client/coral-framework/__tests__/store/authReducer.js
@@ -1,7 +1,7 @@
-import { Map } from 'immutable'
-import {expect} from 'chai'
-import authReducer from '../../store/reducers/auth'
-import * as actions from '../../store/actions/auth'
+import {Map} from 'immutable';
+import {expect} from 'chai';
+import authReducer from '../../store/reducers/auth';
+import * as actions from '../../store/actions/auth';
describe ('authReducer', () => {
describe('SET_LOGGED_IN_USER', () => {
@@ -9,23 +9,23 @@ describe ('authReducer', () => {
const action = {
type: actions.SET_LOGGED_IN_USER,
user_id: '123'
- }
- const store = new Map({})
- const result = authReducer(store, action)
- expect(result.get('user')).to.equal(action.user_id)
- })
- })
+ };
+ const store = new Map({});
+ const result = authReducer(store, action);
+ expect(result.get('user')).to.equal(action.user_id);
+ });
+ });
describe('LOG_OUT_USER', () => {
it('should clear the user store', () => {
const action = {
type: actions.LOG_OUT_USER
- }
+ };
const store = new Map({
user: '123'
- })
- const result = authReducer(store, action)
- expect(result.get('user')).to.equal(undefined)
- })
- })
-})
+ });
+ const result = authReducer(store, action);
+ expect(result.get('user')).to.equal(undefined);
+ });
+ });
+});
diff --git a/client/coral-framework/__tests__/store/itemActions.spec.js b/client/coral-framework/__tests__/store/itemActions.spec.js
index 948aee32d..14bdca790 100644
--- a/client/coral-framework/__tests__/store/itemActions.spec.js
+++ b/client/coral-framework/__tests__/store/itemActions.spec.js
@@ -1,70 +1,70 @@
-import 'react'
-import 'redux'
-import {expect} from 'chai'
-import fetchMock from 'fetch-mock'
-import * as actions from '../../store/actions/items'
-import {Map} from 'immutable'
+import 'react';
+import 'redux';
+import {expect} from 'chai';
+import fetchMock from 'fetch-mock';
+import * as actions from '../../store/actions/items';
+import {Map} from 'immutable';
-import configureStore from 'redux-mock-store'
+import configureStore from 'redux-mock-store';
-const mockStore = configureStore()
+const mockStore = configureStore();
describe('itemActions', () => {
- let store
- const host = 'http://test.host'
+ let store;
+ const host = 'http://test.host';
beforeEach(() => {
- store = mockStore(new Map({}))
- fetchMock.restore()
- })
+ store = mockStore(new Map({}));
+ fetchMock.restore();
+ });
describe('getItemsQuery', () => {
- const query = 'all'
- const rootId = '1234'
- const view = 'testView'
+ const query = 'all';
+ const rootId = '1234';
+ const view = 'testView';
const response = {results: [
{Docs: [
{type: 'comment', data: {content: 'stuff'}, item_id: '123'},
{type: 'comment', data: {content: 'morestuff'}, item_id: '456'}
]}
- ]}
+ ]};
it('should get an item from a query and send the appropriate dispatches', () => {
- fetchMock.get('*', JSON.stringify(response))
+ fetchMock.get('*', JSON.stringify(response));
return actions.getItemsQuery(query, rootId, view, host)(store.dispatch)
.then((res) => {
- expect(fetchMock.calls().matched[0][0]).to.equal('http://test.host/v1/exec/all/view/testView/1234')
- expect(res).to.deep.equal(response.results[0].Docs)
+ expect(fetchMock.calls().matched[0][0]).to.equal('http://test.host/v1/exec/all/view/testView/1234');
+ expect(res).to.deep.equal(response.results[0].Docs);
expect(store.getActions()[0]).to.deep.equal({
type: actions.ADD_ITEM,
item: response.results[0].Docs[0],
item_id: '123'
- })
+ });
expect(store.getActions()[1]).to.deep.equal({
type: actions.ADD_ITEM,
item: response.results[0].Docs[1],
item_id: '456'
- })
- })
- })
+ });
+ });
+ });
it('should handle an error', () => {
- fetchMock.get('*', 404)
+ fetchMock.get('*', 404);
return actions.getItemsQuery(query, rootId, view, host)(store.dispatch)
.catch((err) => {
- expect(err).to.be.truthy
- })
- })
- })
+ expect(err).to.be.truthy;
+ });
+ });
+ });
describe('getItemsArray', () => {
- const response = {items: [{type: 'comment', item_id: '123'}, {type: 'comment', item_id: '456'}]}
- const ids = [1, 2]
+ const response = {items: [{type: 'comment', item_id: '123'}, {type: 'comment', item_id: '456'}]};
+ const ids = [1, 2];
it('should get an item from an array of ids and send the appropriate dispatches', () => {
- fetchMock.get('*', JSON.stringify(response))
+ fetchMock.get('*', JSON.stringify(response));
return actions.getItemsArray(ids, host)(store.dispatch)
.then((res) => {
- expect(res).to.deep.equal(response.items)
+ expect(res).to.deep.equal(response.items);
expect(store.getActions()[0]).to.deep.equal({
type: actions.ADD_ITEM,
item: {
@@ -72,33 +72,33 @@ describe('itemActions', () => {
item_id: '123'
},
item_id: '123'
- })
+ });
expect(store.getActions()[1]).to.deep.equal({
type: actions.ADD_ITEM,
item: {
type: 'comment', item_id: '456'
},
item_id: '456'
- })
- })
- })
+ });
+ });
+ });
it('should handle an error', () => {
- fetchMock.get('*', 404)
+ fetchMock.get('*', 404);
return actions.getItemsArray(ids, host)(store.dispatch)
.catch((err) => {
- expect(err).to.be.truthy
- })
- })
- })
+ expect(err).to.be.truthy;
+ });
+ });
+ });
describe('postItem', () => {
const item = {
type: 'comment',
data:{content: 'stuff'}
- }
+ };
it ('should post an item, return an id, then dispatch that item to the store', () => {
- fetchMock.post('*', {item_id: '123', type: 'comment', data: {content: 'stuff'}})
+ fetchMock.post('*', {item_id: '123', type: 'comment', data: {content: 'stuff'}});
return actions.postItem(item.data, item.type, undefined, host)(store.dispatch)
.then((id) => {
expect(fetchMock.calls().matched[0][1]).to.deep.equal(
@@ -106,8 +106,8 @@ describe('itemActions', () => {
method: 'POST',
body: JSON.stringify({...item, version: 1})
}
- )
- expect(id).to.equal('123')
+ );
+ expect(id).to.equal('123');
expect(store.getActions()[0]).to.deep.equal({
type: actions.ADD_ITEM,
item: {
@@ -118,35 +118,35 @@ describe('itemActions', () => {
item_id: '123'
},
item_id: '123'
- })
- })
- })
+ });
+ });
+ });
it('should handle an error', () => {
- fetchMock.post('*', 404)
+ fetchMock.post('*', 404);
return actions.postItem(item, host)(store.dispatch)
.catch((err) => {
- expect(err).to.be.truthy
- })
- })
- })
+ expect(err).to.be.truthy;
+ });
+ });
+ });
describe('postAction', () => {
it ('should post an action', () => {
- fetchMock.post('*', 200)
+ fetchMock.post('*', 200);
return actions.postAction('abc', 'flag', '123', host)(store.dispatch)
.then(response => {
- expect(fetchMock.calls().matched[0][0]).to.equal('http://test.host/v1/action/flag/user/123/on/item/abc')
- expect(response).to.equal('')
- })
- })
+ expect(fetchMock.calls().matched[0][0]).to.equal('http://test.host/v1/action/flag/user/123/on/item/abc');
+ expect(response).to.equal('');
+ });
+ });
it('should handle an error', () => {
- fetchMock.post('*', 404)
+ fetchMock.post('*', 404);
return actions.postItem('abc', 'flag', '123', host)(store.dispatch)
.catch((err) => {
- expect(err).to.be.truthy
- })
- })
+ expect(err).to.be.truthy;
+ });
+ });
- })
-})
+ });
+});
diff --git a/client/coral-framework/__tests__/store/itemReducer.spec.js b/client/coral-framework/__tests__/store/itemReducer.spec.js
index 8a664ac8c..0e8106bae 100644
--- a/client/coral-framework/__tests__/store/itemReducer.spec.js
+++ b/client/coral-framework/__tests__/store/itemReducer.spec.js
@@ -1,7 +1,6 @@
-import { Map, fromJS } from 'immutable'
-import {expect} from 'chai'
-import itemsReducer from '../../store/reducers/items'
-import * as actions from '../../store/actions/items'
+import {Map, fromJS} from 'immutable';
+import {expect} from 'chai';
+import itemsReducer from '../../store/reducers/items';
describe ('itemsReducer', () => {
describe('ADD_ITEM', () => {
@@ -16,18 +15,18 @@ describe ('itemsReducer', () => {
item_id: '123'
},
item_id: '123'
- }
- const store = new Map({})
- const result = itemsReducer(store, action)
+ };
+ const store = new Map({});
+ const result = itemsReducer(store, action);
expect(result.get('123').toJS()).to.deep.equal({
type: 'comment',
data: {
content: 'stuff'
},
item_id: '123'
- })
- })
- })
+ });
+ });
+ });
describe ('UPDATE_ITEM', () => {
it ('should update an item', () => {
@@ -36,7 +35,7 @@ describe ('itemsReducer', () => {
property: 'stuff',
value: 'things',
item_id: '123'
- }
+ };
const store = fromJS({
'123': {
item_id: '123',
@@ -44,20 +43,20 @@ describe ('itemsReducer', () => {
stuff: 'morestuff'
}
}
- })
- const result = itemsReducer(store, action)
+ });
+ const result = itemsReducer(store, action);
expect(result.get('123').toJS()).to.deep.equal({
item_id: '123',
data: {
stuff: 'things'
}
- })
- })
- })
+ });
+ });
+ });
describe('APPEND_ITEM_ARRAY', () => {
- let action
- let store
+ let action;
+ let store;
beforeEach (() => {
action = {
@@ -65,7 +64,7 @@ describe ('itemsReducer', () => {
property: 'stuff',
value: 'things',
item_id: '123'
- }
+ };
store = fromJS({
'123': {
item_id: '123',
@@ -73,37 +72,37 @@ describe ('itemsReducer', () => {
stuff: ['morestuff']
}
}
- })
- })
+ });
+ });
it ('should append to an existing array', () => {
- const result = itemsReducer(store, action)
+ const result = itemsReducer(store, action);
expect(result.get('123').toJS()).to.deep.equal({
item_id: '123',
data: {
stuff: ['morestuff', 'things']
}
- })
- })
+ });
+ });
it ('should create a new array', () => {
store = fromJS({
'123': {
item_id: '123',
data: {}
}
- })
- const result = itemsReducer(store, action)
+ });
+ const result = itemsReducer(store, action);
expect(result.get('123').toJS()).to.deep.equal({
item_id: '123',
data: {
stuff: ['things']
}
- })
- })
- })
+ });
+ });
+ });
describe('APPEND_ITEM_RELATED', () => {
- let action
- let store
+ let action;
+ let store;
beforeEach (() => {
action = {
@@ -111,7 +110,7 @@ describe ('itemsReducer', () => {
property: 'stuff',
value: 'things',
item_id: '123'
- }
+ };
store = fromJS({
'123': {
item_id: '123',
@@ -119,31 +118,31 @@ describe ('itemsReducer', () => {
stuff: ['morestuff']
}
}
- })
- })
+ });
+ });
it ('should append to an existing array', () => {
- const result = itemsReducer(store, action)
+ const result = itemsReducer(store, action);
expect(result.get('123').toJS()).to.deep.equal({
item_id: '123',
related: {
stuff: ['morestuff', 'things']
}
- })
- })
+ });
+ });
it ('should create a new array', () => {
store = fromJS({
'123': {
item_id: '123',
related: {}
}
- })
- const result = itemsReducer(store, action)
+ });
+ const result = itemsReducer(store, action);
expect(result.get('123').toJS()).to.deep.equal({
item_id: '123',
related: {
stuff: ['things']
}
- })
- })
- })
-})
+ });
+ });
+ });
+});
diff --git a/client/coral-framework/__tests__/store/notificationReducer.spec.js b/client/coral-framework/__tests__/store/notificationReducer.spec.js
index 4f37034a6..974d2c627 100644
--- a/client/coral-framework/__tests__/store/notificationReducer.spec.js
+++ b/client/coral-framework/__tests__/store/notificationReducer.spec.js
@@ -1,7 +1,7 @@
-import { Map } from 'immutable'
-import {expect} from 'chai'
-import notificationReducer from '../../store/reducers/notification'
-import * as actions from '../../store/actions/notification'
+import {Map} from 'immutable';
+import {expect} from 'chai';
+import notificationReducer from '../../store/reducers/notification';
+import * as actions from '../../store/actions/notification';
describe ('notificationsReducer', () => {
describe('ADD_NOTIFICATION', () => {
@@ -10,26 +10,26 @@ describe ('notificationsReducer', () => {
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)
- })
- })
+ };
+ 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(undefined)
- expect(result.get('type')).to.equal(undefined)
- })
- })
-})
+ });
+ const result = notificationReducer(store, action);
+ expect(result.get('text')).to.equal(undefined);
+ expect(result.get('type')).to.equal(undefined);
+ });
+ });
+});
diff --git a/client/coral-framework/i18n/i18n.js b/client/coral-framework/i18n/i18n.js
index d3e7d92b8..43144f3a6 100644
--- a/client/coral-framework/i18n/i18n.js
+++ b/client/coral-framework/i18n/i18n.js
@@ -1,5 +1,5 @@
-import timeago from 'timeago.js'
-import esTA from 'timeago.js/locales/es'
+import timeago from 'timeago.js';
+import esTA from 'timeago.js/locales/es';
/**
* Default locales, this should be overriden by config file
@@ -11,32 +11,34 @@ class i18n {
* Register locales
*/
- this.locales = {'en': 'en', 'es': 'es'}
- timeago.register('es_ES', esTA)
- this.timeagoInstance = new timeago()
+ this.locales = {'en': 'en', 'es': 'es'};
+ timeago.register('es_ES', esTA);
+ this.timeagoInstance = new timeago();
/**
* Load translations
*/
- let trans = translations || { en: {} }
+ let trans = translations || {en: {}};
try {
- const locale = localStorage.getItem('locale') || navigator.language
- localStorage.setItem('locale', locale)
- const lang = this.locales[locale.split('-')[0]] || 'en'
- this.translations = trans[lang]
+ const locale = localStorage.getItem('locale') || navigator.language;
+ localStorage.setItem('locale', locale);
+ const lang = this.locales[locale.split('-')[0]] || 'en';
+ this.translations = trans[lang];
} catch (err) {
- this.translations = trans['en']
+ this.translations = trans['en'];
}
this.setLocale = (locale) => {
try {
- localStorage.setItem('locale', locale)
- } catch (err) {}
- }
+ localStorage.setItem('locale', locale);
+ } catch (err) {
+ console.error(err);
+ }
+ };
this.getLocale = () => (
localStorage.getItem('locale') || navigator.locale || 'en-US'
- )
+ );
/**
* Expose the translation function
@@ -47,28 +49,28 @@ class i18n {
*/
this.t = (key) => {
- const arr = key.split('.')
- let translation = this.translations
+ const arr = key.split('.');
+ let translation = this.translations;
try {
- for (var i = 0; i < arr.length; i++) translation = translation[arr[i]]
+ for (let i = 0; i < arr.length; i++) {translation = translation[arr[i]];}
} catch (error) {
- console.warn(`${key} language key not set`)
- return key
+ console.warn(`${key} language key not set`);
+ return key;
}
- const val = String(translation)
+ const val = String(translation);
if (val) {
- return val
+ return val;
} else {
- console.warn(`${key} language key not set`)
- return key
+ console.warn(`${key} language key not set`);
+ return key;
}
- }
+ };
this.timeago = (time) => {
- return this.timeagoInstance.format(time)
- }
+ return this.timeagoInstance.format(time);
+ };
}
}
-export default i18n
+export default i18n;
diff --git a/client/coral-framework/index.js b/client/coral-framework/index.js
index 537693d97..118935c50 100644
--- a/client/coral-framework/index.js
+++ b/client/coral-framework/index.js
@@ -1,10 +1,10 @@
-import Notification from './notification/Notification'
-import store from './store/store'
-import {fetchConfig} from './store/actions/config'
-import * as itemActions from './store/actions/items'
-import I18n from './i18n/i18n'
-import * as notificationActions from './store/actions/notification'
-import * as authActions from './store/actions/auth'
+import Notification from './notification/Notification';
+import store from './store/store';
+import {fetchConfig} from './store/actions/config';
+import * as itemActions from './store/actions/items';
+import I18n from './i18n/i18n';
+import * as notificationActions from './store/actions/notification';
+import * as authActions from './store/actions/auth';
export {
Notification,
@@ -14,4 +14,4 @@ export {
I18n,
notificationActions,
authActions
-}
+};
diff --git a/client/coral-framework/notification/Notification.js b/client/coral-framework/notification/Notification.js
index 5d26e3dbf..2a5e1d693 100644
--- a/client/coral-framework/notification/Notification.js
+++ b/client/coral-framework/notification/Notification.js
@@ -1,19 +1,19 @@
-import React from 'react'
+import React from 'react';
const Notification = (props) => {
if (props.notification.text) {
setTimeout(() => {
- props.clearNotification()
- }, props.notifLength)
+ props.clearNotification();
+ }, props.notifLength);
}
return
{
props.notification.text &&
-
-}
+ ;
+};
-export default Notification
+export default Notification;
diff --git a/client/coral-framework/store/actions/auth.js b/client/coral-framework/store/actions/auth.js
index dfdf2c7cd..af1e3cb34 100644
--- a/client/coral-framework/store/actions/auth.js
+++ b/client/coral-framework/store/actions/auth.js
@@ -1,17 +1,17 @@
/* Auth Actions */
-export const SET_LOGGED_IN_USER = 'SET_LOGGED_IN_USER'
-export const LOG_OUT_USER = 'LOG_OUT_USER'
+export const SET_LOGGED_IN_USER = 'SET_LOGGED_IN_USER';
+export const LOG_OUT_USER = 'LOG_OUT_USER';
export const setLoggedInUser = (user_id) => {
return {
type: SET_LOGGED_IN_USER,
user_id
- }
-}
+ };
+};
export const LogOutUser = () => {
return {
type: LOG_OUT_USER
- }
-}
+ };
+};
diff --git a/client/coral-framework/store/actions/config.js b/client/coral-framework/store/actions/config.js
index 243cb9049..b529fc313 100644
--- a/client/coral-framework/store/actions/config.js
+++ b/client/coral-framework/store/actions/config.js
@@ -1,28 +1,28 @@
/* @flow */
-import { fromJS } from 'immutable'
+import {fromJS} from 'immutable';
/**
* Action name constants
*/
-export const FETCH_CONFIG_REQUEST = 'FETCH_CONFIG_REQUEST'
-export const FETCH_CONFIG_FAILED = 'FETCH_CONFIG_FAILED'
-export const FETCH_CONFIG_SUCCESS = 'FETCH_CONFIG_SUCCESS'
+export const FETCH_CONFIG_REQUEST = 'FETCH_CONFIG_REQUEST';
+export const FETCH_CONFIG_FAILED = 'FETCH_CONFIG_FAILED';
+export const FETCH_CONFIG_SUCCESS = 'FETCH_CONFIG_SUCCESS';
/**
* Action creators
*/
export const fetchConfig = () => async (dispatch) => {
- dispatch({ type: FETCH_CONFIG_REQUEST })
+ dispatch({type: FETCH_CONFIG_REQUEST});
try {
//TODO: Replace with fetching config from backend
// const response = await fetch(`./talk.config.json`)
// const json = await response.json()
- dispatch({ type: FETCH_CONFIG_SUCCESS, config: fromJS({}) })
+ dispatch({type: FETCH_CONFIG_SUCCESS, config: fromJS({})});
} catch (error) {
- dispatch({ type: FETCH_CONFIG_FAILED })
+ dispatch({type: FETCH_CONFIG_FAILED});
}
-}
+};
diff --git a/client/coral-framework/store/actions/items.js b/client/coral-framework/store/actions/items.js
index 8b30e2548..56e0aafc3 100644
--- a/client/coral-framework/store/actions/items.js
+++ b/client/coral-framework/store/actions/items.js
@@ -1,15 +1,12 @@
/* Item Actions */
-import { fromJS } from 'immutable'
-import mocks from '../../mocks.json'
-
/**
* Action name constants
*/
-export const ADD_ITEM = 'ADD_ITEM'
-export const UPDATE_ITEM = 'UPDATE_ITEM'
-export const APPEND_ITEM_ARRAY = 'APPEND_ITEM_ARRAY'
+export const ADD_ITEM = 'ADD_ITEM';
+export const UPDATE_ITEM = 'UPDATE_ITEM';
+export const APPEND_ITEM_ARRAY = 'APPEND_ITEM_ARRAY';
/**
* Action creators
@@ -26,14 +23,14 @@ export const APPEND_ITEM_ARRAY = 'APPEND_ITEM_ARRAY'
export const addItem = (item) => {
if (!item.id) {
- console.warn('addItem called without an item id.')
+ console.warn('addItem called without an item id.');
}
return {
type: ADD_ITEM,
item: item,
id: item.id
- }
-}
+ };
+};
/*
* Updates an item in the local store without posting it to the server
@@ -46,15 +43,14 @@ export const addItem = (item) => {
*
*/
-
export const updateItem = (id, property, value) => {
return {
type: UPDATE_ITEM,
id,
property,
value
- }
-}
+ };
+};
export const appendItemArray = (id, property, value, addToFront) => {
return {
@@ -63,8 +59,8 @@ export const appendItemArray = (id, property, value, addToFront) => {
property,
value,
addToFront
- }
-}
+ };
+};
/*
* Get Items from Query
@@ -81,47 +77,47 @@ export const appendItemArray = (id, property, value, addToFront) => {
*/
export function getStream (assetId) {
return (dispatch) => {
- return fetch('/api/v1/stream?asset_id='+assetId)
+ return fetch(`/api/v1/stream?asset_id=${assetId}`)
.then(
response => {
- return response.ok ? response.json() : Promise.reject(response.status + ' ' + response.statusText)
+ return response.ok ? response.json() : Promise.reject(`${response.status } ${ response.statusText}`);
}
)
.then((json) => {
/* Sort comments by date*/
- let rootComments = []
- let childComments = {}
- json.sort((a,b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime())
- json.reduce((prev, item) => {
- dispatch(addItem(item))
+ let rootComments = [];
+ let childComments = {};
+ json.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
+ json.forEach(item => {
+ dispatch(addItem(item));
/* Check for root and child comments. */
if (
item.asset_id === assetId &&
!item.parent_id) {
- rootComments.push(item.id)
+ rootComments.push(item.id);
} else if (
item.asset_id === assetId
) {
- let children = childComments[item.parent_id] || []
- childComments[item.parent_id] = children.concat(item.id)
+ let children = childComments[item.parent_id] || [];
+ childComments[item.parent_id] = children.concat(item.id);
}
- }, {})
+ }, {});
dispatch(addItem({
id: assetId,
comments: rootComments
- }))
+ }));
- const keys = Object.keys(childComments)
- for (var i=0; i < keys.length; i++ ) {
- dispatch(updateItem(keys[i], 'children', childComments[keys[i]].reverse()))
+ const keys = Object.keys(childComments);
+ for (let i = 0; i < keys.length; i++ ) {
+ dispatch(updateItem(keys[i], 'children', childComments[keys[i]].reverse()));
}
- return (json)
- })
- }
+ return (json);
+ });
+ };
}
/*
@@ -140,20 +136,20 @@ export function getStream (assetId) {
export function getItemsArray (ids) {
return (dispatch) => {
- return fetch('/v1/item/' + ids)
+ return fetch(`/v1/item/${ ids}`)
.then(
response => {
return response.ok ? response.json()
- : Promise.reject(response.status + ' ' + response.statusText)
+ : Promise.reject(`${response.status } ${ response.statusText}`);
}
)
.then((json) => {
- for (var i = 0; i < json.items.length; i++) {
- dispatch(addItem(json.items[i]))
+ for (let i = 0; i < json.items.length; i++) {
+ dispatch(addItem(json.items[i]));
}
- return json.items
- })
- }
+ return json.items;
+ });
+ };
}
/*
@@ -173,7 +169,7 @@ export function getItemsArray (ids) {
export function postItem (item, type, id) {
return (dispatch) => {
if (id) {
- item.id = id
+ item.id = id;
}
let options = {
method: 'POST',
@@ -181,20 +177,20 @@ export function postItem (item, type, id) {
headers: {
'Content-Type':'application/json'
}
- }
+ };
console.log('postItem', options);
- return fetch('/api/v1/' + type, options)
+ return fetch(`/api/v1/${ type}`, options)
.then(
response => {
return response.ok ? response.json()
- : Promise.reject(response.status + ' ' + response.statusText)
+ : Promise.reject(`${response.status } ${ response.statusText}`);
}
)
.then((json) => {
- dispatch(addItem({...item, id:json.id}))
- return json.id
- })
- }
+ dispatch(addItem({...item, id:json.id}));
+ return json.id;
+ });
+ };
}
//http://localhost:16180/v1/action/flag/user/user_89654/on/item/87e418c5-aafb-4eb7-9ce4-78f28793782a
@@ -219,19 +215,19 @@ export function postAction (id, type, user_id) {
const action = {
type,
user_id
- }
+ };
const options = {
method: 'POST',
body: JSON.stringify(action)
- }
+ };
- dispatch(appendItemArray(id, type, user_id))
- return fetch('/api/v1/comments/' + id + '/actions', options)
+ dispatch(appendItemArray(id, type, user_id));
+ return fetch(`/api/v1/comments/${ id }/actions`, options)
.then(
response => {
return response.ok ? response.text()
- : Promise.reject(response.status + ' ' + response.statusText)
+ : Promise.reject(`${response.status } ${ response.statusText}`);
}
- )
- }
+ );
+ };
}
diff --git a/client/coral-framework/store/actions/notification.js b/client/coral-framework/store/actions/notification.js
index 0503c2a64..c34adc414 100644
--- a/client/coral-framework/store/actions/notification.js
+++ b/client/coral-framework/store/actions/notification.js
@@ -1,18 +1,18 @@
/* Notification Actions */
-export const ADD_NOTIFICATION = 'ADD_NOTIFICATION'
-export const CLEAR_NOTIFICATION = 'CLEAR_NOTIFICATION'
+export const ADD_NOTIFICATION = 'ADD_NOTIFICATION';
+export const CLEAR_NOTIFICATION = 'CLEAR_NOTIFICATION';
export const addNotification = (notifType, text) => {
return {
type: ADD_NOTIFICATION,
notifType,
text
- }
-}
+ };
+};
export const clearNotification = () => {
return {
type: CLEAR_NOTIFICATION
- }
-}
+ };
+};
diff --git a/client/coral-framework/store/reducers/auth.js b/client/coral-framework/store/reducers/auth.js
index f25c88749..b79444cc9 100644
--- a/client/coral-framework/store/reducers/auth.js
+++ b/client/coral-framework/store/reducers/auth.js
@@ -1,17 +1,17 @@
/* Auth */
-import * as actions from '../actions/auth'
-import { fromJS } from 'immutable'
+import * as actions from '../actions/auth';
+import {fromJS} from 'immutable';
-const initialState = fromJS({})
+const initialState = fromJS({});
export default (state = initialState, action) => {
switch (action.type) {
- case actions.SET_LOGGED_IN_USER:
- return state.set('user', action.user_id)
- case actions.LOG_OUT_USER:
- return initialState
- default:
- return state
+ case actions.SET_LOGGED_IN_USER:
+ return state.set('user', action.user_id);
+ case actions.LOG_OUT_USER:
+ return initialState;
+ default:
+ return state;
}
-}
+};
diff --git a/client/coral-framework/store/reducers/config.js b/client/coral-framework/store/reducers/config.js
index d9ee5e763..cbc131fe6 100644
--- a/client/coral-framework/store/reducers/config.js
+++ b/client/coral-framework/store/reducers/config.js
@@ -1,25 +1,25 @@
/* @flow */
-import { Map, fromJS } from 'immutable'
-import * as actions from '../actions/config'
+import {Map} from 'immutable';
+import * as actions from '../actions/config';
const initialState = Map({
features: Map({})
-})
+});
export default (state = initialState, action) => {
switch(action.type) {
- case actions.FETCH_CONFIG_REQUEST:
- return state.set('loading', true)
+ case actions.FETCH_CONFIG_REQUEST:
+ return state.set('loading', true);
- case actions.FETCH_CONFIG_FAILED:
- return state.set('loading', false)
+ case actions.FETCH_CONFIG_FAILED:
+ return state.set('loading', false);
// Override config if worked
- case actions.FETCH_CONFIG_SUCCESS:
- return action.config.set('loading', false)
+ case actions.FETCH_CONFIG_SUCCESS:
+ return action.config.set('loading', false);
- default:
- return state
+ default:
+ return state;
}
-}
+};
diff --git a/client/coral-framework/store/reducers/index.js b/client/coral-framework/store/reducers/index.js
index 5774a4d9d..b38de61ae 100644
--- a/client/coral-framework/store/reducers/index.js
+++ b/client/coral-framework/store/reducers/index.js
@@ -1,10 +1,10 @@
/* @flow */
-import { combineReducers } from 'redux'
-import config from './config'
-import items from './items'
-import notification from './notification'
-import auth from './auth'
+import {combineReducers} from 'redux';
+import config from './config';
+import items from './items';
+import notification from './notification';
+import auth from './auth';
/**
* Expose the combined main reducer
@@ -15,4 +15,4 @@ export default combineReducers({
items,
notification,
auth
-})
+});
diff --git a/client/coral-framework/store/reducers/items.js b/client/coral-framework/store/reducers/items.js
index d3eb4d3af..77ee44130 100644
--- a/client/coral-framework/store/reducers/items.js
+++ b/client/coral-framework/store/reducers/items.js
@@ -1,29 +1,29 @@
/* Items Reducer */
-import { Map, fromJS } from 'immutable'
-import * as actions from '../actions/items'
+import {fromJS} from 'immutable';
+import * as actions from '../actions/items';
-const initialState = fromJS({})
+const initialState = fromJS({});
export default (state = initialState, action) => {
switch (action.type) {
- case actions.ADD_ITEM:
- return state.set(action.id, fromJS(action.item))
- case actions.UPDATE_ITEM:
- return state.updateIn([action.id, action.property], () =>
+ case actions.ADD_ITEM:
+ return state.set(action.id, fromJS(action.item));
+ case actions.UPDATE_ITEM:
+ return state.updateIn([action.id, action.property], () =>
fromJS(action.value)
- )
- case actions.APPEND_ITEM_ARRAY:
- return state.updateIn([action.id, action.property], (prop) => {
- if (action.addToFront) {
- return prop ? prop.unshift(action.value) : fromJS([action.value])
- } else {
- return prop ? prop.push(action.value) : fromJS([action.value])
- }
-
+ );
+ case actions.APPEND_ITEM_ARRAY:
+ return state.updateIn([action.id, action.property], (prop) => {
+ if (action.addToFront) {
+ return prop ? prop.unshift(action.value) : fromJS([action.value]);
+ } else {
+ return prop ? prop.push(action.value) : fromJS([action.value]);
}
- )
- default:
- return state
+
+ }
+ );
+ default:
+ return state;
}
-}
+};
diff --git a/client/coral-framework/store/reducers/notification.js b/client/coral-framework/store/reducers/notification.js
index 86c65c9e7..ea8b4889d 100644
--- a/client/coral-framework/store/reducers/notification.js
+++ b/client/coral-framework/store/reducers/notification.js
@@ -1,17 +1,17 @@
/* Items Notifications */
-import * as actions from '../actions/notification'
-import { fromJS } from 'immutable'
+import * as actions from '../actions/notification';
+import {fromJS} from 'immutable';
-const initialState = fromJS({})
+const initialState = fromJS({});
export default (state = initialState, action) => {
switch (action.type) {
- case actions.ADD_NOTIFICATION:
- return state.set('text', action.text).set('type', action.notifType)
- case actions.CLEAR_NOTIFICATION:
- return initialState
- default:
- return state
+ case actions.ADD_NOTIFICATION:
+ return state.set('text', action.text).set('type', action.notifType);
+ case actions.CLEAR_NOTIFICATION:
+ return initialState;
+ default:
+ return state;
}
-}
+};
diff --git a/client/coral-framework/store/store.js b/client/coral-framework/store/store.js
index 42678cddd..33cc9efb5 100644
--- a/client/coral-framework/store/store.js
+++ b/client/coral-framework/store/store.js
@@ -1,10 +1,10 @@
-import { createStore, applyMiddleware } from 'redux'
-import thunk from 'redux-thunk'
-import mainReducer from './reducers'
+import {createStore, applyMiddleware} from 'redux';
+import thunk from 'redux-thunk';
+import mainReducer from './reducers';
export default createStore(
mainReducer,
window.devToolsExtension && window.devToolsExtension(),
applyMiddleware(thunk)
-)
+);
diff --git a/client/coral-plugin-author-name/AuthorName.js b/client/coral-plugin-author-name/AuthorName.js
index 04817da1c..ddfd40ccf 100644
--- a/client/coral-plugin-author-name/AuthorName.js
+++ b/client/coral-plugin-author-name/AuthorName.js
@@ -1,9 +1,9 @@
-import React from 'react'
-const packagename = 'coral-plugin-author-name'
+import React from 'react';
+const packagename = 'coral-plugin-author-name';
const AuthorName = ({name}) =>
-;
-export default AuthorName
+export default AuthorName;
diff --git a/client/coral-plugin-comment-count/CommentCount.js b/client/coral-plugin-comment-count/CommentCount.js
index 01a5c602b..b0d7312e2 100644
--- a/client/coral-plugin-comment-count/CommentCount.js
+++ b/client/coral-plugin-comment-count/CommentCount.js
@@ -1,23 +1,23 @@
-import React from 'react'
+import React from 'react';
-const name = 'coral-plugin-comment-count'
+const name = 'coral-plugin-comment-count';
const CommentCount = ({items, id}) => {
- let count = 0
+ let count = 0;
if (items[id]) {
- count += items[id].comments.length
+ count += items[id].comments.length;
}
- const itemKeys = Object.keys(items)
- for (var i=0; i < itemKeys.length; i++) {
- const item = items[itemKeys[i]]
+ const itemKeys = Object.keys(items);
+ for (let i = 0; i < itemKeys.length; i++) {
+ const item = items[itemKeys[i]];
if (item.children) {
- count += item.children.length
+ count += item.children.length;
}
}
- return
- {count + ' ' + (count === 1 ? 'Comment':'Comments')}
-
-}
+ return
+ {`${count } ${ count === 1 ? 'Comment' : 'Comments'}`}
+
;
+};
-export default CommentCount
+export default CommentCount;
diff --git a/client/coral-plugin-commentbox/CommentBox.js b/client/coral-plugin-commentbox/CommentBox.js
index 0f1578859..cf428fac2 100644
--- a/client/coral-plugin-commentbox/CommentBox.js
+++ b/client/coral-plugin-commentbox/CommentBox.js
@@ -1,7 +1,7 @@
-import React, {Component, PropTypes} from 'react'
-import {I18n} from '../coral-framework'
+import React, {Component, PropTypes} from 'react';
+import {I18n} from '../coral-framework';
-const name='coral-plugin-commentbox'
+const name = 'coral-plugin-commentbox';
class CommentBox extends Component {
@@ -19,35 +19,35 @@ class CommentBox extends Component {
}
postComment = () => {
- const {postItem, updateItem, id, parent_id, addNotification, appendItemArray} = this.props
+ const {postItem, updateItem, id, parent_id, addNotification, appendItemArray} = this.props;
let comment = {
body: this.state.body,
asset_id: id,
username: this.state.username
- }
- let related
+ };
+ let related;
if (parent_id) {
- comment.parent_id = parent_id
- related = 'children'
+ comment.parent_id = parent_id;
+ related = 'children';
} else {
- related = 'comments'
+ related = 'comments';
}
- updateItem(parent_id, 'showReply', false)
+ updateItem(parent_id, 'showReply', false);
postItem(comment, 'comments')
.then((comment_id) => {
- appendItemArray(parent_id || id, related, comment_id, parent_id ? false : true)
- addNotification('success', 'Your comment has been posted.')
- }).catch((err) => console.error(err))
- this.setState({body: ''})
+ appendItemArray((parent_id || id, related, comment_id, parent_id));
+ addNotification('success', 'Your comment has been posted.');
+ }).catch((err) => console.error(err));
+ this.setState({body: ''});
}
render () {
- const {styles, reply} = this.props
+ const {styles, reply} = this.props;
// How to handle language in plugins? Should we have a dependency on our central translation file?
return
-
+
this.setState({username: e.target.value})}/>
+ className={`${name }-container`}>
-
+
;
}
}
-export default CommentBox
+export default CommentBox;
const lang = new I18n({
en: {
@@ -96,4 +96,4 @@ const lang = new I18n({
reply: 'Respuesta',
comment: 'Comentario'
}
-})
+});
diff --git a/client/coral-plugin-commentbox/__tests__/commentBox.spec.js b/client/coral-plugin-commentbox/__tests__/commentBox.spec.js
index 4a1b5b397..92e085c79 100644
--- a/client/coral-plugin-commentbox/__tests__/commentBox.spec.js
+++ b/client/coral-plugin-commentbox/__tests__/commentBox.spec.js
@@ -1,26 +1,26 @@
-import React from 'react'
-import {shallow, mount} from 'enzyme'
-import {expect} from 'chai'
-import CommentBox from '../CommentBox'
+import React from 'react';
+import {shallow} from 'enzyme';
+import {expect} from 'chai';
+import CommentBox from '../CommentBox';
describe('CommentBox', () => {
- let comment
- let render
+ let comment;
+ let render;
beforeEach(() => {
- comment = {}
+ comment = {};
const postItem = (item) => {
- comment.posted=item
- return Promise.resolve(4)
- }
+ comment.posted = item;
+ return Promise.resolve(4);
+ };
render = shallow(
comment.text=e.target.value}
+ updateItem={(e) => comment.text = e.target.value}
item_id={'1'}
- comments={['1', '2', '3']}/>)
- })
+ comments={['1', '2', '3']}/>);
+ });
it('should render the CommentBox appropriately', () => {
- expect(render.contains(';
+};
-export default Content
+export default Content;
diff --git a/client/coral-plugin-commentcontent/__tests__/commentContent.spec.js b/client/coral-plugin-commentcontent/__tests__/commentContent.spec.js
index 56cc233db..377726b6d 100644
--- a/client/coral-plugin-commentcontent/__tests__/commentContent.spec.js
+++ b/client/coral-plugin-commentcontent/__tests__/commentContent.spec.js
@@ -1,11 +1,11 @@
-import React from 'react'
-import {shallow, mount} from 'enzyme'
-import {expect} from 'chai'
-import CommentContent from '../CommentContent'
+import React from 'react';
+import {shallow} from 'enzyme';
+import {expect} from 'chai';
+import CommentContent from '../CommentContent';
describe('CommentContent', () => {
it('should render content', () => {
- const render = shallow()
- expect(render.contains('test')).to.be.truthy
- })
-})
+ const render = shallow();
+ expect(render.contains('test')).to.be.truthy;
+ });
+});
diff --git a/client/coral-plugin-flags/FlagButton.js b/client/coral-plugin-flags/FlagButton.js
index 0c5bbcbc5..ae6782d78 100644
--- a/client/coral-plugin-flags/FlagButton.js
+++ b/client/coral-plugin-flags/FlagButton.js
@@ -1,29 +1,29 @@
-import React from 'react'
+import React from 'react';
-const name='coral-plugin-flags'
+const name = 'coral-plugin-flags';
const FlagButton = ({flag, item_id, postAction, currentUser, addNotification}) => {
- const flagged = flag && flag.includes(currentUser)
+ const flagged = flag && flag.includes(currentUser);
const onFlagClick = () => {
- postAction(item_id, 'flag', currentUser)
- addNotification('success', 'Thank you for reporting this comment. Our moderation team has been notified and will review it shortly.')
+ postAction(item_id, 'flag', currentUser);
+ addNotification('success', 'Thank you for reporting this comment. Our moderation team has been notified and will review it shortly.');
- }
- return
-
-}
+ ;
+};
-export default FlagButton
+export default FlagButton;
const styles = {
flaggedIcon: {
@@ -32,4 +32,4 @@ const styles = {
unflaggedIcon: {
color: 'inherit'
}
-}
+};
diff --git a/client/coral-plugin-pubdate/PubDate.js b/client/coral-plugin-pubdate/PubDate.js
index bc96c9601..81c8495a4 100644
--- a/client/coral-plugin-pubdate/PubDate.js
+++ b/client/coral-plugin-pubdate/PubDate.js
@@ -1,11 +1,11 @@
-import React from 'react'
-import {I18n} from '../coral-framework'
+import React from 'react';
+import {I18n} from '../coral-framework';
-const lang = new I18n()
-const name = 'coral-plugin-pubdate'
+const lang = new I18n();
+const name = 'coral-plugin-pubdate';
-const PubDate = ({created_at}) =>
+const PubDate = ({created_at}) =>
{lang.timeago(created_at)}
-
+
;
-export default PubDate
+export default PubDate;
diff --git a/client/coral-plugin-replies/ReplyBox.js b/client/coral-plugin-replies/ReplyBox.js
index 6ecd9eef3..cd226181b 100644
--- a/client/coral-plugin-replies/ReplyBox.js
+++ b/client/coral-plugin-replies/ReplyBox.js
@@ -1,10 +1,10 @@
-import React from 'react'
-import CommentBox from '../coral-plugin-commentbox/CommentBox'
+import React from 'react';
+import CommentBox from '../coral-plugin-commentbox/CommentBox';
-const name = 'coral-plugin-replies'
+const name = 'coral-plugin-replies';
const ReplyBox = (props) =>
{
props.showReply &&
}
-
+ ;
-export default ReplyBox
+export default ReplyBox;
diff --git a/client/coral-plugin-replies/ReplyButton.js b/client/coral-plugin-replies/ReplyButton.js
index 157d24aaf..382173a5a 100644
--- a/client/coral-plugin-replies/ReplyButton.js
+++ b/client/coral-plugin-replies/ReplyButton.js
@@ -1,17 +1,17 @@
-import React from 'react'
-import {I18n} from '../coral-framework'
+import React from 'react';
+import {I18n} from '../coral-framework';
-const name = 'coral-plugin-replies'
+const name = 'coral-plugin-replies';
const ReplyButton = (props) => props.updateItem(props.id || props.parent_id, 'showReply', true)}>
- props.updateItem(props.id || props.parent_id, 'showReply', true)}>
+ reply
{lang.t('reply')}
-
+;
-export default ReplyButton
+export default ReplyButton;
const lang = new I18n({
en: {
@@ -20,4 +20,4 @@ const lang = new I18n({
es: {
'reply': '¡traduceme!'
}
-})
+});
diff --git a/client/coral-plugin-replies/index.js b/client/coral-plugin-replies/index.js
index ce2446ab0..2eff814d8 100644
--- a/client/coral-plugin-replies/index.js
+++ b/client/coral-plugin-replies/index.js
@@ -1,7 +1,7 @@
-import ReplyBox from './ReplyBox'
-import ReplyButton from './ReplyButton'
+import ReplyBox from './ReplyBox';
+import ReplyButton from './ReplyButton';
export {
ReplyBox,
ReplyButton
-}
+};
diff --git a/package.json b/package.json
index b2e7b938b..d24ac8a0a 100644
--- a/package.json
+++ b/package.json
@@ -55,6 +55,8 @@
"uuid": "^2.0.3"
},
"devDependencies": {
+ "babel-eslint": "^7.1.0",
+ "babel-jest": "^15.0.0",
"autoprefixer": "^6.5.0",
"babel-core": "^6.18.2",
"babel-loader": "^6.2.7",
@@ -71,6 +73,7 @@
"copy-webpack-plugin": "^4.0.0",
"css-loader": "^0.25.0",
"eslint": "^3.9.1",
+ "eslint-plugin-react": "^6.6.0",
"exports-loader": "^0.6.3",
"hammerjs": "^2.0.8",
"immutable": "^3.8.1",