Merge pull request #587 from coralproject/edit-changes

Edit Consistency
This commit is contained in:
Kim Gardner
2017-05-15 16:47:33 -04:00
committed by GitHub
146 changed files with 967 additions and 1052 deletions
+7
View File
@@ -20,6 +20,8 @@
"no-template-curly-in-string": [1],
"no-unsafe-negation": [1],
"array-callback-return": [1],
"arrow-parens": ["warn", "always"],
"template-curly-spacing": "warn",
"eqeqeq": [2, "smart"],
"no-eval": [2],
"no-global-assign": [2],
@@ -36,6 +38,11 @@
"no-unneeded-ternary": [1],
"object-curly-spacing": [1],
"space-infix-ops": ["error"],
"space-in-parens": ["error", "never"],
"space-unary-ops": ["error", {
"words": true,
"nonwords": false
}],
"no-const-assign": [2],
"no-duplicate-imports": [2],
"prefer-template": [1],
+3 -3
View File
@@ -24,7 +24,7 @@ export const fetchAssets = (skip = '', limit = '', search = '', sort = '', filte
assets: result,
count
}))
.catch(error => dispatch({type: FETCH_ASSETS_FAILURE, error}));
.catch((error) => dispatch({type: FETCH_ASSETS_FAILURE, error}));
};
// Update an asset state
@@ -34,9 +34,9 @@ export const updateAssetState = (id, closedAt) => (dispatch) => {
return coralApi(`/assets/${id}/status`, {method: 'PUT', body: {closedAt}})
.then(() =>
dispatch({type: UPDATE_ASSET_STATE_SUCCESS}))
.catch(error => dispatch({type: UPDATE_ASSET_STATE_FAILURE, error}));
.catch((error) => dispatch({type: UPDATE_ASSET_STATE_FAILURE, error}));
};
export const updateAssets = assets => dispatch => {
export const updateAssets = (assets) => (dispatch) => {
dispatch({type: UPDATE_ASSETS, assets});
};
+9 -9
View File
@@ -7,7 +7,7 @@ import {handleAuthToken} from 'coral-framework/actions/auth';
// SIGN IN
//==============================================================================
export const handleLogin = (email, password, recaptchaResponse) => dispatch => {
export const handleLogin = (email, password, recaptchaResponse) => (dispatch) => {
dispatch({type: actions.LOGIN_REQUEST});
const params = {method: 'POST', body: {email, password}};
if (recaptchaResponse) {
@@ -20,10 +20,10 @@ export const handleLogin = (email, password, recaptchaResponse) => dispatch => {
return dispatch(checkLoginFailure('not logged in'));
}
dispatch(handleAuthToken(token));
const isAdmin = !!user.roles.filter(i => i === 'ADMIN').length;
const isAdmin = !!user.roles.filter((i) => i === 'ADMIN').length;
dispatch(checkLoginSuccess(user, isAdmin));
})
.catch(error => {
.catch((error) => {
if (error.translation_key === 'LOGIN_MAXIMUM_EXCEEDED') {
dispatch({
type: actions.LOGIN_MAXIMUM_EXCEEDED,
@@ -51,11 +51,11 @@ const forgotPassowordFailure = () => ({
type: actions.FETCH_FORGOT_PASSWORD_FAILURE
});
export const requestPasswordReset = email => dispatch => {
export const requestPasswordReset = (email) => (dispatch) => {
dispatch(forgotPassowordRequest(email));
return coralApi('/account/password/reset', {method: 'POST', body: {email}})
.then(() => dispatch(forgotPassowordSuccess()))
.catch(error => dispatch(forgotPassowordFailure(error)));
.catch((error) => dispatch(forgotPassowordFailure(error)));
};
//==============================================================================
@@ -72,12 +72,12 @@ const checkLoginSuccess = (user, isAdmin) => ({
isAdmin
});
const checkLoginFailure = error => ({
const checkLoginFailure = (error) => ({
type: actions.CHECK_LOGIN_FAILURE,
error
});
export const checkLogin = () => dispatch => {
export const checkLogin = () => (dispatch) => {
dispatch(checkLoginRequest());
return coralApi('/auth')
.then(({user}) => {
@@ -86,10 +86,10 @@ export const checkLogin = () => dispatch => {
return dispatch(checkLoginFailure('not logged in'));
}
const isAdmin = !!user.roles.filter(i => i === 'ADMIN').length;
const isAdmin = !!user.roles.filter((i) => i === 'ADMIN').length;
dispatch(checkLoginSuccess(user, isAdmin));
})
.catch(error => {
.catch((error) => {
console.error(error);
dispatch(checkLoginFailure(`${error.translation_key}`));
});
+3 -3
View File
@@ -16,7 +16,7 @@ import {
import coralApi from '../../../coral-framework/helpers/response';
export const fetchAccounts = (query = {}) => dispatch => {
export const fetchAccounts = (query = {}) => (dispatch) => {
dispatch(requestFetchAccounts());
coralApi(`/users?${qs.stringify(query)}`)
@@ -30,14 +30,14 @@ export const fetchAccounts = (query = {}) => dispatch => {
totalPages
});
})
.catch(error => dispatch({type: FETCH_COMMENTERS_FAILURE, error}));
.catch((error) => dispatch({type: FETCH_COMMENTERS_FAILURE, error}));
};
const requestFetchAccounts = () => ({
type: FETCH_COMMENTERS_REQUEST
});
export const updateSorting = sort => ({
export const updateSorting = (sort) => ({
type: SORT_UPDATE,
sort
});
+1 -1
View File
@@ -1,6 +1,6 @@
export const CONFIG_UPDATED = 'CONFIG_UPDATED';
export const fetchConfig = () => dispatch => {
export const fetchConfig = () => (dispatch) => {
let json = document.getElementById('data');
let data = JSON.parse(json.textContent);
dispatch({type: CONFIG_UPDATED, data});
+11 -11
View File
@@ -5,14 +5,14 @@ import errorMsj from 'coral-framework/helpers/error';
export const nextStep = () => ({type: actions.NEXT_STEP});
export const previousStep = () => ({type: actions.PREVIOUS_STEP});
export const goToStep = step => ({type: actions.GO_TO_STEP, step});
export const goToStep = (step) => ({type: actions.GO_TO_STEP, step});
const installRequest = () => ({type: actions.INSTALL_REQUEST});
const installSuccess = () => ({type: actions.INSTALL_SUCCESS});
const installFailure = error => ({type: actions.INSTALL_FAILURE, error});
const installFailure = (error) => ({type: actions.INSTALL_FAILURE, error});
const addError = (name, error) => ({type: actions.ADD_ERROR, name, error});
const hasError = error => ({type: actions.HAS_ERROR, error});
const hasError = (error) => ({type: actions.HAS_ERROR, error});
const clearErrors = () => ({type: actions.CLEAR_ERRORS});
const validation = (formData, dispatch, next) => {
@@ -21,11 +21,11 @@ const validation = (formData, dispatch, next) => {
}
const validKeys = Object.keys(formData)
.filter(name => name !== 'domains');
.filter((name) => name !== 'domains');
// Required Validation
const empty = validKeys
.filter(name => {
.filter((name) => {
const cond = !formData[name].length;
if (cond) {
@@ -45,7 +45,7 @@ const validation = (formData, dispatch, next) => {
// RegExp Validation
const validation = validKeys
.filter(name => {
.filter((name) => {
const cond = !validate[name](formData[name]);
if (cond) {
@@ -88,7 +88,7 @@ export const finishInstall = () => (dispatch, getState) => {
dispatch(installSuccess());
dispatch(nextStep());
})
.catch(error => {
.catch((error) => {
console.error(error);
dispatch(installFailure(`${error.translation_key}`));
});
@@ -99,10 +99,10 @@ export const updateUserFormData = (name, value) => ({type: actions.UPDATE_FORMDA
export const updatePermittedDomains = (value) => ({type: actions.UPDATE_PERMITTED_DOMAINS_SETTINGS, value});
const checkInstallRequest = () => ({type: actions.CHECK_INSTALL_REQUEST});
const checkInstallSuccess = installed => ({type: actions.CHECK_INSTALL_SUCCESS, installed});
const checkInstallFailure = error => ({type: actions.CHECK_INSTALL_FAILURE, error});
const checkInstallSuccess = (installed) => ({type: actions.CHECK_INSTALL_SUCCESS, installed});
const checkInstallFailure = (error) => ({type: actions.CHECK_INSTALL_FAILURE, error});
export const checkInstall = next => dispatch => {
export const checkInstall = (next) => (dispatch) => {
dispatch(checkInstallRequest());
coralApi('/setup')
.then(({installed}) => {
@@ -111,7 +111,7 @@ export const checkInstall = next => dispatch => {
next();
}
})
.catch(error => {
.catch((error) => {
console.error(error);
dispatch(checkInstallFailure(`${error.translation_key}`));
});
+1 -1
View File
@@ -1,6 +1,6 @@
import * as actions from 'constants/moderation';
export const toggleModal = open => ({type: actions.TOGGLE_MODAL, open});
export const toggleModal = (open) => ({type: actions.TOGGLE_MODAL, open});
export const singleView = () => ({type: actions.SINGLE_VIEW});
// Ban User Dialog
+5 -5
View File
@@ -13,19 +13,19 @@ export const SAVE_SETTINGS_FAILED = 'SAVE_SETTINGS_FAILED';
export const WORDLIST_UPDATED = 'WORDLIST_UPDATED';
export const DOMAINLIST_UPDATED = 'DOMAINLIST_UPDATED';
export const fetchSettings = () => dispatch => {
export const fetchSettings = () => (dispatch) => {
dispatch({type: SETTINGS_LOADING});
coralApi('/settings')
.then(settings => {
.then((settings) => {
dispatch({type: SETTINGS_RECEIVED, settings});
})
.catch(error => {
.catch((error) => {
dispatch({type: SETTINGS_FETCH_ERROR, error});
});
};
// for updating top-level settings
export const updateSettings = settings => {
export const updateSettings = (settings) => {
return {type: SETTINGS_UPDATED, settings};
};
@@ -48,7 +48,7 @@ export const saveSettingsToServer = () => (dispatch, getState) => {
.then(() => {
dispatch({type: SAVE_SETTINGS_SUCCESS, settings});
})
.catch(error => {
.catch((error) => {
dispatch({type: SAVE_SETTINGS_FAILED, error});
});
};
+4 -4
View File
@@ -9,8 +9,8 @@ export const userStatusUpdate = (status, userId, commentId) => {
return (dispatch) => {
dispatch({type: userTypes.UPDATE_STATUS_REQUEST});
return coralApi(`/users/${userId}/status`, {method: 'POST', body: {status: status, comment_id: commentId}})
.then(res => dispatch({type: userTypes.UPDATE_STATUS_SUCCESS, res}))
.catch(error => dispatch({type: userTypes.UPDATE_STATUS_FAILURE, error}));
.then((res) => dispatch({type: userTypes.UPDATE_STATUS_SUCCESS, res}))
.catch((error) => dispatch({type: userTypes.UPDATE_STATUS_FAILURE, error}));
};
};
@@ -18,7 +18,7 @@ export const userStatusUpdate = (status, userId, commentId) => {
export const sendNotificationEmail = (userId, subject, body) => {
return (dispatch) => {
return coralApi(`/users/${userId}/email`, {method: 'POST', body: {subject, body}})
.catch(error => dispatch({type: userTypes.USER_EMAIL_FAILURE, error}));
.catch((error) => dispatch({type: userTypes.USER_EMAIL_FAILURE, error}));
};
};
@@ -26,6 +26,6 @@ export const sendNotificationEmail = (userId, subject, body) => {
export const enableUsernameEdit = (userId) => {
return (dispatch) => {
return coralApi(`/users/${userId}/username-enable`, {method: 'POST'})
.catch(error => dispatch({type: userTypes.USERNAME_ENABLE_FAILURE, error}));
.catch((error) => dispatch({type: userTypes.USERNAME_ENABLE_FAILURE, error}));
};
};
@@ -14,7 +14,7 @@ class AdminLogin extends React.Component {
this.state = {email: '', password: '', requestPassword: false};
}
handleSignIn = e => {
handleSignIn = (e) => {
e.preventDefault();
this.props.handleLogin(this.state.email, this.state.password);
}
@@ -28,7 +28,7 @@ class AdminLogin extends React.Component {
this.props.handleLogin(this.state.email, this.state.password, recaptchaResponse);
}
handleRequestPassword = e => {
handleRequestPassword = (e) => {
e.preventDefault();
this.props.requestPasswordReset(this.state.email);
}
@@ -41,11 +41,11 @@ class AdminLogin extends React.Component {
<TextField
label='Email Address'
value={this.state.email}
onChange={e => this.setState({email: e.target.value})} />
onChange={(e) => this.setState({email: e.target.value})} />
<TextField
label='Password'
value={this.state.password}
onChange={e => this.setState({password: e.target.value})}
onChange={(e) => this.setState({password: e.target.value})}
type='password' />
<div style={{height: 10}}></div>
<Button
@@ -54,7 +54,7 @@ class AdminLogin extends React.Component {
full
onClick={this.handleSignIn}>Sign In</Button>
<p className={styles.forgotPasswordCTA}>
Forgot your password? <a href="#" className={styles.forgotPasswordLink} onClick={e => {
Forgot your password? <a href="#" className={styles.forgotPasswordLink} onClick={(e) => {
e.preventDefault();
this.setState({requestPassword: true});
}}>Request a new one.</a>
@@ -82,7 +82,7 @@ class AdminLogin extends React.Component {
<TextField
label='Email Address'
value={this.state.email}
onChange={e => this.setState({email: e.target.value})} />
onChange={(e) => this.setState({email: e.target.value})} />
<Button
type='submit'
cStyle='black'
@@ -1,7 +1,7 @@
import React, {PropTypes} from 'react';
import {Card} from 'coral-ui';
const EmptyCard = props => (
const EmptyCard = (props) => (
<Card style={{textAlign: 'center', maxWidth: 400, margin: '0 auto'}}>
{props.children}
</Card>
@@ -59,8 +59,8 @@ export default class ModerationKeysModal extends React.Component {
</tr>
</thead>
<tbody>
{Object.keys(shortcut.shortcuts).map(key => (
<tr key={`${key }tr`}>
{Object.keys(shortcut.shortcuts).map((key) => (
<tr key={`${key}tr`}>
<td className={styles.shortcut}><span className={styles.key}>{key}</span></td>
<td>{lang.t(shortcut.shortcuts[key])}</td>
</tr>
@@ -72,7 +72,7 @@ export default class ModerationList extends React.Component {
// Add key handlers. Each action has one and added j/k for moving around
bindKeyHandlers () {
const {modActions, isActive} = this.props;
modActions.filter(action => menuOptionsMap[action].key).forEach(action => {
modActions.filter((action) => menuOptionsMap[action].key).forEach((action) => {
key(menuOptionsMap[action].key, 'moderationList', () => isActive && this.actionKeyHandler(menuOptionsMap[action].status));
});
key('j', 'moderationList', () => isActive && this.moveKeyHandler('down'));
@@ -148,12 +148,12 @@ class CommunityContainer extends Component {
}
}
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
community: state.community.toJS()
});
const mapDispatchToProps = dispatch => ({
fetchAccounts: query => dispatch(fetchAccounts(query)),
const mapDispatchToProps = (dispatch) => ({
fetchAccounts: (query) => dispatch(fetchAccounts(query)),
showBanUserDialog: (user) => dispatch(showBanUserDialog(user)),
hideBanUserDialog: () => dispatch(hideBanUserDialog(false)),
showSuspendUserDialog: (user) => dispatch(showSuspendUserDialog(user)),
@@ -1,6 +1,6 @@
import React from 'react';
const CommunityLayout = props => (
const CommunityLayout = (props) => (
<div>
{props.children}
</div>
@@ -54,7 +54,7 @@ class Table extends Component {
<SelectField label={'Select me'} value={row.status || ''}
className={styles.selectField}
label={lang.t('community.status')}
onChange={status => this.onCommenterStatusChange(row.id, status)}>
onChange={(status) => this.onCommenterStatusChange(row.id, status)}>
<Option value={'ACTIVE'}>{lang.t('community.active')}</Option>
<Option value={'BANNED'}>{lang.t('community.banned')}</Option>
</SelectField>
@@ -63,7 +63,7 @@ class Table extends Component {
<SelectField label={'Select me'} value={row.roles[0] || ''}
className={styles.selectField}
label={lang.t('community.role')}
onChange={role => this.onRoleChange(row.id, role)}>
onChange={(role) => this.onRoleChange(row.id, role)}>
<Option value={''}>.</Option>
<Option value={'MODERATOR'}>{lang.t('community.moderator')}</Option>
<Option value={'ADMIN'}>{lang.t('community.admin')}</Option>
@@ -77,4 +77,4 @@ class Table extends Component {
}
}
export default connect(state => ({commenters: state.community.get('accounts')}))(Table);
export default connect((state) => ({commenters: state.community.get('accounts')}))(Table);
@@ -9,7 +9,7 @@ import translations from '../../../translations.json';
const lang = new I18n(translations);
// Render a single user for the list
const User = props => {
const User = (props) => {
const {user, modActionButtons} = props;
let userStatus = user.status;
@@ -37,7 +37,7 @@ const User = props => {
<div className={styles.flaggedByCount}>
<i className="material-icons">flag</i><span className={styles.flaggedByLabel}>{lang.t('community.flags')}({ user.actions.length })</span>:
{ user.action_summaries.map(
(action, i ) => {
(action, i) => {
return <span className={styles.flaggedBy} key={i}>
{lang.t(`community.${action.reason}`)} ({action.count})
</span>;
@@ -46,7 +46,7 @@ const User = props => {
</div>
<div className={styles.flaggedReasons}>
{ user.action_summaries.map(
(action_sum, i ) => {
(action_sum, i) => {
return <div key={i}>
<span className={styles.flaggedByLabel}>
{lang.t(`community.${action_sum.reason}`)} ({action_sum.count})
@@ -171,7 +171,7 @@ class Configure extends Component {
}
}
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
settings: state.settings.toJS()
});
export default connect(mapStateToProps)(Configure);
@@ -18,8 +18,8 @@ const Domainlist = ({domains, onChangeDomainlist}) => {
value={domains}
inputProps={{placeholder: 'URL'}}
addOnPaste={true}
pasteSplit={data => data.split(',').map(d => d.trim())}
onChange={tags => onChangeDomainlist('whitelist', tags)}
pasteSplit={(data) => data.split(',').map((d) => d.trim())}
onChange={(tags) => onChangeDomainlist('whitelist', tags)}
/>
</div>
</div>
@@ -30,7 +30,7 @@ class EmbedLink extends Component {
location.protocol,
'//',
location.hostname,
location.port ? (`:${ window.location.port}`) : ''
location.port ? (`:${window.location.port}`) : ''
].join('');
const coralJsUrl = [talkBaseUrl, '/embed.js'].join('');
const nonce = String(Math.random()).slice(2);
@@ -170,7 +170,7 @@ export default StreamSettings;
// To see if we are talking about weeks, days or hours
// We talk the remainder of the division and see if it's 0
const getTimeoutMeasure = ts => {
const getTimeoutMeasure = (ts) => {
if (ts % TIMESTAMPS['weeks'] === 0) {
return 'weeks';
} else if (ts % TIMESTAMPS['days'] === 0) {
@@ -182,6 +182,6 @@ const getTimeoutMeasure = ts => {
// Dividing the amount by it's measure (hours, days, weeks) we
// obtain the amount of time
const getTimeoutAmount = ts => ts / TIMESTAMPS[getTimeoutMeasure(ts)];
const getTimeoutAmount = (ts) => ts / TIMESTAMPS[getTimeoutMeasure(ts)];
const lang = new I18n(translations);
@@ -15,8 +15,8 @@ const Wordlist = ({suspectWords, bannedWords, onChangeWordlist}) => (
value={bannedWords}
inputProps={{placeholder: 'word or phrase'}}
addOnPaste={true}
pasteSplit={data => data.split(',').map(d => d.trim())}
onChange={tags => onChangeWordlist('banned', tags)}
pasteSplit={(data) => data.split(',').map((d) => d.trim())}
onChange={(tags) => onChangeWordlist('banned', tags)}
/>
</div>
</Card>
@@ -28,8 +28,8 @@ const Wordlist = ({suspectWords, bannedWords, onChangeWordlist}) => (
value={suspectWords}
inputProps={{placeholder: 'word or phrase'}}
addOnPaste={true}
pasteSplit={data => data.split(',').map(d => d.trim())}
onChange={tags => onChangeWordlist('suspect', tags)} />
pasteSplit={(data) => data.split(',').map((d) => d.trim())}
onChange={(tags) => onChangeWordlist('suspect', tags)} />
</div>
</Card>
</div>
@@ -17,7 +17,7 @@ const ActivityWidget = ({assets}) => {
<div className={styles.widgetTable}>
{
assets.length
? assets.map(asset => {
? assets.map((asset) => {
return (
<div className={styles.rowLinkify} key={asset.id}>
<Link className={styles.linkToModerate} to={`/admin/moderate/flagged/${asset.id}`}>Moderate</Link>
@@ -35,7 +35,7 @@ class Dashboard extends React.Component {
}
}
const mapStateToProps = state => {
const mapStateToProps = (state) => {
return {
settings: state.settings.toJS(),
moderation: state.moderation.toJS()
@@ -18,10 +18,10 @@ const FlagWidget = ({assets}) => {
<div className={styles.widgetTable}>
{
assets.length
? assets.map(asset => {
? assets.map((asset) => {
let flagSummary = null;
if (asset.action_summaries) {
flagSummary = asset.action_summaries.find(s => s.__typename === 'FlagAssetActionSummary');
flagSummary = asset.action_summaries.find((s) => s.__typename === 'FlagAssetActionSummary');
}
return (
@@ -18,8 +18,8 @@ const LikeWidget = ({assets}) => {
<div className={styles.widgetTable}>
{
assets.length
? assets.map(asset => {
const likeSummary = asset.action_summaries.find(s => s.type === 'LikeAssetActionSummary');
? assets.map((asset) => {
const likeSummary = asset.action_summaries.find((s) => s.type === 'LikeAssetActionSummary');
return (
<div className={styles.rowLinkify} key={asset.id}>
<Link className={styles.linkToModerate} to={`/admin/moderate/flagged/${asset.id}`}>Moderate</Link>
@@ -7,7 +7,7 @@ import BanUserDialog from 'coral-admin/src/components/BanUserDialog';
const lang = new I18n(translations);
const MostLikedCommentsWidget = props => {
const MostLikedCommentsWidget = (props) => {
const {
comments,
moderation,
@@ -64,32 +64,32 @@ InstallContainer.contextTypes = {
router: React.PropTypes.object
};
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
install: state.install.toJS()
});
const mapDispatchToProps = dispatch => ({
const mapDispatchToProps = (dispatch) => ({
nextStep: () => dispatch(nextStep()),
goToStep: step => dispatch(goToStep(step)),
goToStep: (step) => dispatch(goToStep(step)),
previousStep: () => dispatch(previousStep()),
finishInstall: () => dispatch(finishInstall()),
checkInstall: next => dispatch(checkInstall(next)),
handleDomainsChange: value => {
checkInstall: (next) => dispatch(checkInstall(next)),
handleDomainsChange: (value) => {
dispatch(updatePermittedDomains(value));
},
handleSettingsChange: e => {
handleSettingsChange: (e) => {
const {name, value} = e.currentTarget;
dispatch(updateSettingsFormData(name, value));
},
handleUserChange: e => {
handleUserChange: (e) => {
const {name, value} = e.currentTarget;
dispatch(updateUserFormData(name, value));
},
handleSettingsSubmit: e => {
handleSettingsSubmit: (e) => {
e.preventDefault();
dispatch(submitSettings());
},
handleUserSubmit: e => {
handleUserSubmit: (e) => {
e.preventDefault();
dispatch(submitUser());
}
@@ -6,7 +6,7 @@ const lang = new I18n(translations);
import translations from '../../translations.json';
import I18n from 'coral-framework/modules/i18n/i18n';
const AddOrganizationName = props => {
const AddOrganizationName = (props) => {
const {handleSettingsChange, handleSettingsSubmit, install} = props;
return (
<div className={styles.step}>
@@ -6,7 +6,7 @@ const lang = new I18n(translations);
import translations from '../../translations.json';
import I18n from 'coral-framework/modules/i18n/i18n';
const InitialStep = props => {
const InitialStep = (props) => {
const {handleUserChange, handleUserSubmit, install} = props;
return (
<div className={styles.step}>
@@ -6,7 +6,7 @@ const lang = new I18n(translations);
import translations from '../../translations.json';
import I18n from 'coral-framework/modules/i18n/i18n';
const InitialStep = props => {
const InitialStep = (props) => {
const {nextStep} = props;
return (
<div className={styles.step}>
@@ -2,7 +2,7 @@ import React from 'react';
import styles from './style.css';
import {Button, Select, Option, TextField} from 'coral-ui';
const InviteTeamMembers = props => {
const InviteTeamMembers = (props) => {
const {nextStep} = props;
return (
<div className={styles.step}>
@@ -7,7 +7,7 @@ const lang = new I18n(translations);
import translations from '../../translations.json';
import I18n from 'coral-framework/modules/i18n/i18n';
const PermittedDomainsStep = props => {
const PermittedDomainsStep = (props) => {
const {finishInstall, install, handleDomainsChange} = props;
const domains = install.data.settings.domains.whitelist;
return (
@@ -19,8 +19,8 @@ const PermittedDomainsStep = props => {
value={domains}
inputProps={{placeholder: 'URL'}}
addOnPaste={true}
pasteSplit={data => data.split(',').map(d => d.trim())}
onChange={tags => handleDomainsChange(tags)}
pasteSplit={(data) => data.split(',').map((d) => d.trim())}
onChange={(tags) => handleDomainsChange(tags)}
/>
</Card>
<Button cStyle='green' onClick={finishInstall} raised>{lang.t('PERMITTED_DOMAINS.SUBMIT')}</Button>
@@ -2,9 +2,9 @@ import React, {Component} from 'react';
import {connect} from 'react-redux';
import Layout from '../components/ui/Layout';
import {fetchConfig} from '../actions/config';
import AdminLogin from '../components/AdminLogin';
import {logout} from 'coral-framework/actions/auth';
import {FullLoading} from '../components/FullLoading';
import AdminLogin from '../components/AdminLogin';
import {toggleModal as toggleShortcutModal} from '../actions/moderation';
import {checkLogin, handleLogin, requestPasswordReset} from '../actions/auth';
@@ -58,20 +58,20 @@ class LayoutContainer extends Component {
}
}
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
auth: state.auth.toJS(),
TALK_RECAPTCHA_PUBLIC: state.config
.get('data')
.get('TALK_RECAPTCHA_PUBLIC', null)
});
const mapDispatchToProps = dispatch => ({
const mapDispatchToProps = (dispatch) => ({
checkLogin: () => dispatch(checkLogin()),
fetchConfig: () => dispatch(fetchConfig()),
handleLogin: (username, password, recaptchaResponse) =>
dispatch(handleLogin(username, password, recaptchaResponse)),
requestPasswordReset: email => dispatch(requestPasswordReset(email)),
toggleShortcutModal: toggle => dispatch(toggleShortcutModal(toggle)),
requestPasswordReset: (email) => dispatch(requestPasswordReset(email)),
toggleShortcutModal: (toggle) => dispatch(toggleShortcutModal(toggle)),
handleLogout: () => dispatch(logout())
});
@@ -61,14 +61,14 @@ class ModerationContainer extends Component {
select = (next) => () => {
if (next) {
this.setState(prevState =>
this.setState((prevState) =>
({
...prevState,
selectedIndex: prevState.selectedIndex < this.getComments().length - 1
? prevState.selectedIndex + 1 : prevState.selectedIndex
}));
} else {
this.setState(prevState =>
this.setState((prevState) =>
({
...prevState,
selectedIndex: prevState.selectedIndex > 0 ?
@@ -126,7 +126,7 @@ class ModerationContainer extends Component {
}
if (providedAssetId) {
asset = assets.find(asset => asset.id === this.props.params.id);
asset = assets.find((asset) => asset.id === this.props.params.id);
if (!asset) {
return <NotFoundAsset assetId={providedAssetId} />;
@@ -202,17 +202,17 @@ class ModerationContainer extends Component {
}
}
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
moderation: state.moderation.toJS(),
settings: state.settings.toJS(),
assets: state.assets.get('assets')
});
const mapDispatchToProps = dispatch => ({
toggleModal: toggle => dispatch(toggleModal(toggle)),
const mapDispatchToProps = (dispatch) => ({
toggleModal: (toggle) => dispatch(toggleModal(toggle)),
onClose: () => dispatch(toggleModal(false)),
singleView: () => dispatch(singleView()),
updateAssets: assets => dispatch(updateAssets(assets)),
updateAssets: (assets) => dispatch(updateAssets(assets)),
fetchSettings: () => dispatch(fetchSettings()),
showBanUserDialog: (user, commentId, commentStatus, showRejectedNote) => dispatch(showBanUserDialog(user, commentId, commentStatus, showRejectedNote)),
hideBanUserDialog: () => dispatch(hideBanUserDialog(false)),
@@ -1,6 +1,6 @@
import React from 'react';
const ModerationLayout = props => (
const ModerationLayout = (props) => (
<div>
{props.children}
</div>
@@ -27,11 +27,11 @@ const Comment = ({
...props
}) => {
const links = linkify.getMatches(comment.body);
const linkText = links ? links.map(link => link.raw) : [];
const linkText = links ? links.map((link) => link.raw) : [];
const flagActionSummaries = getActionSummary('FlagActionSummary', comment);
const flagActions =
comment.actions &&
comment.actions.filter(a => a.__typename === 'FlagAction');
comment.actions.filter((a) => a.__typename === 'FlagAction');
let commentType = '';
if (comment.status === 'PREMOD') {
commentType = 'premod';
@@ -43,7 +43,7 @@ const Comment = ({
// this should be the behavior on the front end as well.
// currently the highlighter plugin does not support this out of the box.
const searchWords = [...suspectWords, ...bannedWords]
.filter(w => {
.filter((w) => {
return new RegExp(`(^|\\s)${w}(\\s|$)`).test(comment.body);
})
.concat(linkText);
@@ -2,7 +2,7 @@ import React, {PropTypes} from 'react';
import styles from './CommentType.css';
import {Icon} from 'coral-ui';
const CommentType = props => {
const CommentType = (props) => {
const typeData = getTypeData(props.type);
return (
@@ -12,7 +12,7 @@ const CommentType = props => {
);
};
const getTypeData = type => {
const getTypeData = (type) => {
switch (type) {
case 'premod':
return {icon: 'query_builder', text: 'Pre-Mod', className: 'premod'};
@@ -55,7 +55,7 @@ class FlagBox extends Component {
<ul>
{actionSummaries.map((summary, i) => {
const actionList = actions.filter(a => a.reason === summary.reason);
const actionList = actions.filter((a) => a.reason === summary.reason);
return (
<li key={i}>
@@ -3,7 +3,7 @@ import {Link} from 'react-router';
import {Icon} from 'coral-ui';
import styles from './styles.css';
const ModerationHeader = props => (
const ModerationHeader = (props) => (
<div className=''>
<div className={`mdl-tabs ${styles.header}`}>
{
@@ -57,7 +57,7 @@ const ModerationMenu = (
className={styles.selectField}
label="Sort"
value={sort}
onChange={sort => selectSort(sort)}>
onChange={(sort) => selectSort(sort)}>
<Option value={'REVERSE_CHRONOLOGICAL'}>Newest First</Option>
<Option value={'CHRONOLOGICAL'}>Oldest First</Option>
</SelectField>
@@ -2,7 +2,7 @@ import React from 'react';
import {Link} from 'react-router';
import styles from './styles.css';
const NotFound = props => (
const NotFound = (props) => (
<div className={`mdl-card mdl-shadow--2dp ${styles.notFound}`}>
<p>
The provided asset id <Link to={`/admin/moderate/${props.assetId}`}>{props.assetId}</Link> does not exist.
@@ -55,7 +55,7 @@ class Stories extends Component {
onStatusClick = (closeStream, id, statusMenuOpen) => () => {
if (statusMenuOpen) {
this.setState(prev => {
this.setState((prev) => {
prev.statusMenus[id] = false;
return prev;
});
@@ -65,7 +65,7 @@ class Stories extends Component {
this.props.fetchAssets(page, limit, search, sort, filter);
});
} else {
this.setState(prev => {
this.setState((prev) => {
prev.statusMenus[id] = true;
return prev;
});
@@ -54,7 +54,7 @@ class Stories extends Component {
onStatusClick = (closeStream, id, statusMenuOpen) => () => {
if (statusMenuOpen) {
this.setState(prev => {
this.setState((prev) => {
prev.statusMenus[id] = false;
return prev;
});
@@ -64,7 +64,7 @@ class Stories extends Component {
this.props.fetchAssets(page, limit, search, sort, filter);
});
} else {
this.setState(prev => {
this.setState((prev) => {
prev.statusMenus[id] = true;
return prev;
});
@@ -56,7 +56,7 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, {
updateQueries: {
ModQueue: (oldData) => {
const comment = views.reduce((comment, view) => {
return comment ? comment : oldData[view].find(c => c.id === commentId);
return comment ? comment : oldData[view].find((c) => c.id === commentId);
}, null);
let accepted;
let acceptedCount = oldData.acceptedCount;
@@ -70,9 +70,9 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, {
accepted = [comment, ...oldData.accepted];
}
const premod = oldData.premod.filter(c => c.id !== commentId);
const flagged = oldData.flagged.filter(c => c.id !== commentId);
const rejected = oldData.rejected.filter(c => c.id !== commentId);
const premod = oldData.premod.filter((c) => c.id !== commentId);
const flagged = oldData.flagged.filter((c) => c.id !== commentId);
const rejected = oldData.rejected.filter((c) => c.id !== commentId);
const premodCount = premod.length < oldData.premod.length ? oldData.premodCount - 1 : oldData.premodCount;
const flaggedCount = flagged.length < oldData.flagged.length ? oldData.flaggedCount - 1 : oldData.flaggedCount;
const rejectedCount = rejected.length < oldData.rejected.length ? oldData.rejectedCount - 1 : oldData.rejectedCount;
@@ -101,7 +101,7 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, {
updateQueries: {
ModQueue: (oldData) => {
const comment = views.reduce((comment, view) => {
return comment ? comment : oldData[view].find(c => c.id === commentId);
return comment ? comment : oldData[view].find((c) => c.id === commentId);
}, null);
let rejected;
let rejectedCount = oldData.rejectedCount;
@@ -115,9 +115,9 @@ export const setCommentStatus = graphql(SET_COMMENT_STATUS, {
rejected = [comment, ...oldData.rejected];
}
const premod = oldData.premod.filter(c => c.id !== commentId);
const flagged = oldData.flagged.filter(c => c.id !== commentId);
const accepted = oldData.accepted.filter(c => c.id !== commentId);
const premod = oldData.premod.filter((c) => c.id !== commentId);
const flagged = oldData.flagged.filter((c) => c.id !== commentId);
const accepted = oldData.accepted.filter((c) => c.id !== commentId);
const premodCount = premod.length < oldData.premod.length ? oldData.premodCount - 1 : oldData.premodCount;
const flaggedCount = flagged.length < oldData.flagged.length ? oldData.flaggedCount - 1 : oldData.flaggedCount;
const acceptedCount = accepted.length < oldData.accepted.length ? oldData.acceptedCount - 1 : oldData.acceptedCount;
+4 -4
View File
@@ -53,17 +53,17 @@ export default function community (state = initialState, action) {
}
case SET_ROLE : {
const commenters = state.get('accounts');
const idx = commenters.findIndex(el => el.id === action.id);
const idx = commenters.findIndex((el) => el.id === action.id);
commenters[idx].roles[0] = action.role;
return state.set('accounts', commenters.map(id => id));
return state.set('accounts', commenters.map((id) => id));
}
case SET_COMMENTER_STATUS: {
const commenters = state.get('accounts');
const idx = commenters.findIndex(el => el.id === action.id);
const idx = commenters.findIndex((el) => el.id === action.id);
commenters[idx].status = action.status;
return state.set('accounts', commenters.map(id => id));
return state.set('accounts', commenters.map((id) => id));
}
case SORT_UPDATE :
@@ -3,7 +3,7 @@ import Pym from '../../node_modules/pym.js';
const pym = new Pym.Child({polling: 100});
export default pym;
export const link = url => e => {
export const link = (url) => (e) => {
e.preventDefault();
pym.sendMessage('navigate', url);
};
@@ -123,9 +123,9 @@ const mapStateToProps = (state) => ({
asset: state.asset.toJS()
});
const mapDispatchToProps = dispatch => ({
updateStatus: status => dispatch(updateOpenStatus(status)),
updateConfiguration: newConfig => dispatch(updateConfiguration(newConfig)),
const mapDispatchToProps = (dispatch) => ({
updateStatus: (status) => dispatch(updateOpenStatus(status)),
updateConfiguration: (newConfig) => dispatch(updateConfiguration(newConfig)),
});
export default compose(
@@ -1,6 +1,6 @@
import {ADD_EXTERNAL_CONFIG} from '../constants/config';
export const addExternalConfig = config => ({
export const addExternalConfig = (config) => ({
type: ADD_EXTERNAL_CONFIG,
config
});
@@ -25,7 +25,7 @@ import {getActionSummary, iPerformedThisAction} from 'coral-framework/utils';
import {getEditableUntilDate} from './util';
import styles from './Comment.css';
const isStaff = tags => !tags.every(t => t.name !== 'STAFF');
const isStaff = (tags) => !tags.every((t) => t.name !== 'STAFF');
// hold actions links (e.g. Reply) along the comment footer
const ActionButton = ({children}) => {
@@ -187,9 +187,9 @@ class Comment extends React.Component {
);
let myFlag = null;
if (iPerformedThisAction('FlagActionSummary', comment)) {
myFlag = flagSummary.find(s => s.current_user);
myFlag = flagSummary.find((s) => s.current_user);
} else if (iPerformedThisAction('DontAgreeActionSummary', comment)) {
myFlag = dontAgreeSummary.find(s => s.current_user);
myFlag = dontAgreeSummary.find((s) => s.current_user);
}
let commentClass = parentId
@@ -201,7 +201,7 @@ class Comment extends React.Component {
const notifyOnError = (fn, errorToMessage) =>
async function(...args) {
if (typeof errorToMessage !== 'function') {
errorToMessage = error => error.message;
errorToMessage = (error) => error.message;
}
try {
return await fn(...args);
@@ -375,7 +375,7 @@ class Comment extends React.Component {
/>
: null}
{comment.replies &&
comment.replies.map(reply => {
comment.replies.map((reply) => {
return commentIsIgnored(reply)
? <IgnoredCommentTombstone key={reply.id} />
: <Comment
@@ -427,16 +427,16 @@ export default Comment;
// return whether the comment is editable
function commentIsStillEditable (comment) {
const editing = comment && comment.editing;
if ( ! editing) {return false;}
if (!editing) {return false;}
const editableUntil = getEditableUntilDate(comment);
const editWindowExpired = (editableUntil - new Date) < 0;
return ! editWindowExpired;
return !editWindowExpired;
}
// return number of milliseconds before edit window expires
function editWindowRemainingMs (comment) {
const editableUntil = getEditableUntilDate(comment);
if ( ! editableUntil) {return;}
if (!editableUntil) {return;}
const now = new Date();
const editWindowRemainingMs = (editableUntil - now);
return editWindowRemainingMs;
@@ -65,7 +65,7 @@ export class EditableCommentContent extends React.Component {
componentWillUnmount() {
if (this.editWindowExpiryTimeout) {
this.editWindowExpiryTimeout = clearTimeout(this.editWindowExpiryTimeout);
}
}
}
async editComment(edit) {
const {editComment, addNotification, stopEditing} = this.props;
@@ -83,7 +83,7 @@ export class EditableCommentContent extends React.Component {
successfullyEdited = true;
} catch (error) {
if (error.translation_key) {
addNotification('error', lang.t(error.translation_key) || error.translation_key);
addNotification('error', lang.t(`error.${error.translation_key}`));
} else if (error.networkError) {
addNotification('error', lang.t('error.networkError'));
} else {
@@ -113,7 +113,7 @@ export class EditableCommentContent extends React.Component {
// should be disabled if user hasn't actually changed their
// original comment
return (comment.body !== originalBody) && ! editWindowExpired;
return (comment.body !== originalBody) && !editWindowExpired;
}}
saveComment={this.editComment}
bodyLabel={lang.t('editComment.bodyInputLabel')}
@@ -15,7 +15,7 @@ import ChangeUsernameContainer
from 'coral-sign-in/containers/ChangeUsernameContainer';
class Stream extends React.Component {
setActiveReplyBox = reactKey => {
setActiveReplyBox = (reactKey) => {
if (!this.props.auth.user) {
this.props.showSignInDialog();
} else {
@@ -58,7 +58,7 @@ class Stream extends React.Component {
const firstCommentDate = asset.comments[0]
? asset.comments[0].created_at
: new Date(Date.now() - 1000 * 60 * 60 * 24 * 7).toISOString();
const commentIsIgnored = comment =>
const commentIsIgnored = (comment) =>
myIgnoredUsers && myIgnoredUsers.includes(comment.user.id);
return (
<div id="stream">
@@ -150,7 +150,7 @@ class Stream extends React.Component {
/>
<div className="embed__stream">
{comments.map(
comment =>
(comment) =>
(commentIsIgnored(comment)
? <IgnoredCommentTombstone key={comment.id} />
: <Comment
@@ -72,7 +72,7 @@ class Toggleable extends React.Component {
};
}
toggle() {
this.setState({isOpen: ! this.state.isOpen});
this.setState({isOpen: !this.state.isOpen});
}
close() {
this.setState({isOpen: false});
@@ -22,10 +22,9 @@ const {fetchAssetSuccess} = assetActions;
class EmbedContainer extends React.Component {
componentWillReceiveProps(nextProps) {
if (this.props.root.me && !nextProps.root.me) {
if (this.props.auth.loggedIn !== nextProps.auth.loggedIn) {
// Refetch because on logout `excludeIgnored` becomes `false`.
// TODO: logout via mutation and obsolete this?
// Refetch after login/logout.
this.props.data.refetch();
}
@@ -85,7 +84,7 @@ export const withEmbedQuery = withQuery(EMBED_QUERY, {
}),
});
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
auth: state.auth.toJS(),
commentCountCache: state.stream.commentCountCache,
commentId: state.stream.commentId,
@@ -95,7 +94,7 @@ const mapStateToProps = state => ({
config: state.config
});
const mapDispatchToProps = dispatch =>
const mapDispatchToProps = (dispatch) =>
bindActionCreators(
{
logout,
@@ -110,7 +109,6 @@ const mapDispatchToProps = dispatch =>
export default compose(
connect(mapStateToProps, mapDispatchToProps),
branch(props => !props.auth.checkedInitialLogin && props.config, renderComponent(Spinner)),
branch((props) => !props.auth.checkedInitialLogin && props.config, renderComponent(Spinner)),
withEmbedQuery,
)(EmbedContainer);
@@ -29,7 +29,7 @@ class StreamContainer extends React.Component {
variables,
// Apollo requires this, even though we don't use it...
updateQuery: data => data,
updateQuery: (data) => data,
});
};
@@ -79,7 +79,7 @@ class StreamContainer extends React.Component {
...oldData,
asset: {
...oldData.asset,
comments: oldData.asset.comments.map(comment => {
comments: oldData.asset.comments.map((comment) => {
// since the dipslayed replies and the returned replies can overlap,
// pull out the unique ones.
@@ -203,10 +203,6 @@ const fragments = {
}
}
}
myIgnoredUsers {
id,
username,
}
me {
status
}
@@ -217,7 +213,7 @@ const fragments = {
`,
};
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
auth: state.auth.toJS(),
commentCountCache: state.stream.commentCountCache,
activeReplyBox: state.stream.activeReplyBox,
@@ -228,7 +224,7 @@ const mapStateToProps = state => ({
previousTab: state.embed.previousTab,
});
const mapDispatchToProps = dispatch =>
const mapDispatchToProps = (dispatch) =>
bindActionCreators({
showSignInDialog,
addNotification,
@@ -126,14 +126,14 @@ const extension = {
// TODO: don't rely on refetching.
refetchQueries: [
'EmbedQuery', 'myIgnoredUsers',
'EmbedQuery', 'EmbedStreamProfileQuery',
],
}),
StopIgnoringUser: () => ({
// TODO: don't rely on refetching.
refetchQueries: [
'EmbedQuery', 'myIgnoredUsers',
'EmbedQuery', 'EmbedStreamProfileQuery',
],
}),
PostComment: ({
@@ -212,13 +212,13 @@ const extension = {
return editedComment;
};
const commentIsStillVisible = (comment) => {
return ! ((id === comment.id) && (['PREMOD', 'REJECTED'].includes(status)));
return !((id === comment.id) && (['PREMOD', 'REJECTED'].includes(status)));
};
const resultReflectingEdit = update(previousData, {
asset: {
comments: {
$apply: comments => {
return comments.filter(commentIsStillVisible).map(comment => {
$apply: (comments) => {
return comments.filter(commentIsStillVisible).map((comment) => {
let replyWasEditedToBeHidden = false;
if (comment.id === id) {
return updateCommentWithEdit(comment, edit);
@@ -227,14 +227,14 @@ const extension = {
replies: {
$apply: (comments) => {
return comments
.filter(c => {
.filter((c) => {
if (commentIsStillVisible(c)) {
return true;
}
replyWasEditedToBeHidden = true;
return false;
})
.map(comment => {
.map((comment) => {
if (comment.id === id) {
return updateCommentWithEdit(comment, edit);
}
+1 -1
View File
@@ -22,7 +22,7 @@ if (store === localStore) {
pym.sendMessage('getConfig');
pym.onMessage('config', config => {
pym.onMessage('config', (config) => {
store.dispatch(addExternalConfig(JSON.parse(config)));
});
}
+8 -8
View File
@@ -7,14 +7,14 @@ import translations from './../translations';
const lang = new I18n(translations);
export const fetchAssetRequest = () => ({type: actions.FETCH_ASSET_REQUEST});
export const fetchAssetSuccess = asset => ({type: actions.FETCH_ASSET_SUCCESS, asset});
export const fetchAssetFailure = error => ({type: actions.FETCH_ASSET_FAILURE, error});
export const fetchAssetSuccess = (asset) => ({type: actions.FETCH_ASSET_SUCCESS, asset});
export const fetchAssetFailure = (error) => ({type: actions.FETCH_ASSET_FAILURE, error});
const updateAssetSettingsRequest = () => ({type: actions.UPDATE_ASSET_SETTINGS_REQUEST});
const updateAssetSettingsSuccess = settings => ({type: actions.UPDATE_ASSET_SETTINGS_SUCCESS, settings});
const updateAssetSettingsSuccess = (settings) => ({type: actions.UPDATE_ASSET_SETTINGS_SUCCESS, settings});
const updateAssetSettingsFailure = () => ({type: actions.UPDATE_ASSET_SETTINGS_FAILURE});
export const updateConfiguration = newConfig => (dispatch, getState) => {
export const updateConfiguration = (newConfig) => (dispatch, getState) => {
const assetId = getState().asset.toJS().id;
dispatch(updateAssetSettingsRequest());
coralApi(`/assets/${assetId}/settings`, {method: 'PUT', body: newConfig})
@@ -22,10 +22,10 @@ export const updateConfiguration = newConfig => (dispatch, getState) => {
dispatch(addNotification('success', lang.t('successUpdateSettings')));
dispatch(updateAssetSettingsSuccess(newConfig));
})
.catch(error => dispatch(updateAssetSettingsFailure(error)));
.catch((error) => dispatch(updateAssetSettingsFailure(error)));
};
export const updateOpenStream = closedBody => (dispatch, getState) => {
export const updateOpenStream = (closedBody) => (dispatch, getState) => {
const assetId = getState().asset.toJS().id;
dispatch(fetchAssetRequest());
coralApi(`/assets/${assetId}/status`, {method: 'PUT', body: closedBody})
@@ -33,13 +33,13 @@ export const updateOpenStream = closedBody => (dispatch, getState) => {
dispatch(addNotification('success', lang.t('successUpdateSettings')));
dispatch(fetchAssetSuccess(closedBody));
})
.catch(error => dispatch(fetchAssetFailure(error)));
.catch((error) => dispatch(fetchAssetFailure(error)));
};
const openStream = () => ({type: actions.OPEN_COMMENTS});
const closeStream = () => ({type: actions.CLOSE_COMMENTS});
export const updateOpenStatus = status => dispatch => {
export const updateOpenStatus = (status) => (dispatch) => {
if (status === 'open') {
dispatch(openStream());
dispatch(updateOpenStream({closedAt: null}));
+34 -64
View File
@@ -1,42 +1,15 @@
import {gql} from 'react-apollo';
import {pym} from 'coral-framework';
import * as Storage from '../helpers/storage';
import * as actions from '../constants/auth';
import coralApi, {base} from '../helpers/response';
import client from 'coral-framework/services/client';
import jwtDecode from 'jwt-decode';
const lang = new I18n(translations);
import translations from './../translations';
import I18n from '../../coral-framework/modules/i18n/i18n';
const ME_QUERY = gql`
query Me {
me {
status
comments {
id
body
asset {
id
title
url
}
created_at
}
}
}
`;
function fetchMe() {
return client.query({
fetchPolicy: 'network-only',
query: ME_QUERY
});
}
// Dialog Actions
export const showSignInDialog = () => dispatch => {
export const showSignInDialog = () => (dispatch) => {
const signInPopUp = window.open(
'/embed/stream/login',
'Login',
@@ -54,13 +27,12 @@ export const showSignInDialog = () => dispatch => {
signInPopUp.onunload = () => {
if (loaded) {
dispatch(checkLogin());
fetchMe();
}
};
dispatch({type: actions.SHOW_SIGNIN_DIALOG});
};
export const hideSignInDialog = () => dispatch => {
export const hideSignInDialog = () => (dispatch) => {
dispatch({type: actions.HIDE_SIGNIN_DIALOG});
window.close();
};
@@ -79,7 +51,7 @@ const createUsernameSuccess = () => ({
type: actions.CREATE_USERNAME_SUCCESS
});
const createUsernameFailure = error => ({
const createUsernameFailure = (error) => ({
type: actions.CREATE_USERNAME_FAILURE,
error
});
@@ -89,7 +61,7 @@ export const updateUsername = ({username}) => ({
username
});
export const createUsername = (userId, formData) => dispatch => {
export const createUsername = (userId, formData) => (dispatch) => {
dispatch(createUsernameRequest());
coralApi('/account/username', {method: 'PUT', body: formData})
.then(() => {
@@ -97,12 +69,12 @@ export const createUsername = (userId, formData) => dispatch => {
dispatch(hideCreateUsernameDialog());
dispatch(updateUsername(formData));
})
.catch(error => {
.catch((error) => {
dispatch(createUsernameFailure(lang.t(`error.${error.translation_key}`)));
});
};
export const changeView = view => dispatch => {
export const changeView = (view) => (dispatch) => {
dispatch({
type: actions.CHANGE_VIEW,
view
@@ -130,7 +102,7 @@ const signInRequest = () => ({
type: actions.FETCH_SIGNIN_REQUEST
});
const signInFailure = error => ({
const signInFailure = (error) => ({
type: actions.FETCH_SIGNIN_FAILURE,
error
});
@@ -139,7 +111,7 @@ const signInFailure = error => ({
// AUTH TOKEN
//==============================================================================
export const handleAuthToken = token => dispatch => {
export const handleAuthToken = (token) => (dispatch) => {
Storage.setItem('exp', jwtDecode(token).exp);
Storage.setItem('token', token);
dispatch({type: 'HANDLE_AUTH_TOKEN'});
@@ -149,14 +121,14 @@ export const handleAuthToken = token => dispatch => {
// SIGN IN
//==============================================================================
export const fetchSignIn = formData => dispatch => {
export const fetchSignIn = (formData) => (dispatch) => {
dispatch(signInRequest());
return coralApi('/auth/local', {method: 'POST', body: formData})
.then(({token}) => {
dispatch(handleAuthToken(token));
dispatch(hideSignInDialog());
})
.catch(error => {
.catch((error) => {
if (error.metadata) {
// the user might not have a valid email. prompt the user user re-request the confirmation email
@@ -178,16 +150,16 @@ export const fetchSignIn = formData => dispatch => {
const signInFacebookRequest = () => ({
type: actions.FETCH_SIGNIN_FACEBOOK_REQUEST
});
const signInFacebookSuccess = user => ({
const signInFacebookSuccess = (user) => ({
type: actions.FETCH_SIGNIN_FACEBOOK_SUCCESS,
user
});
const signInFacebookFailure = error => ({
const signInFacebookFailure = (error) => ({
type: actions.FETCH_SIGNIN_FACEBOOK_FAILURE,
error
});
export const fetchSignInFacebook = () => dispatch => {
export const fetchSignInFacebook = () => (dispatch) => {
dispatch(signInFacebookRequest());
window.open(
`${base}/auth/facebook`,
@@ -204,7 +176,7 @@ const signUpFacebookRequest = () => ({
type: actions.FETCH_SIGNUP_FACEBOOK_REQUEST
});
export const fetchSignUpFacebook = () => dispatch => {
export const fetchSignUpFacebook = () => (dispatch) => {
dispatch(signUpFacebookRequest());
window.open(
`${base}/auth/facebook`,
@@ -213,7 +185,7 @@ export const fetchSignUpFacebook = () => dispatch => {
);
};
export const facebookCallback = (err, data) => dispatch => {
export const facebookCallback = (err, data) => (dispatch) => {
if (err) {
dispatch(signInFacebookFailure(err));
return;
@@ -235,10 +207,10 @@ export const facebookCallback = (err, data) => dispatch => {
//==============================================================================
const signUpRequest = () => ({type: actions.FETCH_SIGNUP_REQUEST});
const signUpSuccess = user => ({type: actions.FETCH_SIGNUP_SUCCESS, user});
const signUpFailure = error => ({type: actions.FETCH_SIGNUP_FAILURE, error});
const signUpSuccess = (user) => ({type: actions.FETCH_SIGNUP_SUCCESS, user});
const signUpFailure = (error) => ({type: actions.FETCH_SIGNUP_FAILURE, error});
export const fetchSignUp = (formData, redirectUri) => dispatch => {
export const fetchSignUp = (formData, redirectUri) => (dispatch) => {
dispatch(signUpRequest());
coralApi('/users', {
@@ -249,7 +221,7 @@ export const fetchSignUp = (formData, redirectUri) => dispatch => {
.then(({user}) => {
dispatch(signUpSuccess(user));
})
.catch(error => {
.catch((error) => {
let errorMessage = lang.t(`error.${error.message}`);
// if there is no translation defined, just show the error string
@@ -276,7 +248,7 @@ const forgotPasswordFailure = () => ({
type: actions.FETCH_FORGOT_PASSWORD_FAILURE
});
export const fetchForgotPassword = email => dispatch => {
export const fetchForgotPassword = (email) => (dispatch) => {
dispatch(forgotPasswordRequest(email));
const redirectUri = pym.parentUrl || location.href;
coralApi('/account/password/reset', {
@@ -284,20 +256,18 @@ export const fetchForgotPassword = email => dispatch => {
body: {email, loc: redirectUri}
})
.then(() => dispatch(forgotPasswordSuccess()))
.catch(error => dispatch(forgotPasswordFailure(error)));
.catch((error) => dispatch(forgotPasswordFailure(error)));
};
//==============================================================================
// LOGOUT
//==============================================================================
export const logout = () => dispatch => {
return coralApi('/auth', {method: 'DELETE'})
.then(() => {
dispatch({type: actions.LOGOUT});
Storage.removeItem('token');
fetchMe();
});
export const logout = () => (dispatch) => {
return coralApi('/auth', {method: 'DELETE'}).then(() => {
dispatch({type: actions.LOGOUT});
Storage.removeItem('token');
});
};
//==============================================================================
@@ -305,7 +275,7 @@ export const logout = () => dispatch => {
//==============================================================================
const checkLoginRequest = () => ({type: actions.CHECK_LOGIN_REQUEST});
const checkLoginFailure = error => ({type: actions.CHECK_LOGIN_FAILURE, error});
const checkLoginFailure = (error) => ({type: actions.CHECK_LOGIN_FAILURE, error});
const checkLoginSuccess = (user, isAdmin) => ({
type: actions.CHECK_LOGIN_SUCCESS,
@@ -313,26 +283,26 @@ const checkLoginSuccess = (user, isAdmin) => ({
isAdmin
});
export const checkLogin = () => dispatch => {
export const checkLogin = () => (dispatch) => {
dispatch(checkLoginRequest());
coralApi('/auth')
.then(result => {
.then((result) => {
if (!result.user) {
Storage.removeItem('token');
throw new Error('Not logged in');
}
const isAdmin = !!result.user.roles.filter(i => i === 'ADMIN').length;
const isAdmin = !!result.user.roles.filter((i) => i === 'ADMIN').length;
dispatch(checkLoginSuccess(result.user, isAdmin));
})
.catch(error => {
.catch((error) => {
console.error(error);
dispatch(checkLoginFailure(`${error.translation_key}`));
});
};
export const validForm = () => ({type: actions.VALID_FORM});
export const invalidForm = error => ({type: actions.INVALID_FORM, error});
export const invalidForm = (error) => ({type: actions.INVALID_FORM, error});
//==============================================================================
// VERIFY EMAIL
@@ -350,7 +320,7 @@ const verifyEmailFailure = () => ({
type: actions.VERIFY_EMAIL_FAILURE
});
export const requestConfirmEmail = (email, redirectUri) => dispatch => {
export const requestConfirmEmail = (email, redirectUri) => (dispatch) => {
dispatch(verifyEmailRequest());
return coralApi('/users/resend-verify', {
method: 'POST',
@@ -360,7 +330,7 @@ export const requestConfirmEmail = (email, redirectUri) => dispatch => {
.then(() => {
dispatch(verifyEmailSuccess());
})
.catch(err => {
.catch((err) => {
// email might have already been verifyed
dispatch(verifyEmailFailure(err));
+2 -2
View File
@@ -6,7 +6,7 @@ import I18n from 'coral-framework/modules/i18n/i18n';
import translations from './../translations';
const lang = new I18n(translations);
const editUsernameFailure = error => ({type: actions.EDIT_USERNAME_FAILURE, error});
const editUsernameFailure = (error) => ({type: actions.EDIT_USERNAME_FAILURE, error});
const editUsernameSuccess = () => ({type: actions.EDIT_USERNAME_SUCCESS});
export const editName = (username) => (dispatch) => {
@@ -15,7 +15,7 @@ export const editName = (username) => (dispatch) => {
dispatch(editUsernameSuccess());
dispatch(addNotification('success', lang.t('successNameUpdate')));
})
.catch(error => {
.catch((error) => {
dispatch(editUsernameFailure(lang.t(`error.${error.translation_key}`)));
});
};
+1 -1
View File
@@ -10,7 +10,7 @@ export const withPostComment = withMutation(
}
`, {
props: ({mutate}) => ({
postComment: comment => {
postComment: (comment) => {
return mutate({
variables: {
comment
+13 -13
View File
@@ -9,8 +9,8 @@ import {getDefinitionName, mergeDocuments} from 'coral-framework/utils';
export const pluginReducers = merge(
...plugins
.filter(o => o.module.reducer)
.map(o => ({...o.module.reducer}))
.filter((o) => o.module.reducer)
.map((o) => ({...o.module.reducer}))
);
/**
@@ -18,18 +18,18 @@ export const pluginReducers = merge(
*/
export function getSlotElements(slot, props = {}) {
const components = flatten(plugins
.filter(o => o.module.slots[slot])
.map(o => o.module.slots[slot]));
.filter((o) => o.module.slots[slot])
.map((o) => o.module.slots[slot]));
return components
.map((component, i) => React.createElement(component, {key: i, ...props}));
}
function getComponentFragments(components) {
const res = components
.map(c => c.fragments)
.filter(fragments => fragments)
.map((c) => c.fragments)
.filter((fragments) => fragments)
.reduce((res, fragments) => {
Object.keys(fragments).forEach(key => {
Object.keys(fragments).forEach((key) => {
if (!(key in res)) {
res[key] = {spreads: [], definitions: []};
}
@@ -39,7 +39,7 @@ function getComponentFragments(components) {
return res;
}, {});
Object.keys(res).forEach(key => {
Object.keys(res).forEach((key) => {
// Assemble arguments for `gql` to call it directly without using template literals.
res[key].spreads = `...${res[key].spreads.join('\n...')}\n`;
@@ -65,10 +65,10 @@ export function getSlotsFragments(slots) {
if (!Array.isArray(slots)) {
slots = [slots];
}
const components = uniq(flattenDeep(slots.map(slot => {
const components = uniq(flattenDeep(slots.map((slot) => {
return plugins
.filter(o => o.module.slots[slot])
.map(o => o.module.slots[slot]);
.filter((o) => o.module.slots[slot])
.map((o) => o.module.slots[slot]);
})));
const fragments = getComponentFragments(components);
@@ -84,7 +84,7 @@ export function getSlotsFragments(slots) {
export function getGraphQLExtensions() {
return plugins
.map(o => pick(o.module, ['mutations', 'queries', 'fragments']))
.filter(o => o);
.map((o) => pick(o.module, ['mutations', 'queries', 'fragments']))
.filter((o) => o);
}
+2 -2
View File
@@ -25,9 +25,9 @@ const buildOptions = (inputOptions = {}) => {
return options;
};
const handleResp = res => {
const handleResp = (res) => {
if (res.status > 399) {
return res.json().then(err => {
return res.json().then((err) => {
let message = err.message || res.status;
const error = new Error();
+4 -4
View File
@@ -1,7 +1,7 @@
export default {
email: email => (/^([A-Za-z0-9_\-\.\+])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test(email)),
password: pass => (/^(?=.{8,}).*$/.test(pass)),
email: (email) => (/^([A-Za-z0-9_\-\.\+])+\@([A-Za-z0-9_\-\.])+\.([A-Za-z]{2,4})$/.test(email)),
password: (pass) => (/^(?=.{8,}).*$/.test(pass)),
confirmPassword: () => true,
username: username => (/^[a-zA-Z0-9_]+$/.test(username)),
organizationName: org => (/^[a-zA-Z0-9_ ]+$/).test(org)
username: (username) => (/^[a-zA-Z0-9_]+$/.test(username)),
organizationName: (org) => (/^[a-zA-Z0-9_ ]+$/).test(org)
};
+1 -1
View File
@@ -2,7 +2,7 @@ import React from 'react';
import {getDisplayName} from '../helpers/hoc';
// TODO: revisit `filtering` after https://github.com/apollographql/graphql-anywhere/issues/38.
export default fragments => WrappedComponent => {
export default (fragments) => (WrappedComponent) => {
class WithFragments extends React.Component {
render() {
return <WrappedComponent {...this.props} />;
+12 -12
View File
@@ -12,46 +12,46 @@ import {getDefinitionName} from '../utils';
* Exports a HOC with the same signature as `graphql`, that will
* apply mutation options registered in the graphRegistry.
*/
export default (document, config) => WrappedComponent => {
export default (document, config) => (WrappedComponent) => {
config = {
...config,
options: config.options || {},
props: config.props || (data => ({mutate: data.mutate()})),
props: config.props || ((data) => ({mutate: data.mutate()})),
};
const wrappedProps = (data) => {
const name = getDefinitionName(document);
const callbacks = getMutationOptions(name);
const mutate = (base) => {
const variables = base.variables || config.options.variables;
const configs = callbacks.map(cb => cb({variables, state: store.getState()}));
const configs = callbacks.map((cb) => cb({variables, state: store.getState()}));
const optimisticResponse = merge(
base.optimisticResponse || config.options.optimisticResponse,
...configs.map(cfg => cfg.optimisticResponse),
...configs.map((cfg) => cfg.optimisticResponse),
);
const refetchQueries = flatten(uniq([
base.refetchQueries || config.options.refetchQueries,
...configs.map(cfg => cfg.refetchQueries),
].filter(i => i)));
...configs.map((cfg) => cfg.refetchQueries),
].filter((i) => i)));
const updateCallbacks =
[base.update || config.options.update]
.concat(...configs.map(cfg => cfg.update))
.filter(i => i);
.concat(...configs.map((cfg) => cfg.update))
.filter((i) => i);
const update = (proxy, result) => {
updateCallbacks.forEach(cb => cb(proxy, result));
updateCallbacks.forEach((cb) => cb(proxy, result));
};
const updateQueries =
[
base.updateQueries || config.options.updateQueries,
...configs.map(cfg => cfg.updateQueries)
...configs.map((cfg) => cfg.updateQueries)
]
.filter(i => i)
.filter((i) => i)
.reduce((res, map) => {
Object.keys(map).forEach(key => {
Object.keys(map).forEach((key) => {
if (!(key in res)) {
res[key] = map[key];
} else {
+4 -4
View File
@@ -7,7 +7,7 @@ import {getDefinitionName, separateDataAndRoot} from '../utils';
* Exports a HOC with the same signature as `graphql`, that will
* apply query options registered in the graphRegistry.
*/
export default (document, config) => WrappedComponent => {
export default (document, config) => (WrappedComponent) => {
config = {
...config,
options: config.options || {},
@@ -19,9 +19,9 @@ export default (document, config) => WrappedComponent => {
const name = getDefinitionName(document);
const configs = getQueryOptions(name);
const reducerCallbacks =
[base.reducer || (i => i)]
.concat(...configs.map(cfg => cfg.reducer))
.filter(i => i);
[base.reducer || ((i) => i)]
.concat(...configs.map((cfg) => cfg.reducer))
.filter((i) => i);
const reducer = reducerCallbacks.reduce(
(a, b) => (prev, ...rest) =>
+4 -4
View File
@@ -10,7 +10,7 @@ import {showSignInDialog} from 'coral-framework/actions/auth';
import {capitalize} from 'coral-framework/helpers/strings';
import {getMyActionSummary, getTotalActionCount} from 'coral-framework/utils';
export default reaction => WrappedComponent => {
export default (reaction) => (WrappedComponent) => {
if (typeof reaction !== 'string') {
console.error('Reaction must be a valid string');
return null;
@@ -40,7 +40,7 @@ export default reaction => WrappedComponent => {
}
}
const isReaction = a =>
const isReaction = (a) =>
a.__typename === `${capitalize(reaction)}ActionSummary`;
const COMMENT_FRAGMENT = gql`
@@ -88,7 +88,7 @@ export default reaction => WrappedComponent => {
errors: null
}
},
update: proxy => {
update: (proxy) => {
const fragmentId = `Comment_${reactionData.commentId}`;
// Read the data from our cache for this query.
@@ -208,7 +208,7 @@ export default reaction => WrappedComponent => {
}
);
const mapDispatchToProps = dispatch =>
const mapDispatchToProps = (dispatch) =>
bindActionCreators({showSignInDialog}, dispatch);
const enhance = compose(
@@ -11,7 +11,7 @@ const {stripIndent} = require('common-tags');
function getPluginList(config) {
if (config && config.client) {
return config.client.map(x => typeof x === 'string' ? x : Object.keys(x)[0]);
return config.client.map((x) => typeof x === 'string' ? x : Object.keys(x)[0]);
}
return [];
+1 -1
View File
@@ -20,7 +20,7 @@ const initialState = Map({
fromSignUp: false
});
const purge = user => {
const purge = (user) => {
const {settings, profiles, ...userData} = user; // eslint-disable-line
return fromJS(userData);
};
+3 -3
View File
@@ -12,7 +12,7 @@ const initialState = Map({
ignoredUsers: Set(),
});
const purge = user => {
const purge = (user) => {
const {_id, created_at, updated_at, __v, roles, ...userData} = user; // eslint-disable-line
return userData;
};
@@ -42,9 +42,9 @@ export default function user (state = initialState, action) {
case 'APOLLO_MUTATION_RESULT':
switch (action.operationName) {
case 'ignoreUser':
return state.updateIn(['ignoredUsers'], i => i.add(action.variables.id));
return state.updateIn(['ignoredUsers'], (i) => i.add(action.variables.id));
case 'stopIgnoringUser':
return state.updateIn(['ignoredUsers'], i => i.delete(action.variables.id));
return state.updateIn(['ignoredUsers'], (i) => i.delete(action.variables.id));
}
break;
}
@@ -117,9 +117,9 @@ export function addQueryOptions(key, config) {
* });
*/
export function add(extension) {
Object.keys(extension.fragments || []).forEach(key => addFragment(key, extension.fragments[key]));
Object.keys(extension.mutations || []).forEach(key => addMutationOptions(key, extension.mutations[key]));
Object.keys(extension.queries || []).forEach(key => addQueryOptions(key, extension.queries[key]));
Object.keys(extension.fragments || []).forEach((key) => addFragment(key, extension.fragments[key]));
Object.keys(extension.mutations || []).forEach((key) => addMutationOptions(key, extension.mutations[key]));
Object.keys(extension.queries || []).forEach((key) => addQueryOptions(key, extension.queries[key]));
}
/**
@@ -170,12 +170,12 @@ function init() {
initialized = true;
// Add fragments from framework.
[globalFragments].forEach(map =>
Object.keys(map).forEach(key => addFragment(key, map[key]))
[globalFragments].forEach((map) =>
Object.keys(map).forEach((key) => addFragment(key, map[key]))
);
// Add configs from plugins.
getGraphQLExtensions().forEach(ext => add(ext));
getGraphQLExtensions().forEach((ext) => add(ext));
}
export function resolveFragments(document) {
@@ -184,9 +184,9 @@ export function resolveFragments(document) {
// resolve fragments from registry
const matchedSubFragments = document.loc.source.body.match(/\.\.\.(.*)/g) || [];
const subFragments =
uniq(matchedSubFragments.map(f => f.replace('...', '')))
.map(key => getFragmentDocument(key))
.filter(i => i);
uniq(matchedSubFragments.map((f) => f.replace('...', '')))
.map((key) => getFragmentDocument(key))
.filter((i) => i);
if (subFragments.length > 0) {
return mergeDocuments([document, ...subFragments]);
+1 -1
View File
@@ -3,7 +3,7 @@ import thunk from 'redux-thunk';
import mainReducer from '../reducers';
import {client} from './client';
const apolloErrorReporter = () => next => action => {
const apolloErrorReporter = () => (next) => (action) => {
if (action.type === 'APOLLO_QUERY_ERROR') {
console.error(action.error);
}
+2 -1
View File
@@ -33,7 +33,8 @@
"unexpectedError": "Unexpected error while saving changes. Sorry!"
},
"error": {
"editWindowExpired": "You can no longer edit this comment. The time window to do so has expired.",
"COMMENT_TOO_SHORT": "Your comment must have something in it",
"EDIT_WINDOW_ENDED": "You can no longer edit this comment. The time window to do so has expired.",
"emailNotVerified": "Email address {0} not verified.",
"email": "Not a valid E-Mail",
"networkError": "Failed to connect to server. Check your internet connection and try again.",
+6 -6
View File
@@ -2,7 +2,7 @@ import {gql} from 'react-apollo';
export const getTotalActionCount = (type, comment) => {
return comment.action_summaries
.filter(s => s.__typename === type)
.filter((s) => s.__typename === type)
.reduce((total, summary) => {
return total + summary.count;
}, 0);
@@ -12,14 +12,14 @@ export const iPerformedThisAction = (type, comment) => {
// if there is a current_user on any of the ActionSummary(s), the user performed this action
return comment.action_summaries
.filter(a => a.__typename === type)
.some(a => a.current_user);
.filter((a) => a.__typename === type)
.some((a) => a.current_user);
};
export const getMyActionSummary = (type, comment) => {
return comment.action_summaries
.filter(a => a.__typename === type)
.find(a => a.current_user);
.filter((a) => a.__typename === type)
.find((a) => a.current_user);
};
/**
@@ -29,7 +29,7 @@ export const getMyActionSummary = (type, comment) => {
*/
export const getActionSummary = (type, comment) => {
return comment.action_summaries.filter(a => a.__typename === type);
return comment.action_summaries.filter((a) => a.__typename === type);
};
/**
@@ -6,7 +6,7 @@ export default class AuthorName extends Component {
state = {showTooltip: false}
handleClick = () => {
this.setState(state => ({
this.setState((state) => ({
showTooltip: !state.showTooltip
}));
}
+6 -6
View File
@@ -7,7 +7,7 @@ import classnames from 'classnames';
// tag string for best comments
export const BEST_TAG = 'BEST';
export const commentIsBest = ({tags} = {}) => {
const isBest = Array.isArray(tags) && tags.some(t => t.name === BEST_TAG);
const isBest = Array.isArray(tags) && tags.some((t) => t.name === BEST_TAG);
return isBest;
};
@@ -15,7 +15,7 @@ const name = 'coral-plugin-best';
const lang = new I18n(translations);
// It would be best if the backend/api held this business logic
const canModifyBestTag = ({roles = []} = {}) => roles && ['ADMIN', 'MODERATOR'].some(role => roles.includes(role));
const canModifyBestTag = ({roles = []} = {}) => roles && ['ADMIN', 'MODERATOR'].some((role) => roles.includes(role));
// Put this on a comment to show that it is best
@@ -29,7 +29,7 @@ export const BestIndicator = ({children = <Icon name='star'/>}) => (
* Component that only renders children if the provided user prop can modify best tags
*/
export const IfUserCanModifyBest = ({user, children}) => {
if ( ! ( user && canModifyBestTag(user))) {return null;}
if (!(user && canModifyBestTag(user))) {return null;}
return children;
};
@@ -63,7 +63,7 @@ export class BestButton extends Component {
async onClickAddBest(e) {
e.preventDefault();
const {addBest} = this.props;
if ( ! addBest) {
if (!addBest) {
console.warn('BestButton#onClickAddBest called even though there is no addBest prop. doing nothing');
return;
}
@@ -78,7 +78,7 @@ export class BestButton extends Component {
async onClickRemoveBest(e) {
e.preventDefault();
const {removeBest} = this.props;
if ( ! removeBest) {
if (!removeBest) {
console.warn('BestButton#onClickAddBest called even though there is no removeBest prop. doing nothing');
return;
}
@@ -93,7 +93,7 @@ export class BestButton extends Component {
render() {
const {isBest, addBest, removeBest} = this.props;
const {isSaving} = this.state;
const disabled = isSaving || ! (isBest ? removeBest : addBest);
const disabled = isSaving || !(isBest ? removeBest : addBest);
return (
<button onClick={isBest ? this.onClickRemoveBest : this.onClickAddBest}
disabled={disabled}
+6 -6
View File
@@ -62,14 +62,14 @@ class CommentBox extends React.Component {
!isReply && setCommentCountCache(commentCountCache + 1);
// Execute preSubmit Hooks
this.state.hooks.preSubmit.forEach(hook => hook());
this.state.hooks.preSubmit.forEach((hook) => hook());
postComment(comment, 'comments')
.then(({data}) => {
const postedComment = data.createComment.comment;
// Execute postSubmit Hooks
this.state.hooks.postSubmit.forEach(hook => hook(data));
this.state.hooks.postSubmit.forEach((hook) => hook(data));
notifyForNewCommentStatus(addNotification, postedComment.status);
@@ -95,7 +95,7 @@ class CommentBox extends React.Component {
if (typeof hook !== 'function') {
return console.warn(`Hooks must be functions. Please check your ${hookType} hooks`);
} else if (typeof hookType === 'string') {
this.setState(state => ({
this.setState((state) => ({
hooks: {
...state.hooks,
[hookType]: [
@@ -115,10 +115,10 @@ class CommentBox extends React.Component {
}
}
unregisterHook = hookData => {
unregisterHook = (hookData) => {
const {hookType, hook} = hookData;
this.setState(state => {
this.setState((state) => {
let newHooks = state.hooks[newHooks];
const idx = state.hooks[hookType].indexOf(hook);
@@ -139,7 +139,7 @@ class CommentBox extends React.Component {
});
}
handleChange = e => this.setState({body: e.target.value});
handleChange = (e) => this.setState({body: e.target.value});
render () {
const {styles, isReply, authorId, maxCharCount} = this.props;
+2 -2
View File
@@ -1,9 +1,9 @@
export const addTag = tag => ({
export const addTag = (tag) => ({
type: 'ADD_TAG',
tag
});
export const removeTag = idx => ({
export const removeTag = (idx) => ({
type: 'REMOVE_TAG',
idx
});
+2 -2
View File
@@ -136,7 +136,7 @@ class FlagButton extends Component {
return <div className={`${name}-container`}>
<button
ref={ref => this.flagButton = ref}
ref={(ref) => this.flagButton = ref}
onClick={!this.props.banned && !flaggedByCurrentUser && !localPost ? this.onReportClick : null}
className={`${name}-button`}>
{
@@ -150,7 +150,7 @@ class FlagButton extends Component {
</button>
{
this.state.showMenu &&
<div className={`${name}-popup`} ref={ref => this.popup = ref}>
<div className={`${name}-popup`} ref={(ref) => this.popup = ref}>
<PopupMenu>
<div className={`${name}-popup-header`}>{popupMenu.header}</div>
{
+1 -1
View File
@@ -4,7 +4,7 @@ import styles from './Comment.css';
import PubDate from '../coral-plugin-pubdate/PubDate';
import Content from '../coral-plugin-commentcontent/CommentContent';
const Comment = props => {
const Comment = (props) => {
return (
<div className={styles.myComment}>
<div>
@@ -2,7 +2,7 @@ import React, {PropTypes} from 'react';
import Comment from './Comment';
import styles from './CommentHistory.css';
const CommentHistory = props => {
const CommentHistory = (props) => {
return (
<div className={`${styles.header} commentHistory`}>
<div className="commentHistory__list">
+1 -1
View File
@@ -4,7 +4,7 @@ import marked from 'marked';
const renderer = new marked.Renderer();
// Set link target to `_parent` to work properly in an embed.
renderer.link = ( href, title, text ) =>
renderer.link = (href, title, text) =>
`<a target="_parent" href="${href}" title="${title}">${text}</a>`;
marked.setOptions({renderer});
@@ -3,7 +3,7 @@ import {shallow} from 'enzyme';
import {expect} from 'chai';
import InfoBox from '../InfoBox';
const render = props => shallow(<InfoBox {...props} />);
const render = (props) => shallow(<InfoBox {...props} />);
describe('InfoBox', () => {
it('should render hidden InfoBox', () => {
@@ -3,7 +3,7 @@ import {shallow} from 'enzyme';
import {expect} from 'chai';
import Markdown from '../Markdown';
const render = props => shallow(<Markdown {...props} />);
const render = (props) => shallow(<Markdown {...props} />);
describe('Markdown', () => {
it('should convert Markdown to html', () => {
@@ -4,7 +4,7 @@ import styles from './styles.css';
import {I18n} from '../coral-framework';
import translations from './translations.json';
const ModerationLink = props => props.isAdmin ? (
const ModerationLink = (props) => props.isAdmin ? (
<div className={styles.moderationLink}>
<a href={`/admin/moderate/${props.assetId}`} target="_blank">
{lang.t('MODERATE_THIS_STREAM')}
@@ -53,19 +53,19 @@ class PermalinkButton extends React.Component {
return (
<div className={`${name}-container`}>
<button
ref={ref => this.linkButton = ref}
ref={(ref) => this.linkButton = ref}
onClick={this.toggle}
className={`${name}-button`}>
{lang.t('permalink.permalink')}
<i className={`${name}-icon material-icons`} aria-hidden={true}>link</i>
</button>
<div
ref={ref => this.popover = ref}
ref={(ref) => this.popover = ref}
className={`${name}-popover ${styles.container} ${this.state.popoverOpen ? 'active' : ''}`}>
<input
className={`${name}-copy-field`}
type='text'
ref={input => this.permalinkInput = input}
ref={(input) => this.permalinkInput = input}
value={`${this.props.articleURL}#${this.props.commentId}`}
onChange={() => {}} />
<Button className={`${name}-copy-button ${copySuccessful ? styles.success : ''} ${copyFailure ? styles.failure : ''}`}
+1 -1
View File
@@ -4,7 +4,7 @@ import {I18n} from '../coral-framework';
const lang = new I18n();
const name = 'coral-plugin-pubdate';
const PubDate = ({created_at}) => <div className={`${name }-text`}>
const PubDate = ({created_at}) => <div className={`${name}-text`}>
{lang.timeago(created_at)}
</div>;
@@ -25,23 +25,15 @@ class ProfileContainer extends Component {
};
}
handleTabChange = tab => {
handleTabChange = (tab) => {
this.setState({
activeTab: tab
});
};
render() {
const {
auth,
data,
asset,
showSignInDialog,
stopIgnoringUser,
myIgnoredUsersData
} = this.props;
const {me} = data;
const {auth, asset, data, showSignInDialog, stopIgnoringUser} = this.props;
const {me} = this.props.data;
if (!auth.loggedIn) {
return <NotLoggedIn showSignInDialog={showSignInDialog} />;
@@ -52,9 +44,8 @@ class ProfileContainer extends Component {
}
const localProfile = this.props.user.profiles.find(
p => p.provider === 'local'
(p) => p.provider === 'local'
);
const emailAddress = localProfile && localProfile.id;
return (
@@ -62,12 +53,11 @@ class ProfileContainer extends Component {
<h2>{this.props.user.username}</h2>
{emailAddress ? <p>{emailAddress}</p> : null}
{myIgnoredUsersData.myIgnoredUsers &&
myIgnoredUsersData.myIgnoredUsers.length
{me.ignoredUsers && me.ignoredUsers.length
? <div>
<h3>Ignored users</h3>
<IgnoredUsers
users={myIgnoredUsersData.myIgnoredUsers}
users={me.ignoredUsers}
stopIgnoring={stopIgnoringUser}
/>
</div>
@@ -84,55 +74,39 @@ class ProfileContainer extends Component {
}
}
// TODO: These currently relies on refetching (see ignoreUser and stopIgnoringUser mutations).
//
const withMyIgnoredUsersQuery = graphql(
const withQuery = graphql(
gql`
query myIgnoredUsers {
myIgnoredUsers {
id,
username,
}
}`,
{
props: ({data}) => {
return {
myIgnoredUsersData: data
};
}
}
);
const withMyCommentHistoryQuery = graphql(
gql`
query myCommentHistory {
query EmbedStreamProfileQuery {
me {
ignoredUsers {
id,
username,
}
comments {
id
body
asset {
id
body
asset {
id
title
url
}
created_at
title
url
}
created_at
}
}
}`
);
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
user: state.user.toJS(),
asset: state.asset.toJS(),
auth: state.auth.toJS()
});
const mapDispatchToProps = dispatch =>
const mapDispatchToProps = (dispatch) =>
bindActionCreators({showSignInDialog, checkLogin}, dispatch);
export default compose(
connect(mapStateToProps, mapDispatchToProps),
withMyCommentHistoryQuery,
withMyIgnoredUsersQuery,
withStopIgnoringUser
withStopIgnoringUser,
withQuery
)(ProfileContainer);
@@ -29,7 +29,7 @@ class ForgotContent extends React.Component {
<div className={styles.textField}>
<label htmlFor="email">{lang.t('signIn.email')}</label>
<input
ref={input => this.emailInput = input}
ref={(input) => this.emailInput = input}
type="text"
style={{fontSize: 16}}
id="email"
@@ -39,7 +39,7 @@ class ChangeUsernameContainer extends Component {
handleChange(e) {
const {name, value} = e.target;
this.setState(state => ({
this.setState((state) => ({
...state,
formData: {
...state.formData,
@@ -51,7 +51,7 @@ class ChangeUsernameContainer extends Component {
}
addError(name, error) {
return this.setState(state => ({
return this.setState((state) => ({
errors: {
...state.errors,
[name]: error
@@ -69,13 +69,13 @@ class ChangeUsernameContainer extends Component {
} else {
const { [name]: prop, ...errors } = this.state.errors; // eslint-disable-line
// Removes Error
this.setState(state => ({...state, errors}));
this.setState((state) => ({...state, errors}));
}
}
isCompleted() {
const {formData} = this.state;
return !Object.keys(formData).filter(prop => !formData[prop].length).length;
return !Object.keys(formData).filter((prop) => !formData[prop].length).length;
}
displayErrors(show = true) {
@@ -117,15 +117,15 @@ class ChangeUsernameContainer extends Component {
}
}
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
auth: state.auth.toJS()
});
const mapDispatchToProps = dispatch => ({
const mapDispatchToProps = (dispatch) => ({
createUsername: (userid, formData) => dispatch(createUsername(userid, formData)),
showCreateUsernameDialog: () => dispatch(showCreateUsernameDialog()),
hideCreateUsernameDialog: () => dispatch(hideCreateUsernameDialog()),
invalidForm: error => dispatch(invalidForm(error)),
invalidForm: (error) => dispatch(invalidForm(error)),
validForm: () => dispatch(validForm())
});
@@ -67,7 +67,7 @@ class SignInContainer extends Component {
handleChange(e) {
const {name, value} = e.target;
this.setState(state => ({
this.setState((state) => ({
...state,
formData: {
...state.formData,
@@ -96,7 +96,7 @@ class SignInContainer extends Component {
}
addError(name, error) {
return this.setState(state => ({
return this.setState((state) => ({
errors: {
...state.errors,
[name]: error
@@ -117,13 +117,13 @@ class SignInContainer extends Component {
} else {
const { [name]: prop, ...errors } = this.state.errors; // eslint-disable-line
// Removes Error
this.setState(state => ({...state, errors}));
this.setState((state) => ({...state, errors}));
}
}
isCompleted() {
const {formData} = this.state;
return !Object.keys(formData).filter(prop => !formData[prop].length).length;
return !Object.keys(formData).filter((prop) => !formData[prop].length).length;
}
displayErrors(show = true) {
@@ -169,22 +169,22 @@ class SignInContainer extends Component {
}
}
const mapStateToProps = state => ({
const mapStateToProps = (state) => ({
auth: state.auth.toJS()
});
const mapDispatchToProps = dispatch => ({
const mapDispatchToProps = (dispatch) => ({
checkLogin: () => dispatch(checkLogin()),
facebookCallback: (err, data) => dispatch(facebookCallback(err, data)),
fetchSignUp: (formData, url) => dispatch(fetchSignUp(formData, url)),
fetchSignIn: formData => dispatch(fetchSignIn(formData)),
fetchSignIn: (formData) => dispatch(fetchSignIn(formData)),
fetchSignInFacebook: () => dispatch(fetchSignInFacebook()),
fetchSignUpFacebook: () => dispatch(fetchSignUpFacebook()),
fetchForgotPassword: formData => dispatch(fetchForgotPassword(formData)),
fetchForgotPassword: (formData) => dispatch(fetchForgotPassword(formData)),
requestConfirmEmail: (email, url) => dispatch(requestConfirmEmail(email, url)),
changeView: view => dispatch(changeView(view)),
changeView: (view) => dispatch(changeView(view)),
handleClose: () => dispatch(hideSignInDialog()),
invalidForm: error => dispatch(invalidForm(error)),
invalidForm: (error) => dispatch(invalidForm(error)),
validForm: () => dispatch(validForm())
});
+3 -3
View File
@@ -13,8 +13,8 @@ export default class Dialog extends Component {
};
static defaultProps = {
onCancel: e => e.preventDefault(),
onClose: e => e.preventDefault()
onCancel: (e) => e.preventDefault(),
onClose: (e) => e.preventDefault()
};
componentDidMount(){
@@ -52,7 +52,7 @@ export default class Dialog extends Component {
return (
<dialog
ref={el => { this.dialog = el; }}
ref={(el) => { this.dialog = el; }}
className={`mdl-dialog ${className}`}
{...rest}
>
+1 -1
View File
@@ -18,7 +18,7 @@ export default class List extends Component {
return (
<ul className={`${styles.base} ${className}`}>
{React.Children.toArray(children)
.filter(child => !child.props.restricted)
.filter((child) => !child.props.restricted)
.map((child, i) =>
React.cloneElement(child, {
i,
+1 -1
View File
@@ -2,7 +2,7 @@ import React from 'react';
import {Option as OptionMDL} from 'react-mdl-selectfield';
import styles from './Option.css';
const Option = props => {
const Option = (props) => {
const {children, ...attrs} = props;
return (
<OptionMDL className={styles.Option} {...attrs}>
+1 -1
View File
@@ -2,7 +2,7 @@ import React from 'react';
import {SelectField} from 'react-mdl-selectfield';
import styles from './Select.css';
const Select = props => {
const Select = (props) => {
const {children, ...attrs} = props;
return (
<SelectField className={styles.Select} {...attrs}>
+1 -1
View File
@@ -19,7 +19,7 @@ class TabBar extends React.Component {
<div>
<ul className={`${styles.base} ${cStyle ? styles[cStyle] : ''}`}>
{React.Children.toArray(children)
.filter(child => !child.props.restricted)
.filter((child) => !child.props.restricted)
.map((child, tabId) =>
React.cloneElement(child, {
tabId,
+1 -1
View File
@@ -2,7 +2,7 @@ import React, {PropTypes} from 'react';
import styles from './WizardNav.css';
import Icon from './Icon';
const WizardNav = props => {
const WizardNav = (props) => {
const {goToStep = () => {}, currentStep, items, icon} = props;
return (
<nav className={styles.WizardNav}>
+15 -5
View File
@@ -112,10 +112,12 @@ const ErrContainsProfanity = new APIError('This username contains elements which
});
const ErrNotFound = new APIError('not found', {
translation_key: 'NOT_FOUND',
status: 404
});
const ErrInvalidAssetURL = new APIError('asset_url is invalid', {
translation_key: 'INVALID_ASSET_URL',
status: 400
});
@@ -148,16 +150,23 @@ const ErrPermissionUpdateUsername = new APIError('You do not have permission to
status: 500
});
// ErrLoginAttemptMaximumExceeded is returned when the login maximum is exceeded.
const ErrLoginAttemptMaximumExceeded = new APIError('You have made too many incorrect password attempts.', {
translation_key: 'LOGIN_MAXIMUM_EXCEEDED',
status: 429
});
class ErrEditWindowHasEnded extends APIError {
constructor(message) {
super(message || 'Edit window is over.', {status: 403, translation_key: 'error.editWindowExpired'});
}
}
// ErrEditWindowHasEnded is returned when the edit window has expired.
const ErrEditWindowHasEnded = new APIError('Edit window is over', {
translation_key: 'EDIT_WINDOW_ENDED',
status: 403
});
// ErrCommentTooShort is returned when the comment is too short.
const ErrCommentTooShort = new APIError('Comment was too short', {
translation_key: 'COMMENT_TOO_SHORT',
status: 400
});
module.exports = {
ExtendableError,
@@ -182,4 +191,5 @@ module.exports = {
ErrInstallLock,
ErrLoginAttemptMaximumExceeded,
ErrEditWindowHasEnded,
ErrCommentTooShort
};
+14 -17
View File
@@ -25,34 +25,31 @@ const genAssetsByID = (context, ids) => AssetModel.find({
* @param {String} asset_url the url passed in from the query
* @returns {Promise} resolves to the asset
*/
const findOrCreateAssetByURL = (context, asset_url) => {
const findOrCreateAssetByURL = async (context, asset_url) => {
// Verify that the asset_url is parsable.
let parsed_asset_url = url.parse(asset_url);
if (!parsed_asset_url.protocol) {
return Promise.reject(errors.ErrInvalidAssetURL);
throw errors.ErrInvalidAssetURL;
}
return AssetsService.findOrCreateByUrl(asset_url)
.then((asset) => {
let asset = await AssetsService.findOrCreateByUrl(asset_url);
// If the asset wasn't scraped before, scrape it! Otherwise just return
// the asset.
if (!asset.scraped) {
return scraper.create(asset).then(() => asset);
}
// If the asset wasn't scraped before, scrape it! Otherwise just return
// the asset.
if (!asset.scraped) {
await scraper.create(asset);
}
return asset;
});
return asset;
};
const getAssetsForMetrics = ({loaders: {Actions, Comments}}) => {
return Actions.getByTypes({action_type: 'FLAG', item_type: 'COMMENT'})
.then((actions) => { // ALL ACTIONS :O
const ids = actions.map(({item_id}) => item_id);
const getAssetsForMetrics = async ({loaders: {Actions, Comments}}) => {
let actions = await Actions.getByTypes({action_type: 'FLAG', item_type: 'COMMENT'});
return Comments.getByQuery({ids});
});
const ids = actions.map(({item_id}) => item_id);
return Comments.getByQuery({ids});
};
/**

Some files were not shown because too many files have changed in this diff Show More