mirror of
https://github.com/wassname/talk.git
synced 2026-08-11 11:27:10 +08:00
331 lines
7.9 KiB
JavaScript
331 lines
7.9 KiB
JavaScript
import React from 'react';
|
|
import { compose, gql } from 'react-apollo';
|
|
import { connect } from 'react-redux';
|
|
import { bindActionCreators } from 'redux';
|
|
import get from 'lodash/get';
|
|
import branch from 'recompose/branch';
|
|
import renderComponent from 'recompose/renderComponent';
|
|
|
|
import { Spinner } from 'coral-ui';
|
|
import {
|
|
focusSignInDialog,
|
|
blurSignInDialog,
|
|
hideSignInDialog,
|
|
} from '../actions/login';
|
|
import { updateStatus } from 'coral-framework/actions/auth';
|
|
import {
|
|
getDefinitionName,
|
|
getSlotFragmentSpreads,
|
|
} from 'coral-framework/utils';
|
|
import { withQuery, withPopupAuthHandler } from 'coral-framework/hocs';
|
|
import Embed from '../components/Embed';
|
|
import Stream from '../tabs/stream/containers/Stream';
|
|
import AutomaticAssetClosure from './AutomaticAssetClosure';
|
|
import Configure from '../tabs/configure/containers/Configure';
|
|
import { notify } from 'coral-framework/actions/notification';
|
|
import t from 'coral-framework/services/i18n';
|
|
import PropTypes from 'prop-types';
|
|
import { setActiveTab } from '../actions/embed';
|
|
|
|
class EmbedContainer extends React.Component {
|
|
static contextTypes = {
|
|
pym: PropTypes.object,
|
|
};
|
|
|
|
subscriptions = [];
|
|
|
|
subscribeToUpdates(props = this.props) {
|
|
if (props.currentUser) {
|
|
const newSubscriptions = [
|
|
{
|
|
document: USER_BANNED_SUBSCRIPTION,
|
|
updateQuery: (
|
|
_,
|
|
{ subscriptionData: { data: { userBanned: { state } } } }
|
|
) => {
|
|
notify('info', t('your_account_has_been_banned'));
|
|
props.updateStatus(state.status);
|
|
},
|
|
},
|
|
{
|
|
document: USER_SUSPENDED_SUBSCRIPTION,
|
|
updateQuery: (
|
|
_,
|
|
{ subscriptionData: { data: { userSuspended: { state } } } }
|
|
) => {
|
|
notify('info', t('your_account_has_been_suspended'));
|
|
props.updateStatus(state.status);
|
|
},
|
|
},
|
|
{
|
|
document: USERNAME_REJECTED_SUBSCRIPTION,
|
|
updateQuery: (
|
|
_,
|
|
{ subscriptionData: { data: { usernameRejected: { state } } } }
|
|
) => {
|
|
notify('info', t('your_username_has_been_rejected'));
|
|
props.updateStatus(state.status);
|
|
},
|
|
},
|
|
];
|
|
|
|
this.subscriptions = newSubscriptions.map(s =>
|
|
props.data.subscribeToMore({
|
|
document: s.document,
|
|
variables: {
|
|
user_id: props.currentUser.id,
|
|
},
|
|
updateQuery: s.updateQuery,
|
|
})
|
|
);
|
|
}
|
|
}
|
|
|
|
unsubscribe() {
|
|
this.subscriptions.forEach(unsubscribe => unsubscribe());
|
|
this.subscriptions = [];
|
|
}
|
|
|
|
resubscribe(props) {
|
|
this.unsubscribe();
|
|
this.subscribeToUpdates(props);
|
|
}
|
|
|
|
componentDidMount() {
|
|
this.subscribeToUpdates();
|
|
}
|
|
|
|
componentWillUnmount() {
|
|
this.unsubscribe();
|
|
}
|
|
|
|
componentWillReceiveProps(nextProps) {
|
|
if (this.props.currentUser !== nextProps.currentUser) {
|
|
// Refetch after login/logout.
|
|
this.props.data.refetch();
|
|
this.resubscribe(nextProps);
|
|
}
|
|
}
|
|
|
|
componentDidUpdate(prevProps) {
|
|
if (
|
|
!get(prevProps, 'root.asset.comment') &&
|
|
get(this.props, 'root.asset.comment')
|
|
) {
|
|
// Scroll to a permalinked comment if one is in the URL once the page is done rendering.
|
|
setTimeout(
|
|
() =>
|
|
this.context.pym.scrollParentToChildEl('talk-embed-stream-container'),
|
|
0
|
|
);
|
|
}
|
|
}
|
|
|
|
render() {
|
|
if (!this.props.root.asset) {
|
|
return <Spinner />;
|
|
}
|
|
return (
|
|
<Embed
|
|
setActiveTab={this.props.setActiveTab}
|
|
currentUser={this.props.currentUser}
|
|
blurSignInDialog={this.props.blurSignInDialog}
|
|
focusSignInDialog={this.props.focusSignInDialog}
|
|
hideSignInDialog={this.props.hideSignInDialog}
|
|
router={this.props.router}
|
|
commentId={this.props.commentId}
|
|
root={this.props.root}
|
|
activeTab={this.props.activeTab}
|
|
data={this.props.data}
|
|
showSignInDialog={this.props.showSignInDialog}
|
|
signInDialogFocus={this.props.signInDialogFocus}
|
|
parentUrl={this.props.parentUrl}
|
|
/>
|
|
);
|
|
}
|
|
}
|
|
|
|
const USER_BANNED_SUBSCRIPTION = gql`
|
|
subscription UserBanned($user_id: ID!) {
|
|
userBanned(user_id: $user_id) {
|
|
id
|
|
state {
|
|
status {
|
|
username {
|
|
status
|
|
}
|
|
banned {
|
|
status
|
|
}
|
|
suspension {
|
|
until
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
const USER_SUSPENDED_SUBSCRIPTION = gql`
|
|
subscription UserSuspended($user_id: ID!) {
|
|
userSuspended(user_id: $user_id) {
|
|
id
|
|
state {
|
|
status {
|
|
username {
|
|
status
|
|
}
|
|
banned {
|
|
status
|
|
}
|
|
suspension {
|
|
until
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
const USERNAME_REJECTED_SUBSCRIPTION = gql`
|
|
subscription UsernameRejected($user_id: ID!) {
|
|
usernameRejected(user_id: $user_id) {
|
|
id
|
|
state {
|
|
status {
|
|
username {
|
|
status
|
|
}
|
|
banned {
|
|
status
|
|
}
|
|
suspension {
|
|
until
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`;
|
|
|
|
const slots = [
|
|
'embed',
|
|
'embedStreamTabs',
|
|
'embedStreamTabsPrepend',
|
|
'embedStreamTabPanes',
|
|
];
|
|
|
|
const EMBED_QUERY = gql`
|
|
query CoralEmbedStream_Embed(
|
|
$assetId: ID,
|
|
$assetUrl: String,
|
|
$commentId: ID!,
|
|
$hasComment: Boolean!,
|
|
$excludeIgnored: Boolean,
|
|
$sortBy: SORT_COMMENTS_BY!,
|
|
$sortOrder: SORT_ORDER!,
|
|
) {
|
|
me {
|
|
id
|
|
state {
|
|
status {
|
|
username {
|
|
status
|
|
}
|
|
banned {
|
|
status
|
|
}
|
|
suspension {
|
|
until
|
|
}
|
|
}
|
|
}
|
|
}
|
|
asset(id: $assetId, url: $assetUrl) {
|
|
...${getDefinitionName(Configure.fragments.asset)}
|
|
...${getDefinitionName(Stream.fragments.asset)}
|
|
...${getDefinitionName(AutomaticAssetClosure.fragments.asset)}
|
|
}
|
|
${getSlotFragmentSpreads(slots, 'root')}
|
|
...${getDefinitionName(Stream.fragments.root)}
|
|
...${getDefinitionName(Configure.fragments.root)}
|
|
}
|
|
${Stream.fragments.root}
|
|
${Stream.fragments.asset}
|
|
${Configure.fragments.root}
|
|
${Configure.fragments.asset}
|
|
${AutomaticAssetClosure.fragments.asset}
|
|
`;
|
|
|
|
export const withEmbedQuery = withQuery(EMBED_QUERY, {
|
|
options: ({
|
|
currentUser,
|
|
commentId,
|
|
assetId,
|
|
assetUrl,
|
|
sortBy,
|
|
sortOrder,
|
|
}) => ({
|
|
variables: {
|
|
assetId,
|
|
assetUrl,
|
|
commentId,
|
|
hasComment: commentId !== '',
|
|
excludeIgnored: Boolean(currentUser && currentUser.id),
|
|
sortBy,
|
|
sortOrder,
|
|
},
|
|
}),
|
|
});
|
|
|
|
EmbedContainer.propTypes = {
|
|
setActiveTab: PropTypes.func,
|
|
currentUser: PropTypes.object,
|
|
blurSignInDialog: PropTypes.func,
|
|
focusSignInDialog: PropTypes.func,
|
|
hideSignInDialog: PropTypes.func,
|
|
router: PropTypes.object,
|
|
commentId: PropTypes.string,
|
|
root: PropTypes.object,
|
|
activeTab: PropTypes.string,
|
|
parentUrl: PropTypes.string,
|
|
data: PropTypes.object,
|
|
showSignInDialog: PropTypes.bool,
|
|
signInDialogFocus: PropTypes.bool,
|
|
};
|
|
|
|
const mapStateToProps = state => ({
|
|
currentUser: state.auth.user,
|
|
checkedInitialLogin: state.auth.checkedInitialLogin,
|
|
commentId: state.stream.commentId,
|
|
assetId: state.stream.assetId,
|
|
assetUrl: state.stream.assetUrl,
|
|
activeTab: state.embed.activeTab,
|
|
config: state.config,
|
|
sortOrder: state.stream.sortOrder,
|
|
sortBy: state.stream.sortBy,
|
|
showSignInDialog: state.login.showSignInDialog,
|
|
signInDialogFocus: state.login.signInDialogFocus,
|
|
parentUrl: state.login.parentUrl,
|
|
});
|
|
|
|
const mapDispatchToProps = dispatch =>
|
|
bindActionCreators(
|
|
{
|
|
setActiveTab,
|
|
notify,
|
|
focusSignInDialog,
|
|
blurSignInDialog,
|
|
hideSignInDialog,
|
|
updateStatus,
|
|
},
|
|
dispatch
|
|
);
|
|
|
|
export default compose(
|
|
withPopupAuthHandler,
|
|
connect(mapStateToProps, mapDispatchToProps),
|
|
branch(props => !props.checkedInitialLogin, renderComponent(Spinner)),
|
|
withEmbedQuery
|
|
)(EmbedContainer);
|