diff --git a/client/coral-admin/src/containers/ModerationQueue.js b/client/coral-admin/src/containers/ModerationQueue.js
index 9178bda57..cfc48ae6b 100644
--- a/client/coral-admin/src/containers/ModerationQueue.js
+++ b/client/coral-admin/src/containers/ModerationQueue.js
@@ -6,7 +6,7 @@ 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 translations from '../translations.json';
/*
* Renders the moderation queue as a tabbed layout with 3 moderation
@@ -91,7 +91,7 @@ class ModerationQueue extends React.Component {
commentIds={
comments
.get('ids')
- .filter(id =>
+ .filter(id =>
comments
.get('byId')
.get(id)
diff --git a/client/coral-admin/src/translations.js b/client/coral-admin/src/translations.js
deleted file mode 100644
index fa655294a..000000000
--- a/client/coral-admin/src/translations.js
+++ /dev/null
@@ -1,55 +0,0 @@
-export default {
- en: {
- 'community': {
- username_and_email: 'Username and Email',
- account_creation_date: 'Account Creation Date',
- newsroom_role: 'Newsroom Role',
- admin: 'Administrator',
- moderator: 'Moderator',
- role: 'Select role...'
- },
- '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'
- },
- 'embedlink': {
- 'copy': 'Copy to Clipboard'
- }
- },
- es: {
- 'community': {
- username_and_email: 'Usuario y E-mail',
- account_creation_date: 'Fecha de creación de la cuenta',
- newsroom_role: 'Rol en la redacción',
- admin: 'Administrador',
- moderator: 'Moderador',
- role: 'Select role...'
- },
- 'modqueue': {
- 'pending': 'pendiente',
- 'rejected': 'rechazado',
- 'flagged': 'marcado',
- 'shortcuts': 'Atajos de teclado',
- 'close': 'Cerrar'
- },
- 'comment': {
- 'flagged': 'marcado',
- 'anon': 'Anónimo'
- }
- }
-};
diff --git a/client/coral-admin/src/translations.json b/client/coral-admin/src/translations.json
new file mode 100644
index 000000000..dd959172b
--- /dev/null
+++ b/client/coral-admin/src/translations.json
@@ -0,0 +1,81 @@
+{
+ "en": {
+ "community": {
+ "username_and_email": "Username and Email",
+ "account_creation_date": "Account Creation Date",
+ "newsroom_role": "Newsroom Role",
+ "admin": "Administrator",
+ "moderator": "Moderator",
+ "role": "Select role..."
+ },
+ "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"
+ },
+ "embedlink": {
+ "copy": "Copy to Clipboard"
+ },
+ "configure": {
+ "enable-pre-moderation": "Enable pre-moderation",
+ "include-comment-stream": "Include Comment Stream Description for Readers.",
+ "include-comment-stream-desc": "Write a message to be added to the top of your comment stream. Pose a topic, include community guidelines, etc.",
+ "include-text": "Include your text here.",
+ "comment-settings": "Comment Settings",
+ "embed-comment-stream": "Embed Comment Stream",
+ "save-changes": "Save Changes",
+ "copy-and-paste": "Copy and paste code below into your CMS to embed your comment box in your articles",
+ "moderate": "Moderate",
+ "configure": "Configure",
+ "community": "Community"
+ }
+ },
+ "es": {
+ "community": {
+ "username_and_email": "Usuario y E-mail",
+ "account_creation_date": "Fecha de creación de la cuenta",
+ "newsroom_role": "Rol en la redacción",
+ "admin": "Administrador",
+ "moderator": "Moderador",
+ "role": "Select role..."
+ },
+ "modqueue": {
+ "pending": "pendiente",
+ "rejected": "rechazado",
+ "flagged": "marcado",
+ "shortcuts": "Atajos de teclado",
+ "close": "Cerrar"
+ },
+ "comment": {
+ "flagged": "marcado",
+ "anon": "Anónimo"
+ },
+ "configure": {
+ "enable-pre-moderation": "Habilitar pre-moderación",
+ "include-comment-stream": "Incluir la Descripción a un Hilo de Comentario para los y las Lectoras.",
+ "include-comment-stream-desc": "Escribir un mensaje que será agregado a la parte de arriba del tu hilo de comentarios. Por ejemplo, un tema, guias de comunidad, etc.",
+ "include-text": "Incluir tu texto aqui.",
+ "comment-settings": "Configuración de Comentarios",
+ "embed-comment-stream": "Colocar Hilo de Comentarios",
+ "save-changes": "Guardar Cambios",
+ "copy-and-paste": "Copiar y pegar el código de más abajo en tu CMS para colocar la caja de comentarios en tus articulos",
+ "moderate": "Moderar",
+ "configure": "Configurar",
+ "community": "Comunidad"
+ }
+ }
+}
diff --git a/client/coral-embed-stream/src/CommentStream.js b/client/coral-embed-stream/src/CommentStream.js
index 9a1910105..ecfc6d7d2 100644
--- a/client/coral-embed-stream/src/CommentStream.js
+++ b/client/coral-embed-stream/src/CommentStream.js
@@ -7,6 +7,7 @@ import {
} from '../../coral-framework';
import {connect} from 'react-redux';
import CommentBox from '../../coral-plugin-commentbox/CommentBox';
+import InfoBox from '../../coral-plugin-infobox/InfoBox';
import Content from '../../coral-plugin-commentcontent/CommentContent';
import PubDate from '../../coral-plugin-pubdate/PubDate';
import Count from '../../coral-plugin-comment-count/CommentCount';
@@ -76,34 +77,25 @@ 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');
+ const pym = new Pym.Child({polling: 100});
+ const path = /https?\:\/\/([^?]+)/.exec(pym.parentUrl)[1];
+ this.props.getStream(path);
}
render () {
- if (Object.keys(this.props.items).length === 0) {
- // Loading mock asset
- this.props.postItem({
- comments: [],
- url: 'http://coralproject.net'
- }, 'asset', 'assetTest');
-
- // Loading mock user
- this.props.postItem({name: 'Ban Ki-Moon'}, 'user', 'user_8989')
- .then((id) => {
- this.props.setLoggedInUser(id);
- });
- }
// TODO: Replace teststream id with id from params
- const rootItemId = 'assetTest';
+ const rootItemId = this.props.items.assets && Object.keys(this.props.items.assets)[0];
const rootItem = this.props.items.assets && this.props.items.assets[rootItemId];
return
{
rootItem
?
{
- rootItem.comments.map((commentId) => {
+ rootItem.comments && rootItem.comments.map((commentId) => {
const comment = this.props.items.comments[commentId];
return
diff --git a/client/coral-embed-stream/style/default.css b/client/coral-embed-stream/style/default.css
index f68e2a0e3..2f7394d4d 100644
--- a/client/coral-embed-stream/style/default.css
+++ b/client/coral-embed-stream/style/default.css
@@ -49,6 +49,23 @@ hr {
font-weight: bold;
}
+/* Info Box Styles */
+.coral-plugin-infobox-info {
+ position: fixed;
+ top: 0;
+ border: 0;
+ background: rgb(105,105,105);
+ color: white;
+ border-radius: 2px;
+ font-weight: bold;
+ display: block;
+}
+
+.hidden {
+ visibility: hidden;
+ display: none;
+}
+
/* Comment Box Styles */
.coral-plugin-commentbox-container {
display: flex;
diff --git a/client/coral-framework/store/actions/items.js b/client/coral-framework/store/actions/items.js
index 2e7dca70f..2dad64639 100644
--- a/client/coral-framework/store/actions/items.js
+++ b/client/coral-framework/store/actions/items.js
@@ -94,9 +94,9 @@ export const appendItemArray = (id, property, value, add_to_front, item_type) =>
* @dispatches
* A set of items to the item store
*/
-export function getStream (assetId) {
+export function getStream (assetUrl) {
return (dispatch) => {
- return fetch(`/api/v1/stream?asset_id=${assetId}`, getInit('GET'))
+ return fetch(`/api/v1/stream?asset_url=${encodeURIComponent(assetUrl)}`)
.then(responseHandler)
.then((json) => {
@@ -108,6 +108,8 @@ export function getStream (assetId) {
}
}
+ const assetId = json.assets[0].id;
+
/* Sort comments by date*/
json.comments.sort((a, b) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime());
const rels = json.comments.reduce((h, item) => {
@@ -125,10 +127,7 @@ export function getStream (assetId) {
return h;
}, {rootComments: [], childComments: {}});
- dispatch(addItem({
- id: assetId,
- comments: rels.rootComments,
- }, 'assets'));
+ dispatch(updateItem(assetId, 'comments', rels.rootComments, 'assets'));
const childKeys = Object.keys(rels.childComments);
for (let i = 0; i < childKeys.length; i++ ) {
diff --git a/client/coral-plugin-comment-count/CommentCount.js b/client/coral-plugin-comment-count/CommentCount.js
index 6786d5c74..7a27c1982 100644
--- a/client/coral-plugin-comment-count/CommentCount.js
+++ b/client/coral-plugin-comment-count/CommentCount.js
@@ -5,7 +5,7 @@ const name = 'coral-plugin-comment-count';
const CommentCount = ({items, id}) => {
let count = 0;
- if (items.assets[id]) {
+ if (items.assets[id] && items.assets[id].comments) {
count += items.assets[id].comments.length;
}
const itemKeys = Object.keys(items.comments);
diff --git a/client/coral-plugin-infobox/InfoBox.js b/client/coral-plugin-infobox/InfoBox.js
new file mode 100644
index 000000000..db2ea22c4
--- /dev/null
+++ b/client/coral-plugin-infobox/InfoBox.js
@@ -0,0 +1,10 @@
+import React from 'react';
+const packagename = 'coral-plugin-infobox';
+
+const InfoBox = ({enable, content}) =>
+
+ {content}
+
;
+
+export default InfoBox;
diff --git a/client/coral-plugin-infobox/__tests__/infoBox.spec.js b/client/coral-plugin-infobox/__tests__/infoBox.spec.js
new file mode 100644
index 000000000..b8b761489
--- /dev/null
+++ b/client/coral-plugin-infobox/__tests__/infoBox.spec.js
@@ -0,0 +1,26 @@
+import React from 'react';
+import {shallow} from 'enzyme';
+import {expect} from 'chai';
+import InfoBox from '../InfoBox';
+
+describe('InfoBox', () => {
+ let comment;
+ let render;
+ beforeEach(() => {
+ comment = {};
+ const postItem = (item) => {
+ comment.posted = item;
+ return Promise.resolve(4);
+ };
+ render = shallow(
comment.text = e.target.value}
+ item_id={'1'}
+ comments={['1', '2', '3']}/>);
+ });
+
+ it('should render the InfoBox appropriately', () => {
+ expect(render.contains(' {
- const commentsPromise = Setting.getModerationSetting().then(({moderation}) => {
+
+ // Get the asset_id for this url (or create it if it doesn't exist)
+ Promise.all([
+ Asset.findOrCreateByUrl(decodeURIComponent(req.query.asset_url)),
+ Setting.getModerationSetting()
+ ])
+ .then(([asset, {moderation}]) => {
+ // Get the sitewide moderation setting and return the appropriate comments
switch(moderation){
case 'pre':
- return Comment.findAcceptedByAssetId(req.query.asset_id);
+ return Promise.all([Comment.findAcceptedByAssetId(asset.id), asset]);
case 'post':
- return Comment.findAcceptedAndNewByAssetId(req.query.asset_id);
+ return Promise.all([Comment.findAcceptedAndNewByAssetId(asset.id), asset]);
default:
throw new Error('Moderation setting not found.');
}
- });
-
+ })
// Get all the users and actions for those comments.
- commentsPromise.then(comments => {
+ .then(([comments, asset]) => {
return Promise.all([
+ [asset],
comments,
User.findByIdArray(comments.map((comment) => comment.author_id)),
Action.getActionSummaries(comments.map((comment) => comment.id))
]);
- }).then(([comments, users, actions]) => {
+ })
+ .then(([assets, comments, users, actions]) => {
res.json({
+ assets,
comments,
users,
actions
diff --git a/routes/index.js b/routes/index.js
index cde5b07c7..0c03edcc5 100644
--- a/routes/index.js
+++ b/routes/index.js
@@ -6,7 +6,11 @@ router.use('/admin', require('./admin'));
router.use('/embed', require('./embed'));
router.get('/', (req, res) => {
- return res.render('home', {});
+ return res.render('article', {title: 'Coral Talk'});
+});
+
+router.get('/assets/:asset_title', (req, res) => {
+ return res.render('article', {title: req.params.asset_title.split('-').join(' ')});
});
module.exports = router;
diff --git a/tests/client/coral-framework/store/itemActions.spec.js b/tests/client/coral-framework/store/itemActions.spec.js
index 4dbba5e82..14da38b41 100644
--- a/tests/client/coral-framework/store/itemActions.spec.js
+++ b/tests/client/coral-framework/store/itemActions.spec.js
@@ -18,8 +18,11 @@ describe('itemActions', () => {
});
describe('getStream', () => {
- const rootId = '1234';
+ const assetUrl = 'http://www.test.com';
const response = {
+ assets: [{
+ id: '1234', url: assetUrl
+ }],
comments: [
{body: 'stuff', id: '123'},
{body: 'morestuff', id: '456'}
@@ -42,17 +45,17 @@ describe('itemActions', () => {
it('should get an stream from an asset_id and send the appropriate dispatches', () => {
fetchMock.get('*', JSON.stringify(response));
- return actions.getStream(rootId)(store.dispatch)
+ return actions.getStream(assetUrl)(store.dispatch)
.then((res) => {
- expect(fetchMock.calls().matched[0][0]).to.equal('/api/v1/stream?asset_id=1234');
+ expect(fetchMock.calls().matched[0][0]).to.equal('/api/v1/stream?asset_url=http%3A%2F%2Fwww.test.com');
expect(res).to.deep.equal(response);
- expect(store.getActions()[0]).to.deep.equal({
+ expect(store.getActions()[1]).to.deep.equal({
type: actions.ADD_ITEM,
item: response.comments[0],
item_type: 'comments',
id: '123'
});
- expect(store.getActions()[1]).to.deep.equal({
+ expect(store.getActions()[2]).to.deep.equal({
type: actions.ADD_ITEM,
item: response.comments[1],
item_type: 'comments',
@@ -62,7 +65,7 @@ describe('itemActions', () => {
});
it('should handle an error', () => {
fetchMock.get('*', 404);
- return actions.getStream(rootId)(store.dispatch)
+ return actions.getStream(assetUrl)(store.dispatch)
.catch((err) => {
expect(err).to.be.truthy;
});
diff --git a/tests/models/setting.js b/tests/models/setting.js
index f50110635..3f4dc27fa 100644
--- a/tests/models/setting.js
+++ b/tests/models/setting.js
@@ -8,7 +8,7 @@ const expect = require('chai').expect;
describe('Setting: model', () => {
beforeEach(() => {
- const defaults = {id: 1, moderation: 'pre'};
+ const defaults = {id: 1};
return Setting.update({id: '1'}, {$setOnInsert: defaults}, {upsert: true});
});
@@ -18,13 +18,21 @@ describe('Setting: model', () => {
expect(settings).to.have.property('moderation').and.to.equal('pre');
});
});
+ it('should have two infoBox fields defined', () => {
+ return Setting.getSettings().then(settings => {
+ expect(settings).to.have.property('infoBoxEnable').and.to.equal(false);
+ expect(settings).to.have.property('infoBoxContent').and.to.equal('');
+ });
+ });
});
describe('#updateSettings()', () => {
it('should update the settings with a passed object', () => {
- const mockSettings = {moderation: 'post'};
+ const mockSettings = {moderation: 'post', infoBoxEnable: true, infoBoxContent: 'yeah'};
return Setting.updateSettings(mockSettings).then(updatedSettings => {
expect(updatedSettings).to.have.property('moderation').and.to.equal('post');
+ expect(updatedSettings).to.have.property('infoBoxEnable', true);
+ expect(updatedSettings).to.have.property('infoBoxContent', 'yeah');
});
});
});
diff --git a/tests/routes/api/stream/index.js b/tests/routes/api/stream/index.js
index c967cb932..009184b6b 100644
--- a/tests/routes/api/stream/index.js
+++ b/tests/routes/api/stream/index.js
@@ -11,6 +11,7 @@ chai.use(require('chai-http'));
const Action = require('../../../../models/action');
const User = require('../../../../models/user');
const Comment = require('../../../../models/comment');
+const Asset = require('../../../../models/asset');
const Setting = require('../../../../models/setting');
@@ -21,14 +22,12 @@ describe('api/stream: routes', () => {
const comments = [{
id: 'abc',
body: 'comment 10',
- asset_id: 'asset',
author_id: '',
parent_id: '',
status: 'accepted'
}, {
id: 'def',
body: 'comment 20',
- asset_id: 'asset',
author_id: '',
parent_id: '',
status: ''
@@ -66,29 +65,33 @@ describe('api/stream: routes', () => {
beforeEach(() => {
- return User
- .createLocalUsers(users)
- .then(users => {
+ return Promise.all([
+ User.createLocalUsers(users),
+ Asset.findOrCreateByUrl('http://test.com')
+ ])
+ .then(([users, asset]) => {
- comments[0].author_id = users[0].id;
- comments[1].author_id = users[1].id;
-
- return Promise.all([
- Comment.create(comments),
- Action.create(actions),
- Setting.create(settings)
- ]);
+ comments[0].author_id = users[0].id;
+ comments[1].author_id = users[1].id;
- });
+ comments[0].asset_id = asset.id;
+ comments[1].asset_id = asset.id;
+ return Promise.all([
+ Comment.create(comments),
+ Action.create(actions),
+ Setting.create(settings)
+ ]);
+ });
});
- it('should return a stream with comments, users and actions', () => {
+ it('should return a stream with comments, users and actions for an existing asset', () => {
return chai.request(app)
.get('/api/v1/stream')
- .query({'asset_id': 'asset'})
+ .query({'asset_url': 'http://test.com'})
.then(res => {
expect(res).to.have.status(200);
+ expect(res.body.assets.length).to.equal(1);
expect(res.body.comments.length).to.equal(1);
expect(res.body.users.length).to.equal(1);
expect(res.body.actions.length).to.equal(1);
diff --git a/views/home.ejs b/views/article.ejs
similarity index 61%
rename from views/home.ejs
rename to views/article.ejs
index 5654e1745..95c0d7904 100644
--- a/views/home.ejs
+++ b/views/article.ejs
@@ -1,10 +1,19 @@
+
+
+
+
+
+
+
+
-
Corem ipsal
+
<%= title %>
Lorem ipsum dolor sponge amet, consectetur adipiscing clam. Ut lobortis sollicitudin pillar a ornare. Curabitur dignissim vestibulum cay non rhoncus. Cras laoreet ante vel nunc hendrerit, shelf imperdiet neque egestas. Suspendisse aliquet iaculis fermentum. Talk volutpat, tellus posuere laoreet consequat, mi lacus laoreet massa, sed vehicula mauris velit non lectus. Integer non trust nec neque congue faucibus porttitor sit amet elkhorn.
+
Visit the moderation console
diff --git a/views/embed-stream.ejs b/views/embed-stream.ejs
index 47bda6bee..36f7ce43b 100644
--- a/views/embed-stream.ejs
+++ b/views/embed-stream.ejs
@@ -17,7 +17,12 @@
-
-
+
+
+
+
+