Merge branch 'master' into no-reply-closed-streams

This commit is contained in:
David Erwin
2017-03-22 10:45:02 -04:00
committed by GitHub
8 changed files with 45 additions and 22 deletions
+2
View File
@@ -41,6 +41,8 @@ Facebook Login enabled app.
- `TALK_SMTP_HOST` (*required for email*) - SMTP host url with format `smtp.domain.com`.
- `TALK_SMTP_PORT` (*required for email*) - SMTP port.
- `TALK_INSTALL_LOCK` (_optional for dynamic setup_) - Defaults to `FALSE`. When `TRUE`, disables the dynamic setup endpoint.
- `TALK_RECAPTCHA_SECRET` (*required for reCAPTCHA support*) - server secret used for enabling reCAPTCHA powered logins. If not provided it will instead default to providing only a time based lockout.
- `TALK_RECAPTCHA_PUBLIC` (*required for reCAPTCHA support*) - client secret used for enabling reCAPTCHA powered logins. If not provided it will instead default to providing only a time based lockout.
Refer to the wiki page on [Configuration Loading](https://github.com/coralproject/talk/wiki/Configuration-Loading) for
alternative methods of loading configuration during development.
@@ -2,13 +2,14 @@ import React, {Component} from 'react';
import styles from './Stories.css';
import {connect} from 'react-redux';
import I18n from 'coral-framework/modules/i18n/i18n';
import {fetchAssets, updateAssetState} from '../../actions/assets';
import translations from '../../translations.json';
import {fetchAssets, updateAssetState} from 'coral-admin/src/actions/assets';
import translations from 'coral-admin/src/translations.json';
import {Link} from 'react-router';
import {Pager, Icon} from 'coral-ui';
import {DataTable, TableHeader, RadioGroup, Radio} from 'react-mdl';
import EmptyCard from 'coral-admin/src/components/EmptyCard';
import sortBy from 'lodash/sortBy';
const limit = 25;
@@ -104,7 +105,11 @@ class Stories extends Component {
const {search, sort, filter} = this.state;
const {assets} = this.props;
const assetsIds = assets.ids.map((id) => assets.byId[id]);
const assetsIds = sortBy(assets.ids.map((id) => assets.byId[id]), 'publication_date');
if (this.state.sort === 'desc') {
assetsIds.reverse();
}
return (
<div className={styles.container}>
+9 -4
View File
@@ -23,8 +23,13 @@ export default function assets (state = initialState, action) {
}
const replaceAssets = (action, state) => {
const assets = fromJS(action.assets.reduce((prev, curr) => { prev[curr.id] = curr; return prev; }, {}));
return state.set('byId', assets)
.set('count', action.count)
.set('ids', List(assets.keys()));
const assets = fromJS(action.assets.reduce((prev, curr) => {
prev[curr.id] = curr;
return prev;
}, {}));
return state
.set('byId', assets)
.set('count', action.count)
.set('ids', List(assets.keys()));
};
+2 -1
View File
@@ -157,6 +157,7 @@ class Comment extends React.Component {
? <TagLabel><BestIndicator /></TagLabel>
: null }
<PubDate created_at={comment.created_at} />
<Content body={comment.body} />
<div className="commentActionsLeft comment__action-container">
<ActionButton>
@@ -238,7 +239,7 @@ class Comment extends React.Component {
removeCommentTag={removeCommentTag}
showSignInDialog={showSignInDialog}
reactKey={reply.id}
key={`${reply.id}:${depth}`}
key={reply.id}
comment={reply} />;
})
}
+1 -1
View File
@@ -225,7 +225,7 @@ class Embed extends Component {
topLevel={true}
assetId={asset.id}
comments={asset.comments}
moreComments={asset.commentCount > asset.comments.length}
moreComments={countCache[asset.id] > asset.comments.length}
loadMore={this.props.loadMore}/>
</TabContent>
<TabContent show={activeTab === 1}>
+6 -7
View File
@@ -7,18 +7,17 @@ const lang = new I18n(translations);
const loadMoreComments = (assetId, comments, loadMore, parentId) => {
if (!comments.length) {
return;
let cursor = null;
if (comments.length) {
cursor = parentId
? comments[0].created_at
: comments[comments.length - 1].created_at;
}
const cursor = parentId
? comments[0].created_at
: comments[comments.length - 1].created_at;
loadMore({
limit: ADDTL_COMMENTS_ON_LOAD_MORE,
cursor,
assetId,
asset_id: assetId,
parent_id: parentId,
sort: parentId ? 'CHRONOLOGICAL' : 'REVERSE_CHRONOLOGICAL'
});
@@ -3,6 +3,8 @@ import STREAM_QUERY from './streamQuery.graphql';
import LOAD_MORE from './loadMore.graphql';
import GET_COUNTS from './getCounts.graphql';
import MY_COMMENT_HISTORY from './myCommentHistory.graphql';
import uniqBy from 'lodash/uniqBy';
import sortBy from 'lodash/sortBy';
function getQueryVariable(variable) {
let query = window.location.search.substring(1);
@@ -60,10 +62,18 @@ export const loadMore = (data) => ({limit, cursor, parent_id = null, asset_id, s
...oldData,
asset: {
...oldData.asset,
comments: oldData.asset.comments.map((comment) =>
comment.id === parent_id
? {...comment, replies: [...comment.replies, ...new_top_level_comments]}
: comment)
comments: oldData.asset.comments.map(comment => {
// since the dipslayed replies and the returned replies can overlap,
// pull out the unique ones.
const uniqueReplies = uniqBy([...new_top_level_comments, ...comment.replies], 'id');
// since we just gave the returned replies precedence, they're now out of order.
// resort according to date.
return comment.id === parent_id
? {...comment, replies: sortBy(uniqueReplies, 'created_at')}
: comment;
})
}
};
} else {
+3 -2
View File
@@ -116,14 +116,15 @@ const CheckIfNeedsRecaptcha = (user, email) => {
* This stores the Recaptcha secret.
*/
const RECAPTCHA_SECRET = process.env.TALK_RECAPTCHA_SECRET;
const RECAPTCHA_PUBLIC = process.env.TALK_RECAPTCHA_PUBLIC;
/**
* This is true when the recaptcha secret is provided and the Recaptcha feature
* is to be enabled.
*/
const RECAPTCHA_ENABLED = RECAPTCHA_SECRET && RECAPTCHA_SECRET.length > 0;
const RECAPTCHA_ENABLED = RECAPTCHA_SECRET && RECAPTCHA_SECRET.length > 0 && RECAPTCHA_PUBLIC && RECAPTCHA_PUBLIC.length > 0;
if (!RECAPTCHA_ENABLED) {
console.log('Recaptcha is not enabled for login/signup abuse prevention, set TALK_RECAPTCHA_SECRET to enable Recaptcha.');
console.log('Recaptcha is not enabled for login/signup abuse prevention, set TALK_RECAPTCHA_SECRET and TALK_RECAPTCHA_PUBLIC to enable Recaptcha.');
}
/**