Remove old code

This commit is contained in:
Chi Vinh Le
2018-02-13 15:00:53 +01:00
parent d857585c7f
commit c54a8bdc4f
17 changed files with 341 additions and 856 deletions
+1 -335
View File
@@ -1,8 +1,4 @@
import jwtDecode from 'jwt-decode';
import bowser from 'bowser';
import * as actions from '../constants/login';
import { notify } from 'coral-framework/actions/notification';
import t from 'coral-framework/services/i18n';
import { checkLogin } from 'coral-framework/actions/auth';
export const showSignInDialog = () => ({
@@ -10,15 +6,7 @@ export const showSignInDialog = () => ({
});
export const hideSignInDialog = () => dispatch => {
if (window.opener && window.opener !== window) {
// TODO: We need to address this when we refactor the
// login popup out of the embed.
// we are in a popup
window.close();
} else {
dispatch(checkLogin());
}
dispatch(checkLogin());
dispatch({ type: actions.HIDE_SIGNIN_DIALOG });
};
@@ -29,325 +17,3 @@ export const focusSignInDialog = () => ({
export const blurSignInDialog = () => ({
type: actions.BLUR_SIGNIN_DIALOG,
});
// TODO: remove the rest.
export const updateStatus = status => ({
type: actions.UPDATE_STATUS,
status,
});
export const resetSignInDialog = () => dispatch => {
dispatch({ type: actions.HIDE_SIGNIN_DIALOG });
};
export const showCreateUsernameDialog = () => ({
type: actions.SHOW_CREATEUSERNAME_DIALOG,
});
export const hideCreateUsernameDialog = () => ({
type: actions.HIDE_CREATEUSERNAME_DIALOG,
});
export const updateUsername = username => ({
type: actions.UPDATE_USERNAME,
username,
});
export const changeView = view => dispatch => {
dispatch({
type: actions.CHANGE_VIEW,
view,
});
switch (view) {
case 'SIGNUP':
window.resizeTo(500, 800);
break;
case 'FORGOT':
window.resizeTo(500, 400);
break;
default:
window.resizeTo(500, 550);
}
};
export const cleanState = () => ({
type: actions.CLEAN_STATE,
});
// Sign In Actions
const signInRequest = email => ({
type: actions.FETCH_SIGNIN_REQUEST,
email,
});
const signInFailure = error => ({
type: actions.FETCH_SIGNIN_FAILURE,
error,
});
//==============================================================================
// AUTH TOKEN
//==============================================================================
export const handleAuthToken = token => (dispatch, _, { localStorage }) => {
if (localStorage) {
localStorage.setItem('exp', jwtDecode(token).exp);
localStorage.setItem('token', token);
}
dispatch({ type: 'HANDLE_AUTH_TOKEN' });
};
//==============================================================================
// SIGN IN
//==============================================================================
export const fetchSignIn = formData => {
return (dispatch, _, { rest }) => {
dispatch(signInRequest(formData.email));
return rest('/auth/local', { method: 'POST', body: formData })
.then(({ token }) => {
if (!bowser.safari && !bowser.ios) {
dispatch(handleAuthToken(token));
}
dispatch(hideSignInDialog());
})
.catch(error => {
console.error(error);
if (error.metadata) {
// the user might not have a valid email. prompt the user user re-request the confirmation email
dispatch(
signInFailure(t('error.email_not_verified', error.metadata))
);
} else if (error.translation_key === 'NOT_AUTHORIZED') {
// invalid credentials
dispatch(signInFailure(t('error.email_password'), error.metadata));
} else {
dispatch(signInFailure(error));
}
});
};
};
//==============================================================================
// SIGN IN - FACEBOOK
//==============================================================================
const signInFacebookRequest = () => ({
type: actions.FETCH_SIGNIN_FACEBOOK_REQUEST,
});
const signInFacebookSuccess = user => ({
type: actions.FETCH_SIGNIN_FACEBOOK_SUCCESS,
user,
});
const signInFacebookFailure = error => ({
type: actions.FETCH_SIGNIN_FACEBOOK_FAILURE,
error,
});
export const fetchSignInFacebook = () => (dispatch, _, { rest }) => {
dispatch(signInFacebookRequest());
window.open(
`${rest.uri}/auth/facebook`,
'Continue with Facebook',
'menubar=0,resizable=0,width=500,height=500,top=200,left=500'
);
};
//==============================================================================
// SIGN UP - FACEBOOK
//==============================================================================
const signUpFacebookRequest = () => ({
type: actions.FETCH_SIGNUP_FACEBOOK_REQUEST,
});
export const fetchSignUpFacebook = () => (dispatch, _, { rest }) => {
dispatch(signUpFacebookRequest());
window.open(
`${rest.uri}/auth/facebook`,
'Continue with Facebook',
'menubar=0,resizable=0,width=500,height=500,top=200,left=500'
);
};
export const facebookCallback = (err, data) => dispatch => {
if (err) {
dispatch(signInFacebookFailure(err));
return;
}
try {
dispatch(handleAuthToken(data.token));
dispatch(signInFacebookSuccess(data.user));
dispatch(hideSignInDialog());
} catch (err) {
dispatch(signInFacebookFailure(err));
return;
}
};
//==============================================================================
// SIGN UP
//==============================================================================
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 });
export const fetchSignUp = formData => (dispatch, getState, { rest }) => {
const redirectUri = getState().auth.redirectUri;
dispatch(signUpRequest());
rest('/users', {
method: 'POST',
body: formData,
headers: { 'X-Pym-Url': redirectUri },
})
.then(({ user }) => {
dispatch(signUpSuccess(user));
})
.catch(error => {
console.error(error);
const errorMessage = error.translation_key
? t(`error.${error.translation_key}`)
: error.toString();
dispatch(signUpFailure(errorMessage));
});
};
//==============================================================================
// FORGOT PASSWORD
//==============================================================================
const forgotPasswordRequest = () => ({
type: actions.FETCH_FORGOT_PASSWORD_REQUEST,
});
const forgotPasswordSuccess = () => ({
type: actions.FETCH_FORGOT_PASSWORD_SUCCESS,
});
const forgotPasswordFailure = error => ({
type: actions.FETCH_FORGOT_PASSWORD_FAILURE,
error,
});
export const fetchForgotPassword = email => (dispatch, getState, { rest }) => {
dispatch(forgotPasswordRequest(email));
const redirectUri = getState().auth.redirectUri;
rest('/account/password/reset', {
method: 'POST',
body: { email, loc: redirectUri },
})
.then(() => dispatch(forgotPasswordSuccess()))
.catch(error => {
console.error(error);
const errorMessage = error.translation_key
? t(`error.${error.translation_key}`)
: error.toString();
dispatch(forgotPasswordFailure(errorMessage));
});
};
//==============================================================================
// LOGOUT
//==============================================================================
export const logout = () => async (
dispatch,
_,
{ rest, client, pym, localStorage }
) => {
await rest('/auth', { method: 'DELETE' });
if (localStorage) {
localStorage.removeItem('token');
localStorage.removeItem('exp');
}
// Reset the websocket.
client.resetWebsocket();
dispatch({ type: actions.LOGOUT });
pym.sendMessage('coral-auth-changed');
};
export const validForm = () => ({ type: actions.VALID_FORM });
export const invalidForm = error => ({ type: actions.INVALID_FORM, error });
//==============================================================================
// VERIFY EMAIL
//==============================================================================
const verifyEmailRequest = () => ({
type: actions.VERIFY_EMAIL_REQUEST,
});
const verifyEmailSuccess = () => ({
type: actions.VERIFY_EMAIL_SUCCESS,
});
const verifyEmailFailure = error => ({
type: actions.VERIFY_EMAIL_FAILURE,
error,
});
export const requestConfirmEmail = email => (dispatch, getState, { rest }) => {
const redirectUri = getState().auth.redirectUri;
dispatch(verifyEmailRequest());
return rest('/users/resend-verify', {
method: 'POST',
body: { email },
headers: { 'X-Pym-Url': redirectUri },
})
.then(() => {
dispatch(verifyEmailSuccess());
})
.catch(error => {
console.error(error);
dispatch(verifyEmailFailure(error));
throw error;
});
};
// Login Popup actions.
export const setRequireEmailVerification = required => ({
type: actions.SET_REQUIRE_EMAIL_VERIFICATION,
required,
});
export const setRedirectUri = uri => ({
type: actions.SET_REDIRECT_URI,
uri,
});
//==============================================================================
// Edit Username
//==============================================================================
const editUsernameFailure = error => ({
type: actions.EDIT_USERNAME_FAILURE,
error,
});
const editUsernameSuccess = () => ({ type: actions.EDIT_USERNAME_SUCCESS });
export const editName = username => (dispatch, _, { rest }) => {
return rest('/account/username', { method: 'PUT', body: { username } })
.then(() => {
dispatch(editUsernameSuccess());
dispatch(notify('success', t('framework.success_name_update')));
})
.catch(error => {
console.error(error);
const errorMessage = error.translation_key
? t(`error.${error.translation_key}`)
: error.toString();
dispatch(editUsernameFailure(errorMessage));
});
};
@@ -1,57 +1,4 @@
export const CHANGE_VIEW = 'CHANGE_VIEW';
export const CLEAN_STATE = 'CLEAN_STATE';
export const SHOW_SIGNIN_DIALOG = 'SHOW_SIGNIN_DIALOG';
export const HIDE_SIGNIN_DIALOG = 'HIDE_SIGNIN_DIALOG';
export const FOCUS_SIGNIN_DIALOG = 'FOCUS_SIGNIN_DIALOG';
export const BLUR_SIGNIN_DIALOG = 'BLUR_SIGNIN_DIALOG';
export const CREATE_USERNAME_REQUEST = 'CREATE_USERNAME_REQUEST';
export const CREATE_USERNAME_SUCCESS = 'CREATE_USERNAME_SUCCESS';
export const CREATE_USERNAME_FAILURE = 'CREATE_USERNAME_FAILURE';
export const CREATE_USERNAME = 'CREATE_USERNAME';
export const SHOW_CREATEUSERNAME_DIALOG = 'SHOW_CREATEUSERNAME_DIALOG';
export const HIDE_CREATEUSERNAME_DIALOG = 'HIDE_CREATEUSERNAME_DIALOG';
export const EDIT_USERNAME_REQUEST = 'CREATE_USERNAME_REQUEST';
export const EDIT_USERNAME_SUCCESS = 'CREATE_USERNAME_SUCCESS';
export const EDIT_USERNAME_FAILURE = 'CREATE_USERNAME_FAILURE';
export const EDIT_USERNAME = 'CREATE_USERNAME';
export const FETCH_SIGNUP_REQUEST = 'FETCH_SIGNUP_REQUEST';
export const FETCH_SIGNUP_FAILURE = 'FETCH_SIGNUP_FAILURE';
export const FETCH_SIGNUP_SUCCESS = 'FETCH_SIGNUP_SUCCESS';
export const FETCH_SIGNIN_REQUEST = 'FETCH_SIGNIN_REQUEST';
export const FETCH_SIGNIN_FAILURE = 'FETCH_SIGNIN_FAILURE';
export const FETCH_SIGNIN_SUCCESS = 'FETCH_SIGNIN_SUCCESS';
export const FETCH_SIGNIN_FACEBOOK_REQUEST = 'FETCH_SIGNIN_FACEBOOK_REQUEST';
export const FETCH_SIGNIN_FACEBOOK_FAILURE = 'FETCH_SIGNIN_FACEBOOK_FAILURE';
export const FETCH_SIGNIN_FACEBOOK_SUCCESS = 'FETCH_SIGNIN_FACEBOOK_SUCCESS';
export const FETCH_SIGNUP_FACEBOOK_REQUEST = 'FETCH_SIGNUP_FACEBOOK_REQUEST';
export const FETCH_FORGOT_PASSWORD_REQUEST = 'FETCH_FORGOT_PASSWORD_REQUEST';
export const FETCH_FORGOT_PASSWORD_SUCCESS = 'FETCH_FORGOT_PASSWORD_SUCCESS';
export const FETCH_FORGOT_PASSWORD_FAILURE = 'FETCH_FORGOT_PASSWORD_FAILURE';
export const LOGOUT = 'LOGOUT';
export const INVALID_FORM = 'INVALID_FORM';
export const VALID_FORM = 'VALID_FORM';
export const CHECK_LOGIN_REQUEST = 'CHECK_LOGIN_REQUEST';
export const CHECK_LOGIN_SUCCESS = 'CHECK_LOGIN_SUCCESS';
export const CHECK_LOGIN_FAILURE = 'CHECK_LOGIN_FAILURE';
export const VERIFY_EMAIL_REQUEST = 'VERIFY_EMAIL_REQUEST';
export const VERIFY_EMAIL_SUCCESS = 'VERIFY_EMAIL_SUCCESS';
export const VERIFY_EMAIL_FAILURE = 'VERIFY_EMAIL_FAILURE';
export const UPDATE_USERNAME = 'UPDATE_USERNAME';
// Login Popup actions.
export const SET_REQUIRE_EMAIL_VERIFICATION = 'SET_REQUIRE_EMAIL_VERIFICATION';
export const SET_REDIRECT_URI = 'SET_REDIRECT_URI';
export const RESET_SIGNIN_DIALOG = 'RESET_SIGNIN_DIALOG';
export const UPDATE_STATUS = 'UPDATE_STATUS';
@@ -1,34 +1,10 @@
import * as actions from '../constants/login';
import pym from 'coral-framework/services/pym';
import merge from 'lodash/merge';
const initialState = {
parentUrl: pym.parentUrl || location.href,
showSignInDialog: false,
signInDialogFocus: false,
// TODO: remove the rest
isLoading: false,
loggedIn: false,
user: null,
showCreateUsernameDialog: false,
checkedInitialLogin: false,
view: 'SIGNIN',
error: null,
passwordRequestSuccess: null,
passwordRequestFailure: null,
emailVerificationFailure: false,
emailVerificationLoading: false,
emailVerificationSuccess: false,
successSignUp: false,
fromSignUp: false,
requireEmailConfirmation: false,
redirectUri: pym.parentUrl || location.href,
};
const purge = user => {
const {settings, ...userData} = user; // eslint-disable-line
return userData;
};
export default function login(state = initialState, action) {
@@ -56,204 +32,6 @@ export default function login(state = initialState, action) {
showSignInDialog: false,
signInDialogFocus: false,
};
// TODO: remove the rest.
case actions.RESET_SIGNIN_DIALOG:
return {
...state,
isLoading: false,
showSignInDialog: false,
signInDialogFocus: false,
view: 'SIGNIN',
error: null,
passwordRequestFailure: null,
passwordRequestSuccess: null,
emailVerificationFailure: false,
emailVerificationSuccess: false,
emailVerificationLoading: false,
successSignUp: false,
};
case actions.SHOW_CREATEUSERNAME_DIALOG:
return {
...state,
showCreateUsernameDialog: true,
};
case actions.HIDE_CREATEUSERNAME_DIALOG:
return {
...state,
showCreateUsernameDialog: false,
};
case actions.CREATE_USERNAME_SUCCESS:
return {
...state,
showCreateUsernameDialog: false,
error: null,
};
case actions.CREATE_USERNAME_FAILURE:
return {
...state,
error: action.error,
};
case actions.CHANGE_VIEW:
return {
...state,
error: action.error,
view: action.view,
};
case actions.CLEAN_STATE:
return initialState;
case actions.FETCH_SIGNIN_REQUEST:
return {
...state,
email: action.email,
isLoading: true,
};
case actions.CHECK_LOGIN_FAILURE:
return {
...state,
checkedInitialLogin: true,
loggedIn: false,
user: null,
};
case actions.CHECK_LOGIN_SUCCESS:
return {
...state,
checkedInitialLogin: true,
loggedIn: true,
user: purge(action.user),
};
case actions.FETCH_SIGNIN_SUCCESS:
return {
...state,
loggedIn: true,
user: purge(action.user),
};
case actions.FETCH_SIGNIN_FAILURE:
return {
...state,
isLoading: false,
error: action.error,
user: null,
view:
action.error.translation_key === 'EMAIL_NOT_VERIFIED'
? 'RESEND_VERIFICATION'
: state.view,
};
case actions.FETCH_SIGNUP_FACEBOOK_REQUEST:
return {
...state,
fromSignUp: true,
};
case actions.FETCH_SIGNIN_FACEBOOK_REQUEST:
return {
...state,
fromSignUp: false,
};
case actions.FETCH_SIGNIN_FACEBOOK_SUCCESS:
return {
...state,
loggedIn: true,
user: purge(action.user),
};
case actions.FETCH_SIGNIN_FACEBOOK_FAILURE:
return {
...state,
error: action.error,
user: null,
};
case actions.FETCH_SIGNUP_REQUEST:
return {
...state,
isLoading: true,
};
case actions.FETCH_SIGNUP_FAILURE:
return {
...state,
error: action.error,
isLoading: false,
};
case actions.FETCH_SIGNUP_SUCCESS:
return {
...state,
isLoading: false,
successSignUp: true,
};
case actions.LOGOUT:
return {
...state,
user: null,
isLoading: false,
loggedIn: false,
};
case actions.INVALID_FORM:
return {
...state,
error: action.error,
};
case actions.VALID_FORM:
return {
...state,
error: null,
};
case actions.FETCH_FORGOT_PASSWORD_SUCCESS:
return {
...state,
passwordRequestFailure: null,
passwordRequestSuccess:
'If you have a registered account, a password reset link was sent to that email',
};
case actions.FETCH_FORGOT_PASSWORD_FAILURE:
return {
...state,
passwordRequestFailure:
'There was an error sending your password reset email. Please try again soon!',
passwordRequestSuccess: null,
};
case actions.UPDATE_USERNAME:
return {
...state,
user: {
...state.user,
username: action.username,
lowercaseUsername: action.username.toLowerCase(),
},
};
case actions.VERIFY_EMAIL_FAILURE:
return {
...state,
emailVerificationFailure: action.error,
emailVerificationLoading: false,
};
case actions.VERIFY_EMAIL_REQUEST:
return {
...state,
emailVerificationLoading: true,
};
case actions.VERIFY_EMAIL_SUCCESS:
return {
...state,
emailVerificationSuccess: true,
emailVerificationLoading: false,
};
case actions.SET_REQUIRE_EMAIL_VERIFICATION:
return {
...state,
requireEmailConfirmation: action.required,
};
case actions.SET_REDIRECT_URI:
return {
...state,
redirectUri: action.uri,
};
case actions.UPDATE_STATUS: {
return {
...state,
user: {
...state.user,
status: merge({}, state.user.status, action.status),
},
};
}
default:
return state;
}
@@ -15,10 +15,7 @@ import {
withEditComment,
} from 'coral-framework/graphql/mutations';
import {
showSignInDialog,
editName,
} from 'coral-embed-stream/src/actions/login';
import { showSignInDialog } from 'coral-embed-stream/src/actions/login';
import { notify } from 'coral-framework/actions/notification';
import {
setActiveReplyBox,
@@ -465,7 +462,6 @@ const mapDispatchToProps = dispatch =>
showSignInDialog,
notify,
setActiveReplyBox,
editName,
viewAllComments,
setActiveStreamTab: setActiveTab,
},
+1
View File
@@ -9,6 +9,7 @@ export { default as withMergedSettings } from './withMergedSettings';
export { default as withSignIn } from './withSignIn';
export { default as withSignUp } from './withSignUp';
export { default as withForgotPassword } from './withForgotPassword';
export { default as withSetUsername } from './withSetUsername';
export {
default as withResendEmailConfirmation,
} from './withResendEmailConfirmation';
@@ -0,0 +1,100 @@
import React from 'react';
import hoistStatics from 'recompose/hoistStatics';
import PropTypes from 'prop-types';
import { getErrorMessages } from '../utils';
import validate from '../helpers/validate';
import errorMsg from 'coral-framework/helpers/error';
import t from '../services/i18n';
import { withSetUsername as withSetUsernameMutation } from 'coral-framework/graphql/mutations';
import { updateUsername, updateStatus } from '../actions/auth';
import { compose } from 'recompose';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import get from 'lodash/get';
/**
* withSetUsername provides properties
* `setUsername`,
* `loading`,
* `errorMessage`,
* `requireEmailVerification`,
* `success`,
* `validate`.
*/
const withSetUsername = hoistStatics(WrappedComponent => {
class WithSetUsername extends React.Component {
static propTypes = {
setUsername: PropTypes.func.isRequired,
currentUserId: PropTypes.string,
updateUsername: PropTypes.func.isRequired,
updateStatus: PropTypes.func.isRequired,
};
state = {
error: null,
loading: false,
success: false,
};
validateUsername = value => {
if (!value) {
return t('sign_in.required_field');
}
return validate.username(value) ? '' : errorMsg.username;
};
setUsername = async username => {
if (!this.props.currentUserId) {
throw new Error('User not logged in');
}
try {
await this.props.setUsername(this.props.currentUserId, username);
this.props.updateUsername(username);
this.props.updateStatus({ username: { status: 'SET' } });
this.setState({ success: true, loading: false, error: null });
} catch (error) {
if (!error.status || error.status !== 401) {
console.error(error);
}
const changeSet = { success: false, loading: false, error };
this.setState(changeSet);
}
};
getErrorMessage() {
if (!this.state.error) {
return '';
}
return getErrorMessages(this.state.error).join(', ');
}
render() {
return (
<WrappedComponent
{...this.props}
setUsername={this.setUsername}
loading={this.state.loading}
errorMessage={this.getErrorMessage()}
success={this.state.success}
validateUsername={this.validateUsername}
/>
);
}
}
return WithSetUsername;
});
const mapStateToProps = ({ auth }) => ({
currentUserId: get(auth, 'user.id'),
});
const mapDispatchToProps = dispatch =>
bindActionCreators({ updateUsername, updateStatus }, dispatch);
export default compose(
connect(mapStateToProps, mapDispatchToProps),
withSetUsernameMutation,
withSetUsername
);
+1
View File
@@ -10,6 +10,7 @@ export {
withSignIn,
withSignUp,
withResendEmailConfirmation,
withSetUsername,
} from 'coral-framework/hocs';
export {
withIgnoreUser,
+6
View File
@@ -0,0 +1,6 @@
import get from 'lodash/get';
export const usernameStatusSelector = state =>
get(state, 'auth.user.status.username.status');
export const usernameSelector = state => get(state, 'auth.user.username');
+2 -1
View File
@@ -1,5 +1,6 @@
import UserBox from './stream/containers/UserBox';
import SignInButton from './stream/containers/SignInButton';
import SetUsernameDialog from './stream/containers/SetUsernameDialog';
import translations from './translations.yml';
import Login from './login/containers/Main';
import reducer from './login/reducer';
@@ -8,7 +9,7 @@ export default {
reducer,
translations,
slots: {
stream: [UserBox, SignInButton],
stream: [UserBox, SignInButton, SetUsernameDialog],
login: [Login],
},
};
@@ -0,0 +1,38 @@
.root {
border-top: 1px solid rgba(0, 0, 0, 0.1);
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
margin-bottom: 10px;
padding: 8px 0px 10px 0px;
position: relative;
}
.footer {
display: flex;
justify-content: space-between;
}
.button {
color: #2a2a2a;
margin: 5px 10px 5px 0px;
background: none;
padding: 0px;
border: none;
font-size: inherit;
vertical-align: middle;
&:hover {
color: #767676;
cursor: pointer;
}
}
.icon {
font-size: 12px;
padding: 0 2px 0 5px;
vertical-align: middle;
}
.authorName {
margin-right: 5px;
font-weight: bold;
}
@@ -0,0 +1,42 @@
import React from 'react';
import PropTypes from 'prop-types';
import styles from './FakeComment.css';
import { Icon } from 'plugin-api/beta/client/components/ui';
import { CommentTimestamp } from 'plugin-api/beta/client/components';
import { t } from 'plugin-api/beta/client/services';
export const FakeComment = ({ username, created_at, body }) => (
<div className={styles.root}>
<span className={styles.authorName}>{username}</span>
<CommentTimestamp created_at={created_at} />
<div className={styles.body}>{body}</div>
<div className={styles.footer}>
<div>
<button className={styles.button}>
<span className={styles.label}>{t('like')}</span>
<Icon name="thumb_up" className={styles.icon} />
</button>
<button className={styles.button}>
<span className={styles.label}>{t('reply')}</span>
<Icon name="reply" className={styles.icon} />
</button>
</div>
<div>
<button className={styles.button}>
<span className={styles.label}>{t('permalink')}</span>
<Icon name="link" className={styles.icon} />
</button>
<button className={styles.button}>
<span className={styles.label}>{t('report')}</span>
<Icon name="flag" className={styles.icon} />
</button>
</div>
</div>
</div>
);
FakeComment.propTypes = {
username: PropTypes.string.isRequired,
created_at: PropTypes.string.isRequired,
body: PropTypes.string.isRequired,
};
@@ -0,0 +1,41 @@
.dialogusername {
border: none;
box-shadow: 0 9px 46px 8px rgba(0, 0, 0, 0.14), 0 11px 15px -7px rgba(0, 0, 0, 0.12), 0 24px 38px 3px rgba(0, 0, 0, 0.2);
width: 400px;
top: 10px;
}
.yourusername {
display: block;
}
.example {
display: block;
}
.ifyoudont {
display: block;
margin-top: 15px;
}
.saveusername {
display: block;
width: 100%;
}
.savebutton {
display: inline;
background-color: rgb(105,105,105);
color: white;
}
.fakeComment {
display: block;
margin-bottom: 5px;
}
.hint {
color: grey;
font-weight: 600;
padding: 3px 0 16px;
}
@@ -1,6 +1,6 @@
import React from 'react';
import PropTypes from 'prop-types';
import styles from './styles.css';
import styles from './SetUsernameDialog.css';
import {
Dialog,
Alert,
@@ -8,76 +8,73 @@ import {
Button,
} from 'plugin-api/beta/client/components/ui';
import { FakeComment } from './FakeComment';
import t from 'coral-framework/services/i18n';
import { t } from 'plugin-api/beta/client/services';
const SetUsernameDialog = ({
open,
handleClose,
formData,
handleSubmitUsername,
handleChange,
...props
}) => (
<Dialog
className={styles.dialogusername}
id="createUsernameDialog"
open={open}
>
<span className={styles.close} onClick={handleClose}>
×
</span>
<div>
<div className={styles.header}>
<h1>{t('createdisplay.write_your_username')}</h1>
</div>
<div>
<p className={styles.yourusername}>
{t('createdisplay.your_username')}
</p>
<FakeComment
className={styles.fakeComment}
username={formData.username}
created_at={new Date().toISOString()}
body={t('createdisplay.fake_comment_body')}
/>
<p className={styles.ifyoudont}>
{t('createdisplay.if_you_dont_change_your_name')}
</p>
{props.auth.error && <Alert>{props.auth.error}</Alert>}
<form id="saveUsername" onSubmit={handleSubmitUsername}>
{props.errors.username && (
<span className={styles.hint}>
{' '}
{t('createdisplay.special_characters')}{' '}
</span>
)}
<div className={styles.saveusername}>
<TextField
id="username"
style={{ fontSize: 16 }}
type="string"
label={t('createdisplay.username')}
value={formData.username}
onChange={handleChange}
/>
<Button id="save" type="submit" className={styles.saveButton}>
{t('createdisplay.save')}
</Button>
class SetUsernameDialog extends React.Component {
handleUsernameChange = e => this.props.onUsernameChange(e.target.value);
handleSubmit = e => {
e.preventDefault();
this.props.onSubmit();
};
render() {
const { username, usernameError, errorMessage } = this.props;
return (
<Dialog className={styles.dialogusername} id="createUsernameDialog" open>
<div>
<div className={styles.header}>
<h1>{t('createdisplay.write_your_username')}</h1>
</div>
</form>
</div>
</div>
</Dialog>
);
<div>
<p className={styles.yourusername}>
{t('createdisplay.your_username')}
</p>
<FakeComment
className={styles.fakeComment}
username={username}
created_at={new Date().toISOString()}
body={t('createdisplay.fake_comment_body')}
/>
{errorMessage && <Alert>{errorMessage}</Alert>}
<form id="saveUsername" onSubmit={this.handleSubmit}>
{usernameError && (
<span className={styles.hint}>
{' '}
{t('createdisplay.special_characters')}{' '}
</span>
)}
<div className={styles.saveusername}>
<TextField
id="username"
style={{ fontSize: 16 }}
type="string"
label={t('createdisplay.username')}
value={username}
showErrors={!!usernameError}
errorMsg={usernameError}
onChange={this.handleUsernameChange}
/>
<Button id="save" type="submit" className={styles.saveButton}>
{t('createdisplay.save')}
</Button>
</div>
</form>
</div>
</div>
</Dialog>
);
}
}
SetUsernameDialog.propTypes = {
open: PropTypes.bool,
handleClose: PropTypes.func,
formData: PropTypes.object,
handleSubmitUsername: PropTypes.func,
handleChange: PropTypes.func,
auth: PropTypes.object,
errors: PropTypes.object,
loading: PropTypes.bool.isRequired,
username: PropTypes.string.isRequired,
usernameError: PropTypes.string.isRequired,
onUsernameChange: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
errorMessage: PropTypes.string.isRequired,
};
export default SetUsernameDialog;
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import { Button } from 'plugin-api/beta/client/components/ui';
import t from 'coral-framework/services/i18n';
import { t } from 'plugin-api/beta/client/services';
const SignInButton = ({ currentUser, showSignInDialog }) => (
<div className="talk-stream-auth-sign-in-button">
@@ -1,7 +1,7 @@
import React from 'react';
import PropTypes from 'prop-types';
import styles from './UserBox.css';
import t from 'coral-framework/services/i18n';
import { t } from 'plugin-api/beta/client/services';
import cn from 'classnames';
const UserBox = ({ user, logout, onShowProfile }) => (
@@ -1,183 +1,64 @@
import React from 'react';
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { connect } from 'react-redux';
import { compose } from 'react-apollo';
import { bindActionCreators } from 'redux';
import errorMsj from 'coral-framework/helpers/error';
import validate from 'coral-framework/helpers/validate';
import CreateUsernameDialog from './CreateUsernameDialog';
import { withSetUsername } from 'coral-framework/graphql/mutations';
import { forEachError } from 'plugin-api/beta/client/utils';
import t from 'coral-framework/services/i18n';
import { connect, withSetUsername } from 'plugin-api/beta/client/hocs';
import { compose, branch, renderNothing } from 'recompose';
import {
showCreateUsernameDialog,
hideCreateUsernameDialog,
invalidForm,
validForm,
updateUsername,
} from 'coral-embed-stream/src/actions/login';
usernameStatusSelector,
usernameSelector,
} from 'plugin-api/beta/client/selectors/auth';
import SetUsernameDialog from '../components/SetUsernameDialog';
class SetUsernameDialog extends React.Component {
constructor(props) {
super(props);
this.state = {
formData: {
username: (props.auth.user && props.auth.user.username) || '',
},
errors: {},
showErrors: false,
};
}
componentWillReceiveProps(next) {
if (
!this.props.auth.showCreateUsernameDialog &&
next.auth.showCreateUsernameDialog
) {
this.setState({
formData: {
username:
(this.props.auth.user && this.props.auth.user.username) || '',
},
});
}
}
handleChange = e => {
const { name, value } = e.target;
this.setState(
state => ({
...state,
formData: {
...state.formData,
[name]: value,
},
}),
() => {
this.validation(name, value);
}
);
class SetUsernameDialogContainer extends Component {
state = {
username: this.props.username,
usernameError: '',
};
addError = (name, error) => {
return this.setState(state => ({
errors: {
...state.errors,
[name]: error,
},
}));
};
validation = (name, value) => {
const { addError } = this;
if (!value.length) {
addError(name, t('createdisplay.required_field'));
} else if (!validate[name](value)) {
addError(name, errorMsj[name]);
handleSubmit = () => {
const validationError = this.props.validateUsername(this.state.username);
if (validationError) {
this.setState({ usernameError: validationError });
} else {
const {[name]: prop, ...errors} = this.state.errors; // eslint-disable-line
// Removes Error
this.setState(state => ({ ...state, errors }));
this.props.setUsername(this.state.username);
}
};
isCompleted = () => {
const { formData } = this.state;
return !Object.keys(formData).filter(prop => !formData[prop].length).length;
};
displayErrors = (show = true) => {
this.setState({ showErrors: show });
};
async setUsernameAndClose(username, props = this.props) {
const {
validForm,
invalidForm,
setUsername,
hideCreateUsernameDialog,
updateUsername,
} = props;
try {
// Perform mutation
await setUsername(this.props.auth.user.id, username);
// Also change in redux store...
updateUsername(username);
hideCreateUsernameDialog();
validForm();
} catch (error) {
const msgs = [];
forEachError(error, ({ msg }) => msgs.push(msg));
invalidForm(t(msgs.join(', ')));
}
}
handleSubmitUsername = e => {
e.preventDefault();
const { errors, formData: { username } } = this.state;
const { invalidForm } = this.props;
this.displayErrors();
if (this.isCompleted() && !Object.keys(errors).length) {
this.setUsernameAndClose(username);
} else {
invalidForm(t('createdisplay.check_the_form'));
}
};
handleClose = () => {
this.setUsernameAndClose(this.props.auth.user.username);
};
setUsername = username => this.setState({ username });
render() {
const { loggedIn, auth } = this.props;
if (!this.props.unset) {
return null;
}
return (
<div>
<CreateUsernameDialog
open={auth.showCreateUsernameDialog}
handleClose={this.handleClose}
loggedIn={loggedIn}
handleSubmitUsername={this.handleSubmitUsername}
{...this}
{...this.state}
{...this.props}
/>
</div>
<SetUsernameDialog
username={this.state.username}
usernameError={this.state.usernameError}
onSubmit={this.handleSubmit}
onUsernameChange={this.setUsername}
errorMessage={this.props.errorMessage}
loading={this.props.loading}
/>
);
}
}
SetUsernameDialog.propTypes = {
auth: PropTypes.object,
hideCreateUsernameDialog: PropTypes.func,
validForm: PropTypes.func,
invalidForm: PropTypes.func,
loggedIn: PropTypes.bool,
changeUsername: PropTypes.func,
SetUsernameDialogContainer.propTypes = {
unset: PropTypes.bool.isRequired,
username: PropTypes.string,
setUsername: PropTypes.func.isRequired,
loading: PropTypes.bool.isRequired,
errorMessage: PropTypes.string.isRequired,
success: PropTypes.bool.isRequired,
validateUsername: PropTypes.func.isRequired,
};
const mapStateToProps = ({ auth }) => ({
auth: auth,
const mapStateToProps = state => ({
unset: usernameStatusSelector(state) === 'UNSET',
username: usernameSelector(state),
});
const mapDispatchToProps = dispatch =>
bindActionCreators(
{
showCreateUsernameDialog,
hideCreateUsernameDialog,
invalidForm,
validForm,
updateUsername,
},
dispatch
);
export default compose(
connect(mapStateToProps, null),
withSetUsername,
connect(mapStateToProps, mapDispatchToProps)
)(SetUsernameDialog);
branch(props => !props.username, renderNothing)
)(SetUsernameDialogContainer);
@@ -6,8 +6,6 @@ en:
verify_email2: "You must verify your account before engaging with the community."
not_you: "Not you?"
logged_in_as: "Signed in as"
facebook_sign_in: "Sign in with Facebook"
facebook_sign_up: "Sign up with Facebook"
logout: "Sign out"
sign_in: "Sign in"
sign_in_to_join: "Sign in to join the conversation"
@@ -51,8 +49,6 @@ es:
verify_email2: "Debe confirmarla antes de poder involucrarse en la comunidad."
not_you: "¿No eres tu?"
logged_in_as: "Entraste como"
facebook_sign_in: "Entrar con Facebook"
facebook_sign_up: "Registrarse con Facebook"
logout: "Salir"
sign_in: "Entrar"
sign_in_to_join: "Entrar para unirte a la conversación"
@@ -97,8 +93,6 @@ fr:
verify_email2: "Vous devez vérifier votre adresse e-mail avant de vous engager auprès de la communauté."
not_you: "Pas vous ?"
logged_in_as: "Connecté en tant que"
facebook_sign_in: "Connectez-vous avec Facebook"
facebook_sign_up: "Inscrivez-vous avec Facebook"
logout: "Se déconnecter"
sign_in: "Se connecter"
sign_in_to_join: "Connectez-vous pour participer à la conversation"
@@ -141,8 +135,6 @@ zh_CN:
verify_email2: "您参与社群前须验证帐号。"
not_you: "不是你?"
logged_in_as: "登录身份"
facebook_sign_in: "使用 Facebook 帐号"
facebook_sign_up: "使用 Facebook 帐号"
logout: "登出"
sign_in: "登入"
sign_in_to_join: "登入以加入对话"
@@ -185,8 +177,6 @@ zh_TW:
verify_email2: "您參與社群前須驗證帳號。"
not_you: "不是你?"
logged_in_as: "登錄身份"
facebook_sign_in: "使用 Facebook 帳號"
facebook_sign_up: "使用 Facebook 帳號"
logout: "登出"
sign_in: "登入"
sign_in_to_join: "登入以加入對話"