diff --git a/client/coral-embed-stream/src/containers/Embed.js b/client/coral-embed-stream/src/containers/Embed.js
index 12e05eed8..d5399fc60 100644
--- a/client/coral-embed-stream/src/containers/Embed.js
+++ b/client/coral-embed-stream/src/containers/Embed.js
@@ -3,6 +3,8 @@ import {compose, gql, graphql} from 'react-apollo';
import {connect} from 'react-redux';
import {bindActionCreators} from 'redux';
import isEqual from 'lodash/isEqual';
+import branch from 'recompose/branch';
+import renderComponent from 'recompose/renderComponent';
import {Spinner} from 'coral-ui';
import {authActions, assetActions, pym} from 'coral-framework';
@@ -19,7 +21,6 @@ class EmbedContainer extends React.Component {
componentDidMount() {
pym.sendMessage('childReady');
- this.props.checkLogin();
}
componentWillReceiveProps(nextProps) {
@@ -108,6 +109,10 @@ const mapDispatchToProps = dispatch =>
export default compose(
connect(mapStateToProps, mapDispatchToProps),
+ branch(
+ props => !props.auth.checkedInitialLogin,
+ renderComponent(Spinner),
+ ),
withQuery,
)(EmbedContainer);
diff --git a/client/coral-embed-stream/src/containers/Stream.js b/client/coral-embed-stream/src/containers/Stream.js
index 4df7fc960..49f234dab 100644
--- a/client/coral-embed-stream/src/containers/Stream.js
+++ b/client/coral-embed-stream/src/containers/Stream.js
@@ -19,24 +19,13 @@ const {showSignInDialog} = authActions;
const {addNotification} = notificationActions;
class StreamContainer extends React.Component {
- getCounts = ({asset_id, limit, sort}) => {
+ getCounts = (variables) => {
return this.props.data.fetchMore({
query: LOAD_COMMENT_COUNTS_QUERY,
- variables: {
- asset_id,
- limit,
- sort,
- excludeIgnored: this.props.data.variables.excludeIgnored,
- },
- updateQuery: (oldData, {fetchMoreResult:{asset}}) => {
- return {
- ...oldData,
- asset: {
- ...oldData.asset,
- commentCount: asset.commentCount
- }
- };
- }
+ variables,
+
+ // Apollo requires this, even though we don't use it...
+ updateQuery: data => data,
});
};
@@ -118,14 +107,11 @@ class StreamContainer extends React.Component {
};
componentDidMount() {
- this.props.data.refetch();
+ if (this.props.previousTab) {
+ this.props.data.refetch();
+ }
this.countPoll = setInterval(() => {
- const {asset} = this.props.root;
- this.getCounts({
- asset_id: asset.id,
- limit: asset.comments.length,
- sort: 'REVERSE_CHRONOLOGICAL'
- });
+ this.getCounts(this.props.data.variables);
}, NEW_COMMENT_COUNT_POLL_INTERVAL);
}
@@ -139,13 +125,13 @@ class StreamContainer extends React.Component {
}
const LOAD_COMMENT_COUNTS_QUERY = gql`
- query LoadCommentCounts($asset_id: ID, $limit: Int = 5, $sort: SORT_ORDER) {
- asset(id: $asset_id) {
+ query LoadCommentCounts($assetUrl: String, $assetId: ID, $excludeIgnored: Boolean) {
+ asset(id: $assetId, url: $assetUrl) {
id
- commentCount
- comments(sort: $sort, limit: $limit) {
+ commentCount(excludeIgnored: $excludeIgnored)
+ comments(limit: 10) {
id
- replyCount
+ replyCount(excludeIgnored: $excludeIgnored)
}
}
}
@@ -236,6 +222,7 @@ const mapStateToProps = state => ({
assetId: state.stream.assetId,
assetUrl: state.stream.assetUrl,
activeTab: state.embed.activeTab,
+ previousTab: state.embed.previousTab,
});
const mapDispatchToProps = dispatch =>
diff --git a/client/coral-embed-stream/src/index.js b/client/coral-embed-stream/src/index.js
index f3f6075b6..2fd1e2731 100644
--- a/client/coral-embed-stream/src/index.js
+++ b/client/coral-embed-stream/src/index.js
@@ -3,6 +3,7 @@ import {render} from 'react-dom';
import {ApolloProvider} from 'react-apollo';
import {client} from 'coral-framework/services/client';
+import {checkLogin} from 'coral-framework/actions/auth';
import reducers from './reducers';
import localStore, {injectReducers} from 'coral-framework/services/store';
@@ -12,6 +13,11 @@ injectReducers(reducers);
const store = (window.opener && window.opener.coralStore) ? window.opener.coralStore : localStore;
+// Don't run this in the popup.
+if (store === localStore) {
+ store.dispatch(checkLogin());
+}
+
render(
diff --git a/client/coral-embed-stream/src/reducers/embed.js b/client/coral-embed-stream/src/reducers/embed.js
index e7fe5a533..0fd661543 100644
--- a/client/coral-embed-stream/src/reducers/embed.js
+++ b/client/coral-embed-stream/src/reducers/embed.js
@@ -2,6 +2,7 @@ import * as actions from '../constants/embed';
const initialState = {
activeTab: 'stream',
+ previousTab: '',
};
export default function stream(state = initialState, action) {
@@ -10,6 +11,7 @@ export default function stream(state = initialState, action) {
return {
...state,
activeTab: action.tab,
+ previousTab: state.activeTab,
};
default:
return state;
diff --git a/client/coral-embed-stream/style/default.css b/client/coral-embed-stream/style/default.css
index 087859e89..d1afed204 100644
--- a/client/coral-embed-stream/style/default.css
+++ b/client/coral-embed-stream/style/default.css
@@ -352,17 +352,6 @@ button.comment__action-button[disabled],
/* Flag Styles */
-.coral-plugin-flags-container {
- position: relative;
-}
-
-.coral-plugin-flags-popup span {
- min-width: 280px;
- bottom: 36px;
- position: absolute;
- right: 10px;
-}
-
.coral-plugin-flags-popup-form {
margin-bottom: 10px;
}
@@ -399,6 +388,7 @@ button.comment__action-button[disabled],
margin-top: 5px;
width: 75%;
font-size: 16px;
+ border: 1px solid #ccc;
}
/* Close comments */
diff --git a/client/coral-framework/actions/auth.js b/client/coral-framework/actions/auth.js
index e112b2b6c..d689aeb63 100644
--- a/client/coral-framework/actions/auth.js
+++ b/client/coral-framework/actions/auth.js
@@ -39,10 +39,21 @@ export const showSignInDialog = () => dispatch => {
'menubar=0,resizable=0,width=500,height=550,top=200,left=500'
);
- signInPopUp.onbeforeunload = () => {
- dispatch(checkLogin());
- fetchMe();
+ // Workaround odd behavior in older WebKit versions, where
+ // onunload is called twice. (Encountered in IOS 8.3)
+ let loaded = false;
+ signInPopUp.onload = () => {
+ loaded = true;
};
+
+ // Use `onunload` instead of `onbeforeunload` which is not supported in IOS Safari.
+ signInPopUp.onunload = () => {
+ if (loaded) {
+ dispatch(checkLogin());
+ fetchMe();
+ }
+ };
+
dispatch({type: actions.SHOW_SIGNIN_DIALOG});
};
export const hideSignInDialog = () => dispatch => {
@@ -177,7 +188,13 @@ export const fetchSignUp = (formData, redirectUri) => (dispatch) => {
dispatch(signUpSuccess(user));
})
.catch(error => {
- dispatch(signUpFailure(lang.t(`error.${error.message}`)));
+ let errorMessage = lang.t(`error.${error.message}`);
+
+ // if there is no translation defined, just show the error string
+ if (errorMessage === `error.${error.message}`) {
+ errorMessage = error.message;
+ }
+ dispatch(signUpFailure(errorMessage));
});
};
diff --git a/client/coral-framework/graphql/mutations/index.js b/client/coral-framework/graphql/mutations/index.js
index eb0b5386a..b1ea57ae1 100644
--- a/client/coral-framework/graphql/mutations/index.js
+++ b/client/coral-framework/graphql/mutations/index.js
@@ -57,7 +57,7 @@ export const postComment = graphql(POST_COMMENT, {
...oldData.asset,
comments: oldData.asset.comments.map((oldComment) => {
return oldComment.id === parent_id
- ? {...oldComment, replies: [...oldComment.replies, comment]}
+ ? {...oldComment, replies: [...oldComment.replies, comment], replyCount: oldComment.replyCount + 1}
: oldComment;
})
}
diff --git a/client/coral-framework/helpers/plugins.js b/client/coral-framework/helpers/plugins.js
index 87ac35975..20aee7abb 100644
--- a/client/coral-framework/helpers/plugins.js
+++ b/client/coral-framework/helpers/plugins.js
@@ -65,10 +65,10 @@ export function getSlotsFragments(slots) {
const fragments = getComponentFragments(components);
return {
spreads(key) {
- return fragments[key] && fragments[key].spreads;
+ return (fragments[key] && fragments[key].spreads) || '';
},
definitions(key) {
- return fragments[key] && fragments[key].definitions;
+ return (fragments[key] && fragments[key].definitions) || '';
},
};
}
diff --git a/client/coral-framework/reducers/auth.js b/client/coral-framework/reducers/auth.js
index 6e678cab9..83ea49ce5 100644
--- a/client/coral-framework/reducers/auth.js
+++ b/client/coral-framework/reducers/auth.js
@@ -8,6 +8,7 @@ const initialState = Map({
user: null,
showSignInDialog: false,
showCreateUsernameDialog: false,
+ checkedInitialLogin: false,
view: 'SIGNIN',
error: '',
passwordRequestSuccess: null,
@@ -71,10 +72,12 @@ export default function auth (state = initialState, action) {
.set('isLoading', true);
case actions.CHECK_LOGIN_FAILURE:
return state
+ .set('checkedInitialLogin', true)
.set('loggedIn', false)
.set('user', null);
case actions.CHECK_LOGIN_SUCCESS:
return state
+ .set('checkedInitialLogin', true)
.set('loggedIn', true)
.set('isAdmin', action.isAdmin)
.set('user', purge(action.user));
@@ -114,7 +117,11 @@ export default function auth (state = initialState, action) {
.set('isLoading', false)
.set('successSignUp', true);
case actions.LOGOUT_SUCCESS:
- return initialState;
+ return state
+ .set('user', null)
+ .set('isLoading', false)
+ .set('loggedIn', false)
+ .set('isAdmin', false);
case actions.INVALID_FORM:
return state
.set('error', action.error);
diff --git a/client/coral-plugin-flags/FlagButton.js b/client/coral-plugin-flags/FlagButton.js
index 16e616379..e5daf72c9 100644
--- a/client/coral-plugin-flags/FlagButton.js
+++ b/client/coral-plugin-flags/FlagButton.js
@@ -19,6 +19,12 @@ class FlagButton extends Component {
localDelete: false
}
+ componentDidUpdate () {
+ if (this.popup) { // this will be defined when the reporting popup is opened
+ this.popup.firstChild.style.top = `${this.flagButton.offsetTop - this.popup.firstChild.clientHeight - 15}px`;
+ }
+ }
+
// When the "report" button is clicked expand the menu
onReportClick = () => {
const {currentUser, deleteAction, flaggedByCurrentUser, flag} = this.props;
@@ -135,7 +141,10 @@ class FlagButton extends Component {
const popupMenu = getPopupMenu[this.state.step](this.state.itemType);
return
-