mirror of
https://github.com/wassname/talk.git
synced 2026-07-11 03:37:01 +08:00
Merge pull request #66 from coralproject/site-wide-comments
Site wide comments
This commit is contained in:
@@ -77,28 +77,16 @@ 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 <div>
|
||||
{
|
||||
@@ -121,7 +109,7 @@ class CommentStream extends Component {
|
||||
reply={false}/>
|
||||
</div>
|
||||
{
|
||||
rootItem.comments.map((commentId) => {
|
||||
rootItem.comments && rootItem.comments.map((commentId) => {
|
||||
const comment = this.props.items.comments[commentId];
|
||||
return <div className="comment" key={commentId}>
|
||||
<hr aria-hidden={true}/>
|
||||
|
||||
@@ -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++ ) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -3,35 +3,45 @@ const express = require('express');
|
||||
const Comment = require('../../../models/comment');
|
||||
const User = require('../../../models/user');
|
||||
const Action = require('../../../models/action');
|
||||
const Asset = require('../../../models/asset');
|
||||
|
||||
const Setting = require('../../../models/setting');
|
||||
|
||||
const router = express.Router();
|
||||
|
||||
// Find all the comments by a specific asset_id.
|
||||
// Find all the comments by a specific asset_url.
|
||||
// . if pre: get the comments that are accepted.
|
||||
// . if post: get the comments that are new and accepted.
|
||||
router.get('/', (req, res, next) => {
|
||||
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
|
||||
|
||||
@@ -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;
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -17,7 +17,12 @@
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="coralStream"></div>
|
||||
<script src="<%= basePath %>/bundle.js" charset="utf-8"></script>
|
||||
<div id='coralStreamEmbed'></div>
|
||||
<script type='text/javascript' src='https://pym.nprapps.org/pym.v1.min.js'></script>
|
||||
<script>
|
||||
var pymParent = new pym.Parent('coralStreamEmbed', '/embed/stream', {title: 'Talk Comments'});
|
||||
pymParent.onMessage('height', function(height) {document.querySelector('#coralStreamEmbed iframe').height = height + 'px'})</script>
|
||||
</div>
|
||||
</body>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Reference in New Issue
Block a user