mirror of
https://github.com/wassname/talk.git
synced 2026-08-17 11:27:52 +08:00
Merge branch 'master' into hackday-upvote-downvote-ama
This commit is contained in:
@@ -1,14 +1,13 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import Menu from './Menu';
|
||||
import styles from './AuthorName.css';
|
||||
import { ClickOutside } from 'plugin-api/beta/client/components';
|
||||
import cn from 'classnames';
|
||||
|
||||
export default ({
|
||||
data,
|
||||
root,
|
||||
asset,
|
||||
comment,
|
||||
const AuthorName = ({
|
||||
slotPassthrough,
|
||||
username,
|
||||
contentSlot,
|
||||
menuVisible,
|
||||
toggleMenu,
|
||||
@@ -21,18 +20,23 @@ export default ({
|
||||
className={cn(styles.button, 'talk-plugin-author-menu-button')}
|
||||
onClick={toggleMenu}
|
||||
>
|
||||
<span className={styles.name}>{comment.user.username}</span>
|
||||
<span className={styles.name}>{username}</span>
|
||||
</button>
|
||||
{menuVisible && (
|
||||
<Menu
|
||||
data={data}
|
||||
root={root}
|
||||
asset={asset}
|
||||
comment={comment}
|
||||
contentSlot={contentSlot}
|
||||
/>
|
||||
<Menu slotPassthrough={slotPassthrough} contentSlot={contentSlot} />
|
||||
)}
|
||||
</div>
|
||||
</ClickOutside>
|
||||
);
|
||||
};
|
||||
|
||||
AuthorName.propTypes = {
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
username: PropTypes.string.isRequired,
|
||||
menuVisible: PropTypes.bool.isRequired,
|
||||
toggleMenu: PropTypes.func.isRequired,
|
||||
hideMenu: PropTypes.func.isRequired,
|
||||
contentSlot: PropTypes.string,
|
||||
};
|
||||
|
||||
export default AuthorName;
|
||||
|
||||
@@ -1,17 +1,14 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Menu.css';
|
||||
import { Slot } from 'plugin-api/beta/client/components';
|
||||
import cn from 'classnames';
|
||||
|
||||
export default ({ data, root, asset, comment, contentSlot }) => {
|
||||
const Menu = ({ slotPassthrough, contentSlot }) => {
|
||||
if (contentSlot) {
|
||||
return (
|
||||
<div className={cn(styles.menu, 'talk-plugin-author-menu-popup')}>
|
||||
<Slot
|
||||
fill={contentSlot}
|
||||
data={data}
|
||||
queryData={{ asset, root, comment }}
|
||||
/>
|
||||
<Slot fill={contentSlot} passthrough={slotPassthrough} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -21,15 +18,20 @@ export default ({ data, root, asset, comment, contentSlot }) => {
|
||||
<Slot
|
||||
className={cn('talk-plugin-author-menu-infos')}
|
||||
fill={'authorMenuInfos'}
|
||||
data={data}
|
||||
queryData={{ asset, root, comment }}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
<Slot
|
||||
className={cn(styles.actions, 'talk-plugin-author-menu-actions')}
|
||||
fill={'authorMenuActions'}
|
||||
data={data}
|
||||
queryData={{ asset, root, comment }}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
Menu.propTypes = {
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
contentSlot: PropTypes.string,
|
||||
};
|
||||
|
||||
export default Menu;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { connect, withFragments } from 'plugin-api/beta/client/hocs';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import AuthorName from '../components/AuthorName';
|
||||
@@ -47,21 +48,39 @@ class AuthorNameContainer extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
root,
|
||||
asset,
|
||||
comment,
|
||||
contentSlot,
|
||||
showMenuForComment,
|
||||
} = this.props;
|
||||
|
||||
const slotPassthrough = { root, asset, comment };
|
||||
|
||||
return (
|
||||
<AuthorName
|
||||
data={this.props.data}
|
||||
root={this.props.root}
|
||||
asset={this.props.asset}
|
||||
comment={this.props.comment}
|
||||
contentSlot={this.props.contentSlot}
|
||||
menuVisible={this.props.showMenuForComment === this.props.comment.id}
|
||||
username={comment.user.username}
|
||||
contentSlot={contentSlot}
|
||||
menuVisible={showMenuForComment === comment.id}
|
||||
toggleMenu={this.toggleMenu}
|
||||
hideMenu={this.hideMenu}
|
||||
slotPassthrough={slotPassthrough}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
AuthorNameContainer.propTypes = {
|
||||
root: PropTypes.object.isRequired,
|
||||
asset: PropTypes.object.isRequired,
|
||||
comment: PropTypes.object.isRequired,
|
||||
contentSlot: PropTypes.string,
|
||||
showMenuForComment: PropTypes.string,
|
||||
openMenu: PropTypes.func.isRequired,
|
||||
closeMenu: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
const slots = ['authorMenuInfos', 'authorMenuActions'];
|
||||
|
||||
const mapStateToProps = ({ talkPluginAuthorMenu: state }) => ({
|
||||
|
||||
@@ -18,8 +18,8 @@ class Comment extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { comment, asset, root, data } = this.props;
|
||||
const queryData = { comment, asset, root };
|
||||
const { comment, asset, root } = this.props;
|
||||
const slotPassthrough = { comment, asset, root };
|
||||
return (
|
||||
<div className={cn(styles.root, `${pluginName}-comment`)}>
|
||||
<Slot
|
||||
@@ -27,8 +27,7 @@ class Comment extends React.Component {
|
||||
className={cn(styles.quote, `${pluginName}-comment-body`)}
|
||||
fill="commentContent"
|
||||
defaultComponent={CommentContent}
|
||||
data={data}
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
|
||||
<div className={cn(`${pluginName}-comment-username-box`)}>
|
||||
@@ -36,8 +35,7 @@ class Comment extends React.Component {
|
||||
className={cn(styles.username, `${pluginName}-comment-username`)}
|
||||
fill="commentAuthorName"
|
||||
defaultComponent={CommentAuthorName}
|
||||
queryData={queryData}
|
||||
data={data}
|
||||
passthrough={slotPassthrough}
|
||||
inline
|
||||
/>
|
||||
|
||||
@@ -45,9 +43,7 @@ class Comment extends React.Component {
|
||||
fill="commentTimestamp"
|
||||
defaultComponent={CommentTimestamp}
|
||||
className={cn(styles.timestamp, `${pluginName}-comment-timestamp`)}
|
||||
created_at={comment.created_at}
|
||||
data={data}
|
||||
queryData={queryData}
|
||||
passthrough={{ created_at: comment.created_at, ...slotPassthrough }}
|
||||
inline
|
||||
/>
|
||||
</div>
|
||||
@@ -62,19 +58,11 @@ class Comment extends React.Component {
|
||||
>
|
||||
<Slot
|
||||
fill="commentReactions"
|
||||
root={root}
|
||||
data={data}
|
||||
comment={comment}
|
||||
asset={asset}
|
||||
passthrough={slotPassthrough}
|
||||
inline
|
||||
/>
|
||||
|
||||
<FeaturedButton
|
||||
root={root}
|
||||
data={data}
|
||||
comment={comment}
|
||||
asset={asset}
|
||||
/>
|
||||
<FeaturedButton root={root} comment={comment} asset={asset} />
|
||||
</div>
|
||||
<div
|
||||
className={cn(
|
||||
|
||||
@@ -22,7 +22,6 @@ class TabPane extends React.Component {
|
||||
render() {
|
||||
const {
|
||||
root,
|
||||
data,
|
||||
asset: { featuredComments, ...asset },
|
||||
viewComment,
|
||||
} = this.props;
|
||||
@@ -32,7 +31,6 @@ class TabPane extends React.Component {
|
||||
<Comment
|
||||
key={comment.id}
|
||||
root={root}
|
||||
data={data}
|
||||
comment={comment}
|
||||
asset={asset}
|
||||
viewComment={viewComment}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React from 'react';
|
||||
import { gql } from 'react-apollo';
|
||||
import { subscriptionFields } from 'coral-admin/src/routes/Moderation/graphql';
|
||||
import { compose, withSubscribeToMore } from 'plugin-api/beta/client/hocs';
|
||||
|
||||
class ModIndicatorSubscription extends React.Component {
|
||||
subscriptions = null;
|
||||
@@ -27,7 +28,7 @@ class ModIndicatorSubscription extends React.Component {
|
||||
},
|
||||
];
|
||||
this.subscriptions = configs.map(config =>
|
||||
this.props.data.subscribeToMore(config)
|
||||
this.props.subscribeToMore(config)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -60,4 +61,4 @@ const COMMENT_UNFEATURED_SUBSCRIPTION = gql`
|
||||
}
|
||||
`;
|
||||
|
||||
export default ModIndicatorSubscription;
|
||||
export default compose(withSubscribeToMore)(ModIndicatorSubscription);
|
||||
|
||||
@@ -6,6 +6,11 @@ import { getDefinitionName } from 'coral-framework/utils';
|
||||
import truncate from 'lodash/truncate';
|
||||
import t from 'coral-framework/services/i18n';
|
||||
import { subscriptionFields } from 'coral-admin/src/routes/Moderation/graphql';
|
||||
import {
|
||||
compose,
|
||||
withSubscribeToMore,
|
||||
withVariables,
|
||||
} from 'plugin-api/beta/client/hocs';
|
||||
|
||||
function prepareNotificationText(text) {
|
||||
return truncate(text, { length: 50 }).replace('\n', ' ');
|
||||
@@ -19,7 +24,7 @@ class ModSubscription extends React.Component {
|
||||
{
|
||||
document: COMMENT_FEATURED_SUBSCRIPTION,
|
||||
variables: {
|
||||
assetId: this.props.data.variables.asset_id,
|
||||
assetId: this.props.variables.asset_id,
|
||||
},
|
||||
updateQuery: (
|
||||
prev,
|
||||
@@ -39,7 +44,7 @@ class ModSubscription extends React.Component {
|
||||
{
|
||||
document: COMMENT_UNFEATURED_SUBSCRIPTION,
|
||||
variables: {
|
||||
assetId: this.props.data.variables.asset_id,
|
||||
assetId: this.props.variables.asset_id,
|
||||
},
|
||||
updateQuery: (
|
||||
prev,
|
||||
@@ -62,7 +67,7 @@ class ModSubscription extends React.Component {
|
||||
},
|
||||
];
|
||||
this.subscriptions = configs.map(config =>
|
||||
this.props.data.subscribeToMore(config)
|
||||
this.props.subscribeToMore(config)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -111,4 +116,8 @@ const mapStateToProps = state => ({
|
||||
user: state.auth.user,
|
||||
});
|
||||
|
||||
export default connect(mapStateToProps, null)(ModSubscription);
|
||||
export default compose(
|
||||
connect(mapStateToProps, null),
|
||||
withVariables,
|
||||
withSubscribeToMore
|
||||
)(ModSubscription);
|
||||
|
||||
@@ -2,7 +2,12 @@ import React from 'react';
|
||||
import { bindActionCreators } from 'redux';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import TabPane from '../components/TabPane';
|
||||
import { withFragments, connect } from 'plugin-api/beta/client/hocs';
|
||||
import {
|
||||
withFragments,
|
||||
connect,
|
||||
withFetchMore,
|
||||
withVariables,
|
||||
} from 'plugin-api/beta/client/hocs';
|
||||
import Comment from '../containers/Comment';
|
||||
import { viewComment } from 'coral-embed-stream/src/actions/stream';
|
||||
import {
|
||||
@@ -13,15 +18,15 @@ import update from 'immutability-helper';
|
||||
|
||||
class TabPaneContainer extends React.Component {
|
||||
loadMore = () => {
|
||||
return this.props.data.fetchMore({
|
||||
return this.props.fetchMore({
|
||||
query: LOAD_MORE_QUERY,
|
||||
variables: {
|
||||
limit: 5,
|
||||
cursor: this.props.asset.featuredComments.endCursor,
|
||||
asset_id: this.props.asset.id,
|
||||
sortOrder: this.props.data.variables.sortOrder,
|
||||
sortBy: this.props.data.variables.sortBy,
|
||||
excludeIgnored: this.props.data.variables.excludeIgnored,
|
||||
sortOrder: this.props.variables.sortOrder,
|
||||
sortBy: this.props.variables.sortBy,
|
||||
excludeIgnored: this.props.variables.excludeIgnored,
|
||||
},
|
||||
updateQuery: (previous, { fetchMoreResult: { comments } }) => {
|
||||
const updated = update(previous, {
|
||||
@@ -86,6 +91,8 @@ const mapDispatchToProps = dispatch =>
|
||||
|
||||
const enhance = compose(
|
||||
connect(null, mapDispatchToProps),
|
||||
withFetchMore,
|
||||
withVariables,
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkFeaturedComments_TabPane_root on RootQuery {
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
|
||||
class FlagDetails extends Component {
|
||||
render() {
|
||||
const { comment: { actions }, more, data, root, comment } = this.props;
|
||||
const { comment: { actions }, more, root, comment } = this.props;
|
||||
|
||||
const flagActions =
|
||||
actions && actions.filter(a => a.__typename === 'FlagAction');
|
||||
@@ -26,7 +26,7 @@ class FlagDetails extends Component {
|
||||
}, {});
|
||||
|
||||
const reasons = Object.keys(summaries);
|
||||
const queryData = {
|
||||
const slotPassthrough = {
|
||||
root,
|
||||
comment,
|
||||
};
|
||||
@@ -52,12 +52,11 @@ class FlagDetails extends Component {
|
||||
{more && (
|
||||
<IfSlotIsNotEmpty
|
||||
slot="adminCommentMoreFlagDetails"
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
>
|
||||
<Slot
|
||||
fill="adminCommentMoreFlagDetails"
|
||||
data={data}
|
||||
queryData={queryData}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
</IfSlotIsNotEmpty>
|
||||
)}
|
||||
@@ -68,7 +67,6 @@ class FlagDetails extends Component {
|
||||
|
||||
FlagDetails.propTypes = {
|
||||
more: PropTypes.bool,
|
||||
data: PropTypes.object,
|
||||
root: PropTypes.object,
|
||||
comment: PropTypes.shape({
|
||||
actions: PropTypes.arrayOf(
|
||||
|
||||
@@ -24,7 +24,7 @@ export default {
|
||||
createComment: {
|
||||
comment: {
|
||||
user: {
|
||||
created_at: new Date(),
|
||||
created_at: new Date().toISOString(),
|
||||
__typename: 'User',
|
||||
},
|
||||
__typename: 'Comment',
|
||||
|
||||
@@ -16,12 +16,16 @@ export default class ModerationActions extends React.Component {
|
||||
comment,
|
||||
root,
|
||||
asset,
|
||||
data,
|
||||
menuVisible,
|
||||
toogleMenu,
|
||||
hideMenu,
|
||||
} = this.props;
|
||||
|
||||
const slotPassthrough = {
|
||||
comment,
|
||||
asset,
|
||||
};
|
||||
|
||||
return (
|
||||
<ClickOutside onClickOutside={hideMenu}>
|
||||
<div
|
||||
@@ -45,8 +49,7 @@ export default class ModerationActions extends React.Component {
|
||||
<Slot
|
||||
className="talk-plugin-modetarion-actions-slot"
|
||||
fill="moderationActions"
|
||||
queryData={{ comment, asset }}
|
||||
data={data}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
<ApproveCommentAction comment={comment} hideMenu={hideMenu} />
|
||||
<RejectCommentAction comment={comment} hideMenu={hideMenu} />
|
||||
@@ -67,7 +70,6 @@ ModerationActions.propTypes = {
|
||||
comment: PropTypes.object,
|
||||
root: PropTypes.object,
|
||||
asset: PropTypes.object,
|
||||
data: PropTypes.object,
|
||||
menuVisible: PropTypes.bool,
|
||||
toogleMenu: PropTypes.func,
|
||||
hideMenu: PropTypes.func,
|
||||
|
||||
@@ -42,7 +42,6 @@ class ModerationActionsContainer extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<ModerationActions
|
||||
data={this.props.data}
|
||||
root={this.props.root}
|
||||
asset={this.props.asset}
|
||||
comment={this.props.comment}
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import Toggle from 'talk-plugin-notifications/client/components/Toggle';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { withFragments } from 'plugin-api/beta/client/hocs';
|
||||
|
||||
class ToggleContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
props.setTurnOffInputFragment({ onFeatured: false });
|
||||
|
||||
if (this.getOnFeaturedSetting()) {
|
||||
props.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const prevSetting = this.getOnFeaturedSetting(this.props);
|
||||
const nextSetting = this.getOnFeaturedSetting(nextProps);
|
||||
if (prevSetting && !nextSetting) {
|
||||
nextProps.indicateOff();
|
||||
} else if (!prevSetting && nextSetting) {
|
||||
nextProps.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
getOnFeaturedSetting = (props = this.props) =>
|
||||
props.root.me.notificationSettings.onFeatured;
|
||||
|
||||
toggle = () => {
|
||||
this.props.updateNotificationSettings({
|
||||
onFeatured: !this.getOnFeaturedSetting(),
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Toggle
|
||||
checked={this.getOnFeaturedSetting()}
|
||||
onChange={this.toggle}
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
{t('talk-plugin-notifications-category-featured.toggle_description')}
|
||||
</Toggle>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ToggleContainer.propTypes = {
|
||||
data: PropTypes.object,
|
||||
root: PropTypes.object,
|
||||
indicateOn: PropTypes.func.isRequired,
|
||||
indicateOff: PropTypes.func.isRequired,
|
||||
setTurnOffInputFragment: PropTypes.func.isRequired,
|
||||
updateNotificationSettings: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkNotificationsCategoryFeatured_Toggle_root on RootQuery {
|
||||
me {
|
||||
notificationSettings {
|
||||
onFeatured
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
})
|
||||
);
|
||||
|
||||
export default enhance(ToggleContainer);
|
||||
@@ -1,33 +0,0 @@
|
||||
import { gql } from 'react-apollo';
|
||||
|
||||
export default {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
}) => ({
|
||||
update: proxy => {
|
||||
if (input.onFeatured === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fragment = gql`
|
||||
fragment TalkNotificationsCategoryFeatured_User_Fragment on User {
|
||||
notificationSettings {
|
||||
onFeatured
|
||||
}
|
||||
}
|
||||
`;
|
||||
const fragmentId = `User_${id}`;
|
||||
const data = {
|
||||
__typename: 'User',
|
||||
notificationSettings: {
|
||||
__typename: 'NotificationSettings',
|
||||
onFeatured: input.onFeatured,
|
||||
},
|
||||
};
|
||||
proxy.writeFragment({ fragment, id: fragmentId, data });
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
@@ -1,11 +1,14 @@
|
||||
import Toggle from './containers/Toggle';
|
||||
import translations from './translations.yml';
|
||||
import graphql from './graphql';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { createSettingsToggle } from 'talk-plugin-notifications/client/api/factories';
|
||||
|
||||
const SettingsToggle = createSettingsToggle('onFeatured', () =>
|
||||
t('talk-plugin-notifications-category-featured.toggle_description')
|
||||
);
|
||||
|
||||
export default {
|
||||
slots: {
|
||||
notificationSettings: [Toggle],
|
||||
notificationSettings: [SettingsToggle],
|
||||
},
|
||||
translations,
|
||||
...graphql,
|
||||
};
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import Toggle from 'talk-plugin-notifications/client/components/Toggle';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { withFragments } from 'plugin-api/beta/client/hocs';
|
||||
|
||||
class ToggleContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
props.setTurnOffInputFragment({ onReply: false });
|
||||
|
||||
if (this.getOnReplySetting()) {
|
||||
props.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const prevSetting = this.getOnReplySetting(this.props);
|
||||
const nextSetting = this.getOnReplySetting(nextProps);
|
||||
if (prevSetting && !nextSetting) {
|
||||
nextProps.indicateOff();
|
||||
} else if (!prevSetting && nextSetting) {
|
||||
nextProps.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
getOnReplySetting = (props = this.props) =>
|
||||
props.root.me.notificationSettings.onReply;
|
||||
|
||||
toggle = () => {
|
||||
this.props.updateNotificationSettings({
|
||||
onReply: !this.getOnReplySetting(),
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Toggle
|
||||
checked={this.getOnReplySetting()}
|
||||
onChange={this.toggle}
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
{t('talk-plugin-notifications-category-reply.toggle_description')}
|
||||
</Toggle>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ToggleContainer.propTypes = {
|
||||
data: PropTypes.object,
|
||||
root: PropTypes.object,
|
||||
indicateOn: PropTypes.func.isRequired,
|
||||
indicateOff: PropTypes.func.isRequired,
|
||||
setTurnOffInputFragment: PropTypes.func.isRequired,
|
||||
updateNotificationSettings: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkNotificationsCategoryReply_Toggle_root on RootQuery {
|
||||
me {
|
||||
notificationSettings {
|
||||
onReply
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
})
|
||||
);
|
||||
|
||||
export default enhance(ToggleContainer);
|
||||
@@ -1,33 +0,0 @@
|
||||
import { gql } from 'react-apollo';
|
||||
|
||||
export default {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
}) => ({
|
||||
update: proxy => {
|
||||
if (input.onReply === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fragment = gql`
|
||||
fragment TalkNotificationsCategoryReply_User_Fragment on User {
|
||||
notificationSettings {
|
||||
onReply
|
||||
}
|
||||
}
|
||||
`;
|
||||
const fragmentId = `User_${id}`;
|
||||
const data = {
|
||||
__typename: 'User',
|
||||
notificationSettings: {
|
||||
__typename: 'NotificationSettings',
|
||||
onReply: input.onReply,
|
||||
},
|
||||
};
|
||||
proxy.writeFragment({ fragment, id: fragmentId, data });
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
@@ -1,11 +1,14 @@
|
||||
import Toggle from './containers/Toggle';
|
||||
import translations from './translations.yml';
|
||||
import graphql from './graphql';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { createSettingsToggle } from 'talk-plugin-notifications/client/api/factories';
|
||||
|
||||
const SettingsToggle = createSettingsToggle('onReply', () =>
|
||||
t('talk-plugin-notifications-category-reply.toggle_description')
|
||||
);
|
||||
|
||||
export default {
|
||||
slots: {
|
||||
notificationSettings: [Toggle],
|
||||
notificationSettings: [SettingsToggle],
|
||||
},
|
||||
translations,
|
||||
...graphql,
|
||||
};
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import Toggle from 'talk-plugin-notifications/client/components/Toggle';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { withFragments } from 'plugin-api/beta/client/hocs';
|
||||
|
||||
class ToggleContainer extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
props.setTurnOffInputFragment({ onStaffReply: false });
|
||||
|
||||
if (this.getOnReplySetting()) {
|
||||
props.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const prevSetting = this.getOnReplySetting(this.props);
|
||||
const nextSetting = this.getOnReplySetting(nextProps);
|
||||
if (prevSetting && !nextSetting) {
|
||||
nextProps.indicateOff();
|
||||
} else if (!prevSetting && nextSetting) {
|
||||
nextProps.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
getOnReplySetting = (props = this.props) =>
|
||||
props.root.me.notificationSettings.onStaffReply;
|
||||
|
||||
toggle = () => {
|
||||
this.props.updateNotificationSettings({
|
||||
onStaffReply: !this.getOnReplySetting(),
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<Toggle
|
||||
checked={this.getOnReplySetting()}
|
||||
onChange={this.toggle}
|
||||
disabled={this.props.disabled}
|
||||
>
|
||||
{t('talk-plugin-notifications-category-staff.toggle_description')}
|
||||
</Toggle>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ToggleContainer.propTypes = {
|
||||
data: PropTypes.object,
|
||||
root: PropTypes.object,
|
||||
indicateOn: PropTypes.func.isRequired,
|
||||
indicateOff: PropTypes.func.isRequired,
|
||||
setTurnOffInputFragment: PropTypes.func.isRequired,
|
||||
updateNotificationSettings: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkNotificationsCategoryStaffReply_User_Fragment on RootQuery {
|
||||
me {
|
||||
notificationSettings {
|
||||
onStaffReply
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
})
|
||||
);
|
||||
|
||||
export default enhance(ToggleContainer);
|
||||
@@ -1,33 +0,0 @@
|
||||
import { gql } from 'react-apollo';
|
||||
|
||||
export default {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
}) => ({
|
||||
update: proxy => {
|
||||
if (input.onStaffReply === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fragment = gql`
|
||||
fragment TalkNotificationsCategoryStaffReply_User_Fragment on User {
|
||||
notificationSettings {
|
||||
onStaffReply
|
||||
}
|
||||
}
|
||||
`;
|
||||
const fragmentId = `User_${id}`;
|
||||
const data = {
|
||||
__typename: 'User',
|
||||
notificationSettings: {
|
||||
__typename: 'NotificationSettings',
|
||||
onStaffReply: input.onStaffReply,
|
||||
},
|
||||
};
|
||||
proxy.writeFragment({ fragment, id: fragmentId, data });
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
@@ -1,11 +1,14 @@
|
||||
import Toggle from './containers/Toggle';
|
||||
import translations from './translations.yml';
|
||||
import graphql from './graphql';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
import { createSettingsToggle } from 'talk-plugin-notifications/client/api/factories';
|
||||
|
||||
const SettingsToggle = createSettingsToggle('onStaffReply', () =>
|
||||
t('talk-plugin-notifications-category-staff.toggle_description')
|
||||
);
|
||||
|
||||
export default {
|
||||
slots: {
|
||||
notificationSettings: [Toggle],
|
||||
notificationSettings: [SettingsToggle],
|
||||
},
|
||||
translations,
|
||||
...graphql,
|
||||
};
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
.title {
|
||||
display: inline-block;
|
||||
width: 100%;
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
|
||||
&.disabled {
|
||||
color: #e5e5e5;
|
||||
cursor: default;
|
||||
}
|
||||
}
|
||||
|
||||
.toggle {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.checkBox {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Checkbox } from 'plugin-api/beta/client/components/ui';
|
||||
import styles from './Toggle.css';
|
||||
import uuid from 'uuid/v4';
|
||||
import cn from 'classnames';
|
||||
|
||||
class Toggle extends React.Component {
|
||||
id = uuid();
|
||||
|
||||
render() {
|
||||
const { checked, onChange, children, disabled } = this.props;
|
||||
return (
|
||||
<div className={styles.toggle}>
|
||||
<label
|
||||
htmlFor={this.id}
|
||||
className={cn(styles.title, { [styles.disabled]: disabled })}
|
||||
>
|
||||
{children}
|
||||
</label>
|
||||
<div className={styles.checkBox}>
|
||||
<Checkbox
|
||||
checked={checked}
|
||||
onChange={onChange}
|
||||
id={this.id}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Toggle.propTypes = {
|
||||
disabled: PropTypes.bool,
|
||||
checked: PropTypes.bool,
|
||||
onChange: PropTypes.func,
|
||||
children: PropTypes.node,
|
||||
};
|
||||
|
||||
export default Toggle;
|
||||
@@ -0,0 +1 @@
|
||||
export { default as Toggle } from './Toggle';
|
||||
@@ -0,0 +1,22 @@
|
||||
import React from 'react';
|
||||
import Toggle from '../components/Toggle';
|
||||
import withSettingsToggle from '../hocs/withSettingsToggle';
|
||||
|
||||
/**
|
||||
* createSettingsToggle will add a boolean setting with the
|
||||
* name `settingsName` to notification settings and return
|
||||
* a full Toggle Component.
|
||||
*
|
||||
* You must provide a `label` either as a string or as a callback.
|
||||
* E.g. to provide translations you could do:
|
||||
*
|
||||
* `const SettingsToggle = createSettingsToggle('onReply', () => t('translate'));`
|
||||
*/
|
||||
const createSettingsToggle = (settingsName, label) => {
|
||||
const SettingsToggle = props => (
|
||||
<Toggle {...props}>{typeof label === 'function' ? label() : label}</Toggle>
|
||||
);
|
||||
return withSettingsToggle(settingsName)(SettingsToggle);
|
||||
};
|
||||
|
||||
export default createSettingsToggle;
|
||||
@@ -0,0 +1 @@
|
||||
export { default as createSettingsToggle } from './createSettingsToggle';
|
||||
@@ -0,0 +1 @@
|
||||
export { default as withSettingsToggle } from './withSettingsToggle';
|
||||
@@ -0,0 +1,121 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import {
|
||||
withFragments,
|
||||
withGraphQLExtension,
|
||||
} from 'plugin-api/beta/client/hocs';
|
||||
|
||||
const createHOC = settingsName => WrappedComponent => {
|
||||
class WithSettingsToggle extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
props.setTurnOffInputFragment({ [settingsName]: false });
|
||||
|
||||
if (this.isChecked()) {
|
||||
props.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
const prevSetting = this.isChecked(this.props);
|
||||
const nextSetting = this.isChecked(nextProps);
|
||||
if (prevSetting && !nextSetting) {
|
||||
nextProps.indicateOff();
|
||||
} else if (!prevSetting && nextSetting) {
|
||||
nextProps.indicateOn();
|
||||
}
|
||||
}
|
||||
|
||||
isChecked = (props = this.props) =>
|
||||
props.root.me.notificationSettings[settingsName];
|
||||
|
||||
toggle = () => {
|
||||
this.props.updateNotificationSettings({
|
||||
[settingsName]: !this.isChecked(),
|
||||
});
|
||||
};
|
||||
|
||||
render() {
|
||||
return (
|
||||
<WrappedComponent
|
||||
checked={this.isChecked()}
|
||||
onChange={this.toggle}
|
||||
disabled={this.props.disabled}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
WithSettingsToggle.propTypes = {
|
||||
root: PropTypes.object,
|
||||
indicateOn: PropTypes.func.isRequired,
|
||||
indicateOff: PropTypes.func.isRequired,
|
||||
setTurnOffInputFragment: PropTypes.func.isRequired,
|
||||
updateNotificationSettings: PropTypes.func.isRequired,
|
||||
disabled: PropTypes.bool.isRequired,
|
||||
};
|
||||
|
||||
return WithSettingsToggle;
|
||||
};
|
||||
|
||||
/**
|
||||
* withSettingsToggle will add a boolean setting with the
|
||||
* name `settingsName` to notification settings and provide
|
||||
* the folliwng props:
|
||||
*
|
||||
* `checked: boolean` Whether setting is on or off
|
||||
* `onChange: () => void` Calling this will toggle the setting
|
||||
* `disabled: boolean` Whether setting is disabled
|
||||
*/
|
||||
const withSettingsToggle = settingsName => {
|
||||
const extension = {
|
||||
mutations: {
|
||||
UpdateNotificationSettings: ({
|
||||
variables: { input },
|
||||
state: { auth: { user: { id } } },
|
||||
}) => ({
|
||||
update: proxy => {
|
||||
if (input[settingsName] === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fragment = gql`
|
||||
fragment TalkNotifications_Toggle_${settingsName}_Fragment on User {
|
||||
notificationSettings {
|
||||
${settingsName}
|
||||
}
|
||||
}
|
||||
`;
|
||||
const fragmentId = `User_${id}`;
|
||||
const data = {
|
||||
__typename: 'User',
|
||||
notificationSettings: {
|
||||
__typename: 'NotificationSettings',
|
||||
[settingsName]: input[settingsName],
|
||||
},
|
||||
};
|
||||
proxy.writeFragment({ fragment, id: fragmentId, data });
|
||||
},
|
||||
}),
|
||||
},
|
||||
};
|
||||
|
||||
return compose(
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkNotifications_Toggle_${settingsName}_root on RootQuery {
|
||||
me {
|
||||
notificationSettings {
|
||||
${settingsName}
|
||||
}
|
||||
}
|
||||
}
|
||||
`,
|
||||
}),
|
||||
withGraphQLExtension(extension),
|
||||
createHOC(settingsName)
|
||||
);
|
||||
};
|
||||
|
||||
export default withSettingsToggle;
|
||||
@@ -37,15 +37,18 @@ class Settings extends React.Component {
|
||||
onChangeDigestFrequency,
|
||||
} = this.props;
|
||||
|
||||
const slotProps = {
|
||||
queryData: { root },
|
||||
setTurnOffInputFragment: setTurnOffInputFragment,
|
||||
updateNotificationSettings: updateNotificationSettings,
|
||||
const slotPassthrough = {
|
||||
root,
|
||||
setTurnOffInputFragment,
|
||||
updateNotificationSettings,
|
||||
disabled: needEmailVerification,
|
||||
};
|
||||
|
||||
return (
|
||||
<IfSlotIsNotEmpty slot="notificationSettings" {...slotProps}>
|
||||
<IfSlotIsNotEmpty
|
||||
slot="notificationSettings"
|
||||
passthrough={slotPassthrough}
|
||||
>
|
||||
<div className={styles.root}>
|
||||
<h3>{t('talk-plugin-notifications.settings_title')}</h3>
|
||||
<div className={styles.bannerContainer}>
|
||||
@@ -63,7 +66,7 @@ class Settings extends React.Component {
|
||||
className={styles.notifcationSettingsSlot}
|
||||
fill="notificationSettings"
|
||||
childFactory={this.childFactory}
|
||||
{...slotProps}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
</div>
|
||||
{digestFrequencyValues.length > 1 && (
|
||||
|
||||
@@ -50,7 +50,6 @@ class SettingsContainer extends React.Component {
|
||||
render() {
|
||||
return (
|
||||
<Settings
|
||||
data={this.props.data}
|
||||
root={this.props.root}
|
||||
indicateOn={this.indicateOn}
|
||||
indicateOff={this.indicateOff}
|
||||
@@ -72,7 +71,6 @@ class SettingsContainer extends React.Component {
|
||||
}
|
||||
|
||||
SettingsContainer.propTypes = {
|
||||
data: PropTypes.object,
|
||||
root: PropTypes.object,
|
||||
updateNotificationSettings: PropTypes.func.isRequired,
|
||||
digestFrequencyValues: PropTypes.array.isRequired,
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
{
|
||||
"extends": "@coralproject/eslint-config-talk/client"
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
import React from 'react';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
|
||||
const Tab = () => {
|
||||
return <span>{t('talk-plugin-profile-settings.tab')}</span>;
|
||||
};
|
||||
|
||||
export default Tab;
|
||||
@@ -1,21 +0,0 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import { Slot } from 'plugin-api/beta/client/components';
|
||||
|
||||
class TabPane extends React.Component {
|
||||
render() {
|
||||
const { data, root } = this.props;
|
||||
return (
|
||||
<div>
|
||||
<Slot fill="profileSettings" data={data} queryData={{ root }} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
TabPane.propTypes = {
|
||||
data: PropTypes.object,
|
||||
root: PropTypes.object,
|
||||
};
|
||||
|
||||
export default TabPane;
|
||||
@@ -1,26 +0,0 @@
|
||||
import React from 'react';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import TabPane from '../components/TabPane';
|
||||
import { withFragments } from 'plugin-api/beta/client/hocs';
|
||||
import { getSlotFragmentSpreads } from 'plugin-api/beta/client/utils';
|
||||
|
||||
const slots = ['profileSettings'];
|
||||
|
||||
class TabPaneContainer extends React.Component {
|
||||
render() {
|
||||
return <TabPane {...this.props} />;
|
||||
}
|
||||
}
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
root: gql`
|
||||
fragment TalkProfileSettings_TabPane_root on RootQuery {
|
||||
__typename
|
||||
${getSlotFragmentSpreads(slots, 'root')}
|
||||
}
|
||||
`,
|
||||
})
|
||||
);
|
||||
|
||||
export default enhance(TabPaneContainer);
|
||||
@@ -1,11 +0,0 @@
|
||||
import Tab from './components/Tab';
|
||||
import TabPane from './containers/TabPane';
|
||||
import translations from './translations.yml';
|
||||
|
||||
export default {
|
||||
slots: {
|
||||
profileTabs: [Tab],
|
||||
profileTabPanes: [TabPane],
|
||||
},
|
||||
translations,
|
||||
};
|
||||
@@ -1,30 +0,0 @@
|
||||
ar:
|
||||
talk-plugin-profile-settings:
|
||||
tab: إعدادات
|
||||
en:
|
||||
talk-plugin-profile-settings:
|
||||
tab: Settings
|
||||
de:
|
||||
talk-plugin-profile-settings:
|
||||
tab: Einstellungen
|
||||
es:
|
||||
talk-plugin-profile-settings:
|
||||
tab: Configuración
|
||||
fr:
|
||||
talk-plugin-profile-settings:
|
||||
tab: Paramètres
|
||||
nl_NL:
|
||||
talk-plugin-profile-settings:
|
||||
tab: Instellingen
|
||||
da:
|
||||
talk-plugin-profile-settings:
|
||||
tab: Indstillinger
|
||||
pt_PR:
|
||||
talk-plugin-profile-settings:
|
||||
tab: Configurações
|
||||
zh_TW:
|
||||
talk-plugin-profile-settings:
|
||||
tab: 設置
|
||||
zh_CN:
|
||||
talk-plugin-profile-settings:
|
||||
tab: 设置
|
||||
@@ -1 +0,0 @@
|
||||
module.exports = {};
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import styles from './Category.css';
|
||||
import { Slot } from 'plugin-api/beta/client/components';
|
||||
|
||||
@@ -8,7 +9,7 @@ const childFactory = child => (
|
||||
</li>
|
||||
);
|
||||
|
||||
const ViewingOptions = ({ slot, title, data, asset, root }) => {
|
||||
const Category = ({ slot, title, slotPassthrough }) => {
|
||||
return (
|
||||
<div className={styles.root}>
|
||||
<div className={styles.title}>{title}</div>
|
||||
@@ -17,11 +18,16 @@ const ViewingOptions = ({ slot, title, data, asset, root }) => {
|
||||
childFactory={childFactory}
|
||||
className={styles.list}
|
||||
component={'ul'}
|
||||
data={data}
|
||||
queryData={{ asset, root }}
|
||||
passthrough={slotPassthrough}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default ViewingOptions;
|
||||
Category.propTypes = {
|
||||
slot: PropTypes.string.isRequired,
|
||||
title: PropTypes.string.isRequired,
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default Category;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import styles from './Menu.css';
|
||||
import { capitalize } from 'plugin-api/beta/client/utils';
|
||||
@@ -13,16 +14,19 @@ class Menu extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { slotPassthrough } = this.props;
|
||||
return (
|
||||
<div className={cn([styles.menu, 'talk-plugin-viewing-options-menu'])}>
|
||||
{Object.keys(this.categories).map(category => (
|
||||
<IfSlotIsNotEmpty
|
||||
slot={`viewingOptions${capitalize(category)}`}
|
||||
key={category}
|
||||
passthrough={slotPassthrough}
|
||||
>
|
||||
<Category
|
||||
slot={`viewingOptions${capitalize(category)}`}
|
||||
title={this.categories[category]}
|
||||
slotPassthrough={slotPassthrough}
|
||||
/>
|
||||
</IfSlotIsNotEmpty>
|
||||
))}
|
||||
@@ -31,4 +35,8 @@ class Menu extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
Menu.propTypes = {
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
};
|
||||
|
||||
export default Menu;
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import React from 'react';
|
||||
import PropTypes from 'prop-types';
|
||||
import cn from 'classnames';
|
||||
import styles from './ViewingOptions.css';
|
||||
import { t } from 'plugin-api/beta/client/services';
|
||||
@@ -24,7 +25,7 @@ class ViewingOptions extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const { open, data, root, asset } = this.props;
|
||||
const { open, slotPassthrough } = this.props;
|
||||
return (
|
||||
<ClickOutside onClickOutside={this.handleClickOutside}>
|
||||
<div className={cn([styles.root, 'talk-plugin-viewing-options'])}>
|
||||
@@ -41,11 +42,18 @@ class ViewingOptions extends React.Component {
|
||||
)}
|
||||
</button>
|
||||
</div>
|
||||
{open && <Menu data={data} root={root} asset={asset} />}
|
||||
{open && <Menu slotPassthrough={slotPassthrough} />}
|
||||
</div>
|
||||
</ClickOutside>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
ViewingOptions.propTypes = {
|
||||
slotPassthrough: PropTypes.object.isRequired,
|
||||
open: PropTypes.bool.isRequired,
|
||||
openMenu: PropTypes.func.isRequired,
|
||||
closeMenu: PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
export default ViewingOptions;
|
||||
|
||||
@@ -4,6 +4,7 @@ import ViewingOptions from '../components/ViewingOptions';
|
||||
import { openMenu, closeMenu } from '../actions';
|
||||
import { compose, gql } from 'react-apollo';
|
||||
import { getSlotFragmentSpreads } from 'plugin-api/beta/client/utils';
|
||||
import { mapProps } from 'recompose';
|
||||
|
||||
const slots = ['viewingOptionsSort', 'viewingOptionsFilter'];
|
||||
|
||||
@@ -29,7 +30,14 @@ const withViewingOptionsFragments = withFragments({
|
||||
|
||||
const enhance = compose(
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
withViewingOptionsFragments
|
||||
withViewingOptionsFragments,
|
||||
mapProps(({ root, asset, ...rest }) => ({
|
||||
slotPassthrough: {
|
||||
root,
|
||||
asset,
|
||||
},
|
||||
...rest,
|
||||
}))
|
||||
);
|
||||
|
||||
export default enhance(ViewingOptions);
|
||||
|
||||
Reference in New Issue
Block a user