Merge branch 'master' into ban-user

This commit is contained in:
gaba
2016-12-08 09:22:22 -10:00
9 changed files with 79 additions and 24 deletions
+36 -9
View File
@@ -67,24 +67,44 @@ class CommentStream extends Component {
// Set up messaging between embedded Iframe an parent component
this.pym = new Pym.Child({polling: 100});
const path = /https?\:\/\/([^?#]+)/.exec(this.pym.parentUrl);
const path = this.pym.parentUrl.split('#')[0];
this.props.getStream(path[1] || window.location);
this.props.getStream(path || window.location);
this.path = path;
this.pym.sendMessage('childReady');
this.pym.onMessage('DOMContentLoaded', hash => {
const commentId = hash.replace('#', 'c_');
let count = 0;
const interval = setInterval(() => {
if (document.getElementById(commentId)) {
window.clearInterval(interval);
this.pym.scrollParentToChildEl(commentId);
}
if (++count > 100) { // ~10 seconds
// give up waiting for the comments to load.
// it would be weird for the page to jump after that long.
window.clearInterval(interval);
}
}, 100);
});
}
render () {
const rootItemId = this.props.items.assets && Object.keys(this.props.items.assets)[0];
const rootItem = this.props.items.assets && this.props.items.assets[rootItemId];
const {actions, users, comments} = this.props.items;
const {loggedIn, user, showSignInDialog} = this.props.auth;
const {loggedIn, user, showSignInDialog, signInOffset} = this.props.auth;
const {status} = this.props.config;
const {activeTab} = this.state;
const banned = (this.props.userData.status === 'banned');
return <div className={showSignInDialog ? 'expandForSignin' : ''}>
const expandForLogin = showSignInDialog ? {
minHeight: document.body.scrollHeight + 150
} : {};
return <div style={expandForLogin}>
{
rootItem
? <div className="commentStream">
@@ -108,17 +128,18 @@ class CommentStream extends Component {
postItem={this.props.postItem}
appendItemArray={this.props.appendItemArray}
updateItem={this.props.updateItem}
currentUser={this.props.auth.user}
banned={banned}
id={rootItemId}
premod={this.props.config.moderation}
reply={false}
author={user}/>
currentUser={this.props.auth.user}
banned={banned}
author={user}
/>
</RestrictedContent>
</div>
: <p>Comments are closed for this thread.</p>
}
{!loggedIn && <SignInContainer />}
{!loggedIn && <SignInContainer offset={signInOffset} />}
{
rootItem.comments && rootItem.comments.map((commentId) => {
const comment = comments[commentId];
@@ -256,6 +277,12 @@ class CommentStream extends Component {
<CloseCommentsInfo onClick={this.toggleStatus} status={status} />
</RestrictedContent>
</TabContent>
<TabContent show={activeTab === 2}>
<h3>{status === 'open' ? 'Close' : 'Open'} Comment Stream</h3>
<RestrictedContent restricted={!loggedIn}>
<CloseCommentsInfo onClick={this.toggleStatus} status={status} />
</RestrictedContent>
</TabContent>
<Notification
notifLength={4500}
clearNotification={this.props.clearNotification}
@@ -284,7 +311,7 @@ const mapDispatchToProps = (dispatch) => ({
getStream: (rootId) => dispatch(getStream(rootId)),
addNotification: (type, text) => dispatch(addNotification(type, text)),
clearNotification: () => dispatch(clearNotification()),
showSignInDialog: () => dispatch(showSignInDialog()),
showSignInDialog: (offset) => dispatch(showSignInDialog(offset)),
postAction: (item, action, user, itemType) => dispatch(postAction(item, action, user, itemType)),
deleteAction: (item, action, user, itemType) => dispatch(deleteAction(item, action, user, itemType)),
appendItemArray: (item, property, value, addToFront, itemType) => dispatch(appendItemArray(item, property, value, addToFront, itemType)),
+1 -2
View File
@@ -8,7 +8,7 @@ body {
}
.expandForSignin {
min-height: 550px;
min-height: 600px;
}
button {
@@ -113,7 +113,6 @@ hr {
/* Comment styles */
.comment {
position: relative;
margin-bottom: 10px;
position: relative;
}
+1 -1
View File
@@ -6,7 +6,7 @@ import coralApi, {base} from '../helpers/response';
import {addItem} from './items';
// Dialog Actions
export const showSignInDialog = () => ({type: actions.SHOW_SIGNIN_DIALOG});
export const showSignInDialog = (offset = 0) => ({type: actions.SHOW_SIGNIN_DIALOG, offset});
export const hideSignInDialog = () => ({type: actions.HIDE_SIGNIN_DIALOG});
export const changeView = view => dispatch =>
+2 -1
View File
@@ -22,7 +22,8 @@ export default function auth (state = initialState, action) {
switch (action.type) {
case actions.SHOW_SIGNIN_DIALOG :
return state
.set('showSignInDialog', true);
.set('showSignInDialog', true)
.set('signInOffset', action.offset);
case actions.HIDE_SIGNIN_DIALOG :
return state.merge(Map({
isLoading: false,
+2 -1
View File
@@ -8,7 +8,8 @@ const FlagButton = ({flag, id, postAction, deleteAction, addItem, showSignInDial
const flagged = flag && flag.current_user;
const onFlagClick = () => {
if (!currentUser) {
showSignInDialog();
const offset = document.getElementById(`c_${id}`).getBoundingClientRect().top - 75;
showSignInDialog(offset);
return;
}
if (banned) {
+2 -1
View File
@@ -8,7 +8,8 @@ const LikeButton = ({like, id, postAction, deleteAction, addItem, showSignInDial
const liked = like && like.current_user;
const onLikeClick = () => {
if (!currentUser) {
showSignInDialog();
const offset = document.getElementById(`c_${id}`).getBoundingClientRect().top - 75;
showSignInDialog(offset);
return;
}
if (banned) {
@@ -6,8 +6,14 @@ import SignInContent from './SignInContent';
import SingUpContent from './SignUpContent';
import ForgotContent from './ForgotContent';
const SignDialog = ({open, view, handleClose, ...props}) => (
<Dialog className={styles.dialog} open={open}>
const SignDialog = ({open, view, handleClose, offset, ...props}) => (
<Dialog
className={styles.dialog}
open={open}
style={{
position: 'relative',
top: offset !== 0 && offset
}}>
<span className={styles.close} onClick={handleClose}>×</span>
{view === 'SIGNIN' && <SignInContent {...props} />}
{view === 'SIGNUP' && <SingUpContent {...props} />}
@@ -129,7 +129,7 @@ class SignInContainer extends Component {
}
render() {
const {auth, showSignInDialog, noButton} = this.props;
const {auth, showSignInDialog, noButton, offset} = this.props;
return (
<div>
{!noButton && <Button id='coralSignInButton' onClick={showSignInDialog} full>
@@ -138,6 +138,7 @@ class SignInContainer extends Component {
<SignDialog
open={auth.showSignInDialog}
view={auth.view}
offset={offset}
{...this}
{...this.state}
{...this.props}
+25 -6
View File
@@ -1,17 +1,36 @@
const nodemailer = require('nodemailer');
if (!process.env.TALK_SMTP_USERNAME || !process.env.TALK_SMTP_PASSWORD) {
console.error('TALK_SMTP_USERNAME and TALK_SMTP_PASSWORD should be defined if you would like to send password reset emails from Talk');
}
const smtpRequiredProps = [
'TALK_SMTP_USERNAME',
'TALK_SMTP_PASSWORD',
'TALK_SMTP_PROVIDER'
];
const defaultTransporter = nodemailer.createTransport({
smtpRequiredProps.forEach(prop => {
if (!process.env[prop]) {
console.error(`process.env.${prop} should be defined if you would like to send password reset emails from Talk`);
}
});
const options = {
// list of providers here:
// https://github.com/nodemailer/nodemailer-wellknown#supported-services
service: 'SendGrid',
service: process.env.TALK_SMTP_PROVIDER,
auth: {
user: process.env.TALK_SMTP_USERNAME,
pass: process.env.TALK_SMTP_PASSWORD
}
});
};
if (process.env.TALK_SMTP_PORT) {
options.port = process.env.TALK_SMTP_PORT;
}
if (process.env.TALK_SMTP_HOST) {
options.host = process.env.TALK_SMTP_HOST;
}
const defaultTransporter = nodemailer.createTransport(options);
const mailer = {