diff --git a/client/coral-embed-stream/src/AppRouter.js b/client/coral-embed-stream/src/AppRouter.js new file mode 100644 index 000000000..133a3790d --- /dev/null +++ b/client/coral-embed-stream/src/AppRouter.js @@ -0,0 +1,16 @@ +import React from 'react'; +import {Router, Route, browserHistory} from 'react-router'; + +import Embed from './Embed'; +import SignInContainer from 'coral-sign-in/containers/SignInContainer'; + +const routes = ( +
+ + +
+); + +const AppRouter = () => ; + +export default AppRouter; diff --git a/client/coral-embed-stream/src/Comment.js b/client/coral-embed-stream/src/Comment.js index 51402e490..674c03ec5 100644 --- a/client/coral-embed-stream/src/Comment.js +++ b/client/coral-embed-stream/src/Comment.js @@ -19,7 +19,7 @@ import FlagComment from 'coral-plugin-flags/FlagComment'; import LikeButton from 'coral-plugin-likes/LikeButton'; import {BestButton, IfUserCanModifyBest, BEST_TAG, commentIsBest, BestIndicator} from 'coral-plugin-best/BestButton'; import LoadMore from 'coral-embed-stream/src/LoadMore'; -import {Slot} from 'coral-framework'; +import Slot from 'coral-framework/components/Slot'; import IgnoredCommentTombstone from './IgnoredCommentTombstone'; import {TopRightMenu} from './TopRightMenu'; import {getActionSummary, getTotalActionCount, iPerformedThisAction} from 'coral-framework/utils'; diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js index b67e9e1c4..c7c204288 100644 --- a/client/coral-embed-stream/src/Embed.js +++ b/client/coral-embed-stream/src/Embed.js @@ -8,7 +8,7 @@ const lang = new I18n(translations); import {TabBar, Tab, TabContent, Spinner, Button} from 'coral-ui'; -const {logout, showSignInDialog, requestConfirmEmail} = authActions; +const {logout, showSignInDialog, requestConfirmEmail, openSignInPopUp, checkLogin} = authActions; const {addNotification, clearNotification} = notificationActions; const {fetchAssetSuccess} = assetActions; import {NEW_COMMENT_COUNT_POLL_INTERVAL} from 'coral-framework/constants/comments'; @@ -26,7 +26,6 @@ import {ModerationLink} from 'coral-plugin-moderation'; import Count from 'coral-plugin-comment-count/CommentCount'; import CommentBox from 'coral-plugin-commentbox/CommentBox'; import UserBox from 'coral-sign-in/components/UserBox'; -import SignInContainer from 'coral-sign-in/containers/SignInContainer'; import SuspendedAccount from 'coral-framework/components/SuspendedAccount'; import ChangeUsernameContainer from '../../coral-sign-in/containers/ChangeUsernameContainer'; import ProfileContainer from 'coral-settings/containers/ProfileContainer'; @@ -78,6 +77,7 @@ class Embed extends React.Component { componentDidMount () { pym.sendMessage('childReady'); + this.props.checkLogin(); } componentWillUnmount () { @@ -119,8 +119,7 @@ class Embed extends React.Component { setActiveReplyBox = (reactKey) => { if (!this.props.auth.user) { - const offset = document.getElementById(`c_${reactKey}`).getBoundingClientRect().top - 75; - this.props.showSignInDialog(offset); + this.props.showSignInDialog(); } else { this.setState({activeReplyBox: reactKey}); } @@ -130,7 +129,7 @@ class Embed extends React.Component { const {activeTab} = this.state; const {closedAt, countCache = {}} = this.props.asset; const {asset, refetch, comment} = this.props.data; - const {loggedIn, isAdmin, user, showSignInDialog, signInOffset} = this.props.auth; + const {loggedIn, isAdmin, user, showSignInDialog} = this.props.auth; // even though the permalinked comment is the highlighted one, we're displaying its parent + replies const highlightedComment = comment && comment.parent ? comment.parent : comment; @@ -218,11 +217,10 @@ class Embed extends React.Component { :

{asset.settings.closedMessage}

} - {!loggedIn && } - {loggedIn && user && } + + {!loggedIn && } + + {loggedIn && user && } {loggedIn && } {/* the highlightedComment is isolated after the user followed a permalink */} @@ -290,7 +288,6 @@ class Embed extends React.Component { @@ -320,10 +317,12 @@ const mapDispatchToProps = dispatch => ({ addNotification: (type, text) => addNotification(type, text), clearNotification: () => dispatch(clearNotification()), editName: (username) => dispatch(editName(username)), - showSignInDialog: (offset) => dispatch(showSignInDialog(offset)), + showSignInDialog: () => dispatch(showSignInDialog()), updateCountCache: (id, count) => dispatch(updateCountCache(id, count)), viewAllComments: () => dispatch(viewAllComments()), logout: () => dispatch(logout()), + openSignInPopUp: cb => dispatch(openSignInPopUp(cb)), + checkLogin: () => dispatch(checkLogin()), dispatch: d => dispatch(d), }); diff --git a/client/coral-embed-stream/src/index.js b/client/coral-embed-stream/src/index.js index 3dc69400c..d7ee99e73 100644 --- a/client/coral-embed-stream/src/index.js +++ b/client/coral-embed-stream/src/index.js @@ -3,13 +3,15 @@ import {render} from 'react-dom'; import {ApolloProvider} from 'react-apollo'; import {client} from 'coral-framework/services/client'; -import store from 'coral-framework/services/store'; +import localStore from 'coral-framework/services/store'; -import Embed from './Embed'; +import AppRouter from './AppRouter'; + +const store = (window.opener && window.opener.coralStore) ? window.opener.coralStore : localStore; render( - + , document.querySelector('#coralStream') ); diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js index 11e7bd996..e112b2b6c 100644 --- a/client/coral-framework/actions/auth.js +++ b/client/coral-framework/actions/auth.js @@ -11,6 +11,16 @@ const ME_QUERY = gql` query Me { me { status + comments { + id + body + asset { + id + title + url + } + created_at + } } } `; @@ -22,8 +32,23 @@ function fetchMe() { } // Dialog Actions -export const showSignInDialog = (offset = 0) => ({type: actions.SHOW_SIGNIN_DIALOG, offset}); -export const hideSignInDialog = () => ({type: actions.HIDE_SIGNIN_DIALOG}); +export const showSignInDialog = () => dispatch => { + const signInPopUp = window.open( + '/embed/stream/login', + 'Login', + 'menubar=0,resizable=0,width=500,height=550,top=200,left=500' + ); + + signInPopUp.onbeforeunload = () => { + dispatch(checkLogin()); + fetchMe(); + }; + dispatch({type: actions.SHOW_SIGNIN_DIALOG}); +}; +export const hideSignInDialog = () => dispatch => { + dispatch({type: actions.HIDE_SIGNIN_DIALOG}); + window.close(); +}; export const createUsernameRequest = () => ({type: actions.CREATE_USERNAME_REQUEST}); export const showCreateUsernameDialog = () => ({type: actions.SHOW_CREATEUSERNAME_DIALOG}); @@ -47,29 +72,39 @@ export const createUsername = (userId, formData) => dispatch => { }); }; -export const changeView = view => dispatch => +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 = () => ({type: actions.FETCH_SIGNIN_REQUEST}); -const signInSuccess = (user, isAdmin) => ({type: actions.FETCH_SIGNIN_SUCCESS, user, isAdmin}); + +// TODO: revisit login redux flow. +// const signInSuccess = (user, isAdmin) => ({type: actions.FETCH_SIGNIN_SUCCESS, user, isAdmin}); +// const signInFailure = error => ({type: actions.FETCH_SIGNIN_FAILURE, error}); export const fetchSignIn = (formData) => (dispatch) => { dispatch(signInRequest()); return coralApi('/auth/local', {method: 'POST', body: formData}) - .then(({user}) => { - const isAdmin = !!user && !!user.roles.filter(i => i === 'ADMIN').length; - dispatch(signInSuccess(user, isAdmin)); - dispatch(hideSignInDialog()); - fetchMe(); - }) + .then(() => dispatch(hideSignInDialog())) .catch(error => { if (error.metadata) { @@ -121,7 +156,7 @@ export const facebookCallback = (err, data) => dispatch => { dispatch(signInFacebookSuccess(user)); dispatch(hideSignInDialog()); dispatch(showCreateUsernameDialog()); - fetchMe(); + dispatch(hideSignInDialog()); } catch (err) { dispatch(signInFacebookFailure(err)); return; diff --git a/client/coral-framework/index.js b/client/coral-framework/index.js index 96750bffd..b85b69bcd 100644 --- a/client/coral-framework/index.js +++ b/client/coral-framework/index.js @@ -1,16 +1,12 @@ -import store from './services/store'; import pym from './services/PymConnection'; import I18n from './modules/i18n/i18n'; import actions from './actions'; -import Slot from './components/Slot'; // TODO (bc): Deprecate old actions. Spreading actions is now needed. export default { pym, - Slot, I18n, - store, actions, ...actions }; diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js index f9712c937..6e678cab9 100644 --- a/client/coral-framework/reducers/auth.js +++ b/client/coral-framework/reducers/auth.js @@ -28,8 +28,7 @@ export default function auth (state = initialState, action) { switch (action.type) { case actions.SHOW_SIGNIN_DIALOG : return state - .set('showSignInDialog', true) - .set('signInOffset', action.offset); + .set('showSignInDialog', true); case actions.HIDE_SIGNIN_DIALOG : return state.merge(Map({ isLoading: false, diff --git a/client/coral-framework/services/store.js b/client/coral-framework/services/store.js index fbc444eec..d7090f4b5 100644 --- a/client/coral-framework/services/store.js +++ b/client/coral-framework/services/store.js @@ -24,7 +24,7 @@ if (window.devToolsExtension) { middlewares.push(window.devToolsExtension()); } -export default createStore( +const store = createStore( combineReducers({ ...mainReducer, apollo: client.reducer() @@ -32,3 +32,6 @@ export default createStore( {}, compose(...middlewares) ); + +export default store; +window.coralStore = store; diff --git a/client/coral-plugin-commentbox/CommentBox.js b/client/coral-plugin-commentbox/CommentBox.js index f395b56c9..2a988711d 100644 --- a/client/coral-plugin-commentbox/CommentBox.js +++ b/client/coral-plugin-commentbox/CommentBox.js @@ -2,7 +2,7 @@ import React, {Component, PropTypes} from 'react'; import {I18n} from '../coral-framework'; import translations from './translations.json'; import {Button} from 'coral-ui'; -import {Slot} from 'coral-framework'; +import Slot from 'coral-framework/components/Slot'; import {connect} from 'react-redux'; const name = 'coral-plugin-commentbox'; diff --git a/client/coral-plugin-flags/FlagButton.js b/client/coral-plugin-flags/FlagButton.js index 054ca2fb1..16e616379 100644 --- a/client/coral-plugin-flags/FlagButton.js +++ b/client/coral-plugin-flags/FlagButton.js @@ -25,8 +25,7 @@ class FlagButton extends Component { const {localPost, localDelete} = this.state; const localFlagged = (flaggedByCurrentUser && !localDelete) || localPost; if (!currentUser) { - const offset = document.getElementById(`c_${this.props.id}`).getBoundingClientRect().top - 75; - this.props.showSignInDialog(offset); + this.props.showSignInDialog(); return; } if (localFlagged) { diff --git a/client/coral-plugin-likes/LikeButton.js b/client/coral-plugin-likes/LikeButton.js index 8f6964051..28382dbc2 100644 --- a/client/coral-plugin-likes/LikeButton.js +++ b/client/coral-plugin-likes/LikeButton.js @@ -35,8 +35,7 @@ class LikeButton extends Component { const onLikeClick = () => { if (!currentUser) { - const offset = document.getElementById(`c_${id}`).getBoundingClientRect().top - 75; - showSignInDialog(offset); + showSignInDialog(); return; } if (currentUser.banned) { diff --git a/client/coral-settings/components/NotLoggedIn.js b/client/coral-settings/components/NotLoggedIn.js index c76553c50..a5d8b0693 100644 --- a/client/coral-settings/components/NotLoggedIn.js +++ b/client/coral-settings/components/NotLoggedIn.js @@ -1,17 +1,13 @@ import React from 'react'; import styles from './NotLoggedIn.css'; -import SignInContainer from '../../coral-sign-in/containers/SignInContainer'; import translations from '../translations'; import I18n from 'coral-framework/modules/i18n/i18n'; const lang = new I18n(translations); -export default ({showSignInDialog, requireEmailConfirmation}) => ( +export default ({showSignInDialog}) => (
-
- { - showSignInDialog(); - }}>{lang.t('signIn')} {lang.t('toAccess')} + {lang.t('signIn')} {lang.t('toAccess')}
{lang.t('fromSettingsPage')} diff --git a/client/coral-settings/containers/ProfileContainer.js b/client/coral-settings/containers/ProfileContainer.js index 2d756077d..553504462 100644 --- a/client/coral-settings/containers/ProfileContainer.js +++ b/client/coral-settings/containers/ProfileContainer.js @@ -2,6 +2,7 @@ import {connect} from 'react-redux'; import {compose} from 'react-apollo'; import React, {Component} from 'react'; import I18n from 'coral-framework/modules/i18n/i18n'; +import {bindActionCreators} from 'redux'; import {myCommentHistory, myIgnoredUsers} from 'coral-framework/graphql/queries'; import {stopIgnoringUser} from 'coral-framework/graphql/mutations'; @@ -12,6 +13,8 @@ import IgnoredUsers from '../components/IgnoredUsers'; import {Spinner} from 'coral-ui'; import CommentHistory from 'coral-plugin-history/CommentHistory'; +import {showSignInDialog, checkLogin} from 'coral-framework/actions/auth'; + import translations from '../translations'; const lang = new I18n(translations); @@ -32,17 +35,17 @@ class ProfileContainer extends Component { } render() { - const {loggedIn, asset, showSignInDialog, data, myIgnoredUsersData, stopIgnoringUser} = this.props; + const {loggedIn, asset, data, showSignInDialog, myIgnoredUsersData, stopIgnoringUser} = this.props; const {me} = this.props.data; - if (!loggedIn || !me) { - return ; - } - if (data.loading) { return ; } + if (!loggedIn || !me) { + return ; + } + const localProfile = this.props.user.profiles.find(p => p.provider === 'local'); const emailAddress = localProfile && localProfile.id; @@ -81,7 +84,6 @@ class ProfileContainer extends Component { :

{lang.t('userNoComment')}

} -
); } @@ -93,10 +95,8 @@ const mapStateToProps = state => ({ auth: state.auth.toJS() }); -const mapDispatchToProps = () => ({ - - // saveBio: (user_id, formData) => dispatch(saveBio(user_id, formData)) -}); +const mapDispatchToProps = dispatch => + bindActionCreators({showSignInDialog, checkLogin}, dispatch); export default compose( connect(mapStateToProps, mapDispatchToProps), diff --git a/client/coral-sign-in/components/CreateUsernameDialog.js b/client/coral-sign-in/components/CreateUsernameDialog.js index 4a7a99b81..38fe9dd83 100644 --- a/client/coral-sign-in/components/CreateUsernameDialog.js +++ b/client/coral-sign-in/components/CreateUsernameDialog.js @@ -10,16 +10,12 @@ import I18n from 'coral-framework/modules/i18n/i18n'; import translations from '../translations'; const lang = new I18n(translations); -const CreateUsernameDialog = ({open, handleClose, offset, formData, handleSubmitUsername, handleChange, ...props}) => { +const CreateUsernameDialog = ({open, handleClose, formData, handleSubmitUsername, handleChange, ...props}) => { return ( + open={open}> ×
diff --git a/client/coral-sign-in/components/SignDialog.js b/client/coral-sign-in/components/SignDialog.js index 6243472b4..ff2464f7c 100644 --- a/client/coral-sign-in/components/SignDialog.js +++ b/client/coral-sign-in/components/SignDialog.js @@ -6,15 +6,11 @@ import SignInContent from './SignInContent'; import SignUpContent from './SignUpContent'; import ForgotContent from './ForgotContent'; -const SignDialog = ({open, view, handleClose, offset, ...props}) => ( +const SignDialog = ({open, view, handleClose, ...props}) => ( + open={open}> × {view === 'SIGNIN' && } {view === 'SIGNUP' && } diff --git a/client/coral-sign-in/components/SignInContent.js b/client/coral-sign-in/components/SignInContent.js index a0ed5b5b4..b057e57bd 100644 --- a/client/coral-sign-in/components/SignInContent.js +++ b/client/coral-sign-in/components/SignInContent.js @@ -20,8 +20,8 @@ const SignInContent = ({ }) => { return ( -
-
+
+

{auth.emailVerificationFailure ? lang.t('signIn.emailVerifyCTA') : lang.t('signIn.signIn')}

@@ -42,7 +42,7 @@ const SignInContent = ({ {emailVerificationSuccess && } :
-
+
@@ -80,7 +80,7 @@ const SignInContent = ({
} -
+
changeView('FORGOT')}>{lang.t('signIn.forgotYourPass')} {lang.t('signIn.needAnAccount')} diff --git a/client/coral-sign-in/containers/ChangeUsernameContainer.js b/client/coral-sign-in/containers/ChangeUsernameContainer.js index c4450aa56..a3b4b969d 100644 --- a/client/coral-sign-in/containers/ChangeUsernameContainer.js +++ b/client/coral-sign-in/containers/ChangeUsernameContainer.js @@ -100,12 +100,11 @@ class ChangeUsernameContainer extends Component { } render() { - const {loggedIn, auth, offset} = this.props; + const {loggedIn, auth} = this.props; return (
- {!noButton && } ({ fetchSignUpFacebook: () => dispatch(fetchSignUpFacebook()), fetchForgotPassword: formData => dispatch(fetchForgotPassword(formData)), requestConfirmEmail: (email, url) => dispatch(requestConfirmEmail(email, url)), - showSignInDialog: () => dispatch(showSignInDialog()), changeView: view => dispatch(changeView(view)), handleClose: () => dispatch(hideSignInDialog()), invalidForm: error => dispatch(invalidForm(error)), diff --git a/plugins/coral-plugin-respect/client/components/RespectButton.js b/plugins/coral-plugin-respect/client/components/RespectButton.js index 417b978ad..c1e0c1b47 100644 --- a/plugins/coral-plugin-respect/client/components/RespectButton.js +++ b/plugins/coral-plugin-respect/client/components/RespectButton.js @@ -19,8 +19,7 @@ class RespectButton extends Component { // If the current user does not exist, trigger sign in dialog. if (!me) { - const offset = document.getElementById(`c_${commentId}`).getBoundingClientRect().top - 75; - showSignInDialog(offset); + showSignInDialog(); return; }