mirror of
https://github.com/wassname/talk.git
synced 2026-06-29 19:01:47 +08:00
Filter queryData in withFragments and optimize rendering
This commit is contained in:
@@ -224,6 +224,10 @@ export default class Comment extends React.Component {
|
||||
return;
|
||||
}
|
||||
|
||||
commentPostedHandler = () => {
|
||||
this.props.setActiveReplyBox('');
|
||||
}
|
||||
|
||||
// getVisibileReplies returns a list containing comments
|
||||
// which were authored by current user or comes before the `idCursor`.
|
||||
getVisibileReplies() {
|
||||
@@ -372,10 +376,13 @@ export default class Comment extends React.Component {
|
||||
// props that are passed down the slots.
|
||||
const slotProps = {
|
||||
data,
|
||||
depth,
|
||||
};
|
||||
|
||||
const queryData = {
|
||||
root,
|
||||
asset,
|
||||
comment,
|
||||
depth,
|
||||
};
|
||||
|
||||
return (
|
||||
@@ -389,6 +396,7 @@ export default class Comment extends React.Component {
|
||||
className={`${styles.commentAvatar} talk-stream-comment-avatar`}
|
||||
fill="commentAvatar"
|
||||
{...slotProps}
|
||||
queryData={queryData}
|
||||
inline
|
||||
/>
|
||||
|
||||
@@ -411,6 +419,7 @@ export default class Comment extends React.Component {
|
||||
className={styles.commentInfoBar}
|
||||
fill="commentInfoBar"
|
||||
{...slotProps}
|
||||
queryData={queryData}
|
||||
/>
|
||||
|
||||
{ isActive && (currentUser && (comment.user.id === currentUser.id)) &&
|
||||
@@ -457,6 +466,7 @@ export default class Comment extends React.Component {
|
||||
fill="commentContent"
|
||||
defaultComponent={CommentContent}
|
||||
{...slotProps}
|
||||
queryData={queryData}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
@@ -468,6 +478,7 @@ export default class Comment extends React.Component {
|
||||
<Slot
|
||||
fill="commentReactions"
|
||||
{...slotProps}
|
||||
queryData={queryData}
|
||||
inline
|
||||
/>
|
||||
{!disableReply &&
|
||||
@@ -484,6 +495,7 @@ export default class Comment extends React.Component {
|
||||
fill="commentActions"
|
||||
wrapperComponent={ActionButton}
|
||||
{...slotProps}
|
||||
queryData={queryData}
|
||||
inline
|
||||
/>
|
||||
<ActionButton>
|
||||
@@ -509,9 +521,7 @@ export default class Comment extends React.Component {
|
||||
|
||||
{activeReplyBox === comment.id
|
||||
? <ReplyBox
|
||||
commentPostedHandler={() => {
|
||||
setActiveReplyBox('');
|
||||
}}
|
||||
commentPostedHandler={this.commentPostedHandler}
|
||||
charCountEnable={charCountEnable}
|
||||
maxCharCount={maxCharCount}
|
||||
setActiveReplyBox={setActiveReplyBox}
|
||||
|
||||
@@ -40,6 +40,15 @@ class Stream extends React.Component {
|
||||
}
|
||||
}
|
||||
|
||||
commentIsIgnored = (comment) => {
|
||||
const me = this.props.root.me;
|
||||
return (
|
||||
me &&
|
||||
me.ignoredUsers &&
|
||||
me.ignoredUsers.find((u) => u.id === comment.user.id)
|
||||
);
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
data,
|
||||
@@ -48,7 +57,7 @@ class Stream extends React.Component {
|
||||
setActiveReplyBox,
|
||||
appendItemArray,
|
||||
commentClassNames,
|
||||
root: {asset, asset: {comment, comments, totalCommentCount}, me},
|
||||
root: {asset, asset: {comment, comments, totalCommentCount}},
|
||||
postComment,
|
||||
addNotification,
|
||||
editComment,
|
||||
@@ -89,16 +98,9 @@ class Stream extends React.Component {
|
||||
user.suspension.until &&
|
||||
new Date(user.suspension.until) > new Date();
|
||||
|
||||
const commentIsIgnored = (comment) => {
|
||||
return (
|
||||
me &&
|
||||
me.ignoredUsers &&
|
||||
me.ignoredUsers.find((u) => u.id === comment.user.id)
|
||||
);
|
||||
};
|
||||
|
||||
const showCommentBox = loggedIn && ((!banned && !temporarilySuspended && !highlightedComment) || keepCommentBox);
|
||||
const slotProps = {data, root, asset};
|
||||
const slotProps = {data};
|
||||
const slotQueryData = {root, asset};
|
||||
|
||||
if (!comment && !comments) {
|
||||
console.error('Talk: No comments came back from the graph given that query. Please, check the query params.');
|
||||
@@ -160,6 +162,7 @@ class Stream extends React.Component {
|
||||
|
||||
<Slot
|
||||
fill="stream"
|
||||
queryData={slotQueryData}
|
||||
{...slotProps}
|
||||
/>
|
||||
|
||||
@@ -194,7 +197,7 @@ class Stream extends React.Component {
|
||||
deleteAction={deleteAction}
|
||||
showSignInDialog={showSignInDialog}
|
||||
key={highlightedComment.id}
|
||||
commentIsIgnored={commentIsIgnored}
|
||||
commentIsIgnored={this.commentIsIgnored}
|
||||
comment={highlightedComment}
|
||||
charCountEnable={asset.settings.charCountEnable}
|
||||
maxCharCount={asset.settings.charCount}
|
||||
@@ -209,6 +212,7 @@ class Stream extends React.Component {
|
||||
>
|
||||
<Slot
|
||||
fill="streamFilter"
|
||||
queryData={slotQueryData}
|
||||
{...slotProps}
|
||||
/>
|
||||
</div>
|
||||
@@ -219,6 +223,7 @@ class Stream extends React.Component {
|
||||
tabSlot={'streamTabs'}
|
||||
tabPaneSlot={'streamTabPanes'}
|
||||
slotProps={slotProps}
|
||||
queryData={slotQueryData}
|
||||
appendTabs={
|
||||
<Tab tabId={'all'} key='all'>
|
||||
All Comments <TabCount active={activeStreamTab === 'all'} sub>{totalCommentCount}</TabCount>
|
||||
@@ -245,7 +250,7 @@ class Stream extends React.Component {
|
||||
loadNewReplies={loadNewReplies}
|
||||
deleteAction={deleteAction}
|
||||
showSignInDialog={showSignInDialog}
|
||||
commentIsIgnored={commentIsIgnored}
|
||||
commentIsIgnored={this.commentIsIgnored}
|
||||
charCountEnable={asset.settings.charCountEnable}
|
||||
maxCharCount={asset.settings.charCount}
|
||||
editComment={editComment}
|
||||
|
||||
@@ -3,7 +3,9 @@ import React from 'react';
|
||||
import Comment from '../components/Comment';
|
||||
import {withFragments} from 'coral-framework/hocs';
|
||||
import {getSlotFragmentSpreads} from 'coral-framework/utils';
|
||||
import {THREADING_LEVEL} from '../constants/stream';
|
||||
import hoistStatics from 'recompose/hoistStatics';
|
||||
import {nest} from '../graphql/utils';
|
||||
|
||||
const slots = [
|
||||
'streamQuestionArea',
|
||||
@@ -48,6 +50,36 @@ const withAnimateEnter = hoistStatics((BaseComponent) => {
|
||||
return WithAnimateEnter;
|
||||
});
|
||||
|
||||
const singleCommentFragment = gql`
|
||||
fragment CoralEmbedStream_Comment_SingleComment on Comment {
|
||||
id
|
||||
body
|
||||
created_at
|
||||
status
|
||||
replyCount
|
||||
tags {
|
||||
tag {
|
||||
name
|
||||
}
|
||||
}
|
||||
user {
|
||||
id
|
||||
username
|
||||
}
|
||||
action_summaries {
|
||||
__typename
|
||||
count
|
||||
current_user {
|
||||
id
|
||||
}
|
||||
}
|
||||
editing {
|
||||
edited
|
||||
editableUntil
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
const withCommentFragments = withFragments({
|
||||
root: gql`
|
||||
fragment CoralEmbedStream_Comment_root on RootQuery {
|
||||
@@ -63,33 +95,21 @@ const withCommentFragments = withFragments({
|
||||
`,
|
||||
comment: gql`
|
||||
fragment CoralEmbedStream_Comment_comment on Comment {
|
||||
id
|
||||
body
|
||||
created_at
|
||||
status
|
||||
replyCount
|
||||
tags {
|
||||
tag {
|
||||
name
|
||||
...CoralEmbedStream_Comment_SingleComment
|
||||
${nest(`
|
||||
replies(limit: 3, excludeIgnored: $excludeIgnored) {
|
||||
nodes {
|
||||
...CoralEmbedStream_Comment_SingleComment
|
||||
...nest
|
||||
}
|
||||
hasNextPage
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
}
|
||||
user {
|
||||
id
|
||||
username
|
||||
}
|
||||
action_summaries {
|
||||
__typename
|
||||
count
|
||||
current_user {
|
||||
id
|
||||
}
|
||||
}
|
||||
editing {
|
||||
edited
|
||||
editableUntil
|
||||
}
|
||||
`, THREADING_LEVEL)}
|
||||
${getSlotFragmentSpreads(slots, 'comment')}
|
||||
}
|
||||
${singleCommentFragment}
|
||||
`
|
||||
});
|
||||
|
||||
|
||||
@@ -161,19 +161,11 @@ class StreamContainer extends React.Component {
|
||||
const commentFragment = gql`
|
||||
fragment CoralEmbedStream_Stream_comment on Comment {
|
||||
id
|
||||
status
|
||||
user {
|
||||
id
|
||||
}
|
||||
...${getDefinitionName(Comment.fragments.comment)}
|
||||
${nest(`
|
||||
replies(excludeIgnored: $excludeIgnored) {
|
||||
nodes {
|
||||
id
|
||||
...${getDefinitionName(Comment.fragments.comment)}
|
||||
...nest
|
||||
}
|
||||
hasNextPage
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
`, THREADING_LEVEL)}
|
||||
}
|
||||
${Comment.fragments.comment}
|
||||
`;
|
||||
@@ -210,27 +202,14 @@ const LOAD_MORE_QUERY = gql`
|
||||
query CoralEmbedStream_LoadMoreComments($limit: Int = 5, $cursor: Date, $parent_id: ID, $asset_id: ID, $sort: SORT_ORDER, $excludeIgnored: Boolean) {
|
||||
comments(query: {limit: $limit, cursor: $cursor, parent_id: $parent_id, asset_id: $asset_id, sort: $sort, excludeIgnored: $excludeIgnored}) {
|
||||
nodes {
|
||||
id
|
||||
...${getDefinitionName(Comment.fragments.comment)}
|
||||
${nest(`
|
||||
replies(limit: 3, excludeIgnored: $excludeIgnored) {
|
||||
nodes {
|
||||
id
|
||||
...${getDefinitionName(Comment.fragments.comment)}
|
||||
...nest
|
||||
}
|
||||
hasNextPage
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
`, THREADING_LEVEL)}
|
||||
...CoralEmbedStream_Stream_comment
|
||||
}
|
||||
hasNextPage
|
||||
startCursor
|
||||
endCursor
|
||||
}
|
||||
}
|
||||
${Comment.fragments.comment}
|
||||
${commentFragment}
|
||||
`;
|
||||
|
||||
const slots = [
|
||||
|
||||
@@ -2,7 +2,7 @@ import React from 'react';
|
||||
import StreamTabPanel from '../components/StreamTabPanel';
|
||||
import {connect} from 'react-redux';
|
||||
import omit from 'lodash/omit';
|
||||
import {getSlotComponents} from 'coral-framework/helpers/plugins';
|
||||
import {getSlotComponents, getSlotComponentProps} from 'coral-framework/helpers/plugins';
|
||||
import {Tab, TabPane} from 'coral-ui';
|
||||
import {getShallowChanges} from 'coral-framework/utils';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
@@ -43,14 +43,14 @@ class StreamTabPanelContainer extends React.Component {
|
||||
}
|
||||
|
||||
getSlotComponents(slot, props = this.props) {
|
||||
return getSlotComponents(slot, props.reduxState, props.slotProps);
|
||||
return getSlotComponents(slot, props.reduxState, props.slotProps, props.queryData);
|
||||
}
|
||||
|
||||
getPluginTabElements(props = this.props) {
|
||||
return this.getSlotComponents(props.tabSlot).map((PluginComponent) => (
|
||||
<Tab tabId={PluginComponent.talkPluginName} key={PluginComponent.talkPluginName}>
|
||||
<PluginComponent
|
||||
{...props.slotProps}
|
||||
{...getSlotComponentProps(PluginComponent, props.reduxState, props.slotProps, props.queryData)}
|
||||
active={this.props.activeTab === PluginComponent.talkPluginName}
|
||||
/>
|
||||
</Tab>
|
||||
@@ -61,7 +61,7 @@ class StreamTabPanelContainer extends React.Component {
|
||||
return this.getSlotComponents(props.tabPaneSlot).map((PluginComponent) => (
|
||||
<TabPane tabId={PluginComponent.talkPluginName} key={PluginComponent.talkPluginName}>
|
||||
<PluginComponent
|
||||
{...props.slotProps}
|
||||
{...getSlotComponentProps(PluginComponent, props.reduxState, props.slotProps, props.queryData)}
|
||||
/>
|
||||
</TabPane>
|
||||
));
|
||||
@@ -95,6 +95,8 @@ StreamTabPanelContainer.propTypes = {
|
||||
fallbackTab: PropTypes.string.isRequired,
|
||||
tabSlot: PropTypes.string.isRequired,
|
||||
tabPaneSlot: PropTypes.string.isRequired,
|
||||
slotProps: PropTypes.object.isRequired,
|
||||
queryData: PropTypes.object,
|
||||
className: PropTypes.string,
|
||||
sub: PropTypes.bool,
|
||||
};
|
||||
|
||||
@@ -2,11 +2,13 @@ import React from 'react';
|
||||
import cn from 'classnames';
|
||||
import styles from './Slot.css';
|
||||
import {connect} from 'react-redux';
|
||||
import {getSlotElements} from 'coral-framework/helpers/plugins';
|
||||
import {getSlotElements, getSlotComponentProps} from 'coral-framework/helpers/plugins';
|
||||
import omit from 'lodash/omit';
|
||||
import isEqual from 'lodash/isEqual';
|
||||
import {getShallowChanges} from 'coral-framework/utils';
|
||||
|
||||
const emptyConfig = {};
|
||||
|
||||
class Slot extends React.Component {
|
||||
shouldComponentUpdate(next) {
|
||||
|
||||
@@ -23,20 +25,20 @@ class Slot extends React.Component {
|
||||
return changes.length !== 0;
|
||||
}
|
||||
|
||||
getSlotProps({fill: _a, inline: _b, className: _c, reduxState: _d, defaultComponent_: _e, ...rest} = this.props) {
|
||||
getSlotProps({fill: _a, inline: _b, className: _c, reduxState: _d, defaultComponent_: _e, queryData: _f, ...rest} = this.props) {
|
||||
return rest;
|
||||
}
|
||||
|
||||
getChildren(props = this.props) {
|
||||
return getSlotElements(props.fill, props.reduxState, this.getSlotProps(props));
|
||||
return getSlotElements(props.fill, props.reduxState, this.getSlotProps(props), props.queryData);
|
||||
}
|
||||
|
||||
render() {
|
||||
const {inline = false, className, reduxState, defaultComponent: DefaultComponent} = this.props;
|
||||
const {inline = false, className, reduxState, defaultComponent: DefaultComponent, queryData} = this.props;
|
||||
let children = this.getChildren();
|
||||
const pluginConfig = reduxState.config.pluginConfig || {};
|
||||
const pluginConfig = reduxState.config.pluginConfig || emptyConfig;
|
||||
if (children.length === 0 && DefaultComponent) {
|
||||
children = <DefaultComponent {...this.getSlotProps(this.props)} />;
|
||||
children = <DefaultComponent {...getSlotComponentProps(DefaultComponent, reduxState, this.getSlotProps(this.props), queryData)} />;
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -48,7 +50,8 @@ class Slot extends React.Component {
|
||||
}
|
||||
|
||||
Slot.propTypes = {
|
||||
fill: React.PropTypes.string.isRequired
|
||||
fill: React.PropTypes.string.isRequired,
|
||||
queryData: React.PropTypes.object,
|
||||
};
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
|
||||
@@ -11,8 +11,11 @@ import camelize from './camelize';
|
||||
import plugins from 'pluginsConfig';
|
||||
import uuid from 'uuid/v4';
|
||||
|
||||
export function getSlotComponents(slot, reduxState, props = {}) {
|
||||
const pluginConfig = reduxState.config.plugin_config || {};
|
||||
// This is returned for pluginConfig when it is empty.
|
||||
const emptyConfig = {};
|
||||
|
||||
export function getSlotComponents(slot, reduxState, props = {}, queryData = {}) {
|
||||
const pluginConfig = reduxState.config.plugin_config || emptyConfig;
|
||||
return flatten(plugins
|
||||
|
||||
// Filter out components that have slots and have been disabled in `plugin_config`
|
||||
@@ -25,7 +28,7 @@ export function getSlotComponents(slot, reduxState, props = {}) {
|
||||
if(!component.isExcluded) {
|
||||
return true;
|
||||
}
|
||||
let resolvedProps = {...props, config: pluginConfig};
|
||||
let resolvedProps = getSlotComponentProps(component, reduxState, props, queryData);
|
||||
if (component.mapStateToProps) {
|
||||
resolvedProps = {...resolvedProps, ...component.mapStateToProps(reduxState)};
|
||||
}
|
||||
@@ -33,17 +36,35 @@ export function getSlotComponents(slot, reduxState, props = {}) {
|
||||
});
|
||||
}
|
||||
|
||||
export function isSlotEmpty(slot, reduxState, props) {
|
||||
return getSlotComponents(slot, reduxState, props).length === 0;
|
||||
export function isSlotEmpty(slot, reduxState, props = {}, queryData = {}) {
|
||||
return getSlotComponents(slot, reduxState, props, queryData).length === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* getSlotComponentProps calculate the props we would pass to the slot component.
|
||||
* query datas are only passed to the component if it is defined in `component.fragments`.
|
||||
*/
|
||||
export function getSlotComponentProps(component, reduxState, props, queryData) {
|
||||
const pluginConfig = reduxState.config.plugin_config || emptyConfig;
|
||||
return {
|
||||
...props,
|
||||
config: pluginConfig,
|
||||
...(
|
||||
component.fragments
|
||||
? pick(queryData, Object.keys(component.fragments))
|
||||
: queryData // TODO: should be {}
|
||||
)
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns React Elements for given slot.
|
||||
*/
|
||||
export function getSlotElements(slot, reduxState, props = {}) {
|
||||
const pluginConfig = reduxState.config.plugin_config || {};
|
||||
return getSlotComponents(slot, reduxState, props)
|
||||
.map((component, i) => React.createElement(component, {key: i, ...props, config: pluginConfig}));
|
||||
export function getSlotElements(slot, reduxState, props = {}, queryData = {}) {
|
||||
return getSlotComponents(slot, reduxState, props, queryData)
|
||||
.map((component, i) => {
|
||||
return React.createElement(component, {key: i, ...getSlotComponentProps(component, reduxState, props, queryData)});
|
||||
});
|
||||
}
|
||||
|
||||
export function getSlotFragments(slot, part) {
|
||||
|
||||
@@ -1,17 +1,98 @@
|
||||
// TODO: revisit `filtering` after https://github.com/apollographql/graphql-anywhere/issues/38.
|
||||
|
||||
import React from 'react';
|
||||
import graphql from 'graphql-anywhere';
|
||||
import {resolveFragments} from 'coral-framework/services/graphqlRegistry';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
import hoistStatics from 'recompose/hoistStatics';
|
||||
import {getShallowChanges} from 'coral-framework/utils';
|
||||
|
||||
// TODO: Should not depend on `props.data`
|
||||
// Currently necessary because of this https://github.com/apollographql/graphql-anywhere/issues/38
|
||||
function filter(doc, data, variables) {
|
||||
const resolver = (
|
||||
fieldName,
|
||||
root,
|
||||
args,
|
||||
context,
|
||||
info,
|
||||
) => {
|
||||
return root[info.resultKey];
|
||||
};
|
||||
|
||||
return graphql(resolver, doc, data, null, variables);
|
||||
}
|
||||
|
||||
// filterProps returns only the property as defined in the fragments.
|
||||
// TODO: Should not depend on `props.data`
|
||||
function filterProps(props, fragments) {
|
||||
const filtered = {};
|
||||
Object.keys(fragments).forEach((key) => {
|
||||
if (!(key in props)) {
|
||||
return;
|
||||
}
|
||||
filtered[key] = filter(fragments[key], props[key], props.data.variables);
|
||||
});
|
||||
return filtered;
|
||||
}
|
||||
|
||||
// hasEqualLeaves compares two different apollo query result for equality.
|
||||
function hasEqualLeaves(a, b, path = '') {
|
||||
for (const key in a) {
|
||||
if (typeof a[key] === 'object') {
|
||||
if (Array.isArray(a[key])) {
|
||||
if (a[key].length !== b[key].length) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!hasEqualLeaves(a[key], b[key], `${path}.${key}`)) {
|
||||
return false;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (a[key] !== b[key]) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
export default (fragments) => hoistStatics((BaseComponent) => {
|
||||
class WithFragments extends React.Component {
|
||||
fragments = mapValues(fragments, (val) => resolveFragments(val));
|
||||
fragmentKeys = Object.keys(fragments).sort();
|
||||
|
||||
// Cache variables between lifecycles to speed up render.
|
||||
filteredProps = filterProps(this.props, this.fragments)
|
||||
queryDataHasChanged = false;
|
||||
lastFilteredProps = null;
|
||||
shallowChanges = null;
|
||||
|
||||
componentWillReceiveProps(next) {
|
||||
this.shallowChanges = getShallowChanges(this.props, next);
|
||||
this.queryDataHasChanged = this.fragmentKeys.some((key) => this.shallowChanges.indexOf(key) >= 0);
|
||||
|
||||
if (this.queryDataHasChanged) {
|
||||
|
||||
// If query data has changed, we compute the next filtered props.
|
||||
this.lastFilteredProps = this.filteredProps;
|
||||
this.filteredProps = filterProps(next, this.fragments);
|
||||
}
|
||||
}
|
||||
|
||||
shouldComponentUpdate(next) {
|
||||
|
||||
// If only query data was changed.
|
||||
if (this.queryDataHasChanged && this.shallowChanges.every((key) => this.fragmentKeys.indexOf(key) >= 0)) {
|
||||
return !hasEqualLeaves(this.lastFilteredProps, this.filteredProps);
|
||||
}
|
||||
|
||||
return this.shallowChanges.length !== 0;
|
||||
}
|
||||
|
||||
render() {
|
||||
const queryProps = this.filteredProps;
|
||||
return <BaseComponent
|
||||
{...this.props}
|
||||
{...queryProps}
|
||||
/>;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -176,7 +176,7 @@ export default (reaction) => hoistStatics((WrappedComponent) => {
|
||||
createdSubscription = context.client.subscribe({
|
||||
query: REACTION_CREATED_SUBSCRIPTION,
|
||||
variables: {
|
||||
assetId: this.props.root.asset.id,
|
||||
assetId: this.props.asset.id,
|
||||
},
|
||||
}).subscribe({
|
||||
next: this.onReactionCreated,
|
||||
@@ -186,7 +186,7 @@ export default (reaction) => hoistStatics((WrappedComponent) => {
|
||||
deletedSubscription = context.client.subscribe({
|
||||
query: REACTION_DELETED_SUBSCRIPTION,
|
||||
variables: {
|
||||
assetId: this.props.root.asset.id,
|
||||
assetId: this.props.asset.id,
|
||||
},
|
||||
}).subscribe({
|
||||
next: this.onReactionDeleted,
|
||||
@@ -372,9 +372,16 @@ export default (reaction) => hoistStatics((WrappedComponent) => {
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
asset: gql`
|
||||
fragment ${Reaction}Button_asset on Asset {
|
||||
id
|
||||
}
|
||||
`,
|
||||
comment: gql`
|
||||
fragment ${Reaction}Button_comment on Comment {
|
||||
id
|
||||
action_summaries {
|
||||
__typename
|
||||
... on ${Reaction}ActionSummary {
|
||||
count
|
||||
current_user {
|
||||
|
||||
@@ -93,8 +93,14 @@ export default (tag) => hoistStatics((WrappedComponent) => {
|
||||
|
||||
const enhance = compose(
|
||||
withFragments({
|
||||
asset: gql`
|
||||
fragment ${Tag}Button_asset on Asset {
|
||||
id
|
||||
}
|
||||
`,
|
||||
comment: gql`
|
||||
fragment ${Tag}Button_comment on Comment {
|
||||
id
|
||||
tags {
|
||||
tag {
|
||||
name
|
||||
|
||||
@@ -16,8 +16,8 @@ class TabPaneContainer extends React.Component {
|
||||
query: LOAD_MORE_QUERY,
|
||||
variables: {
|
||||
limit: 5,
|
||||
cursor: this.props.root.asset.featuredComments.endCursor,
|
||||
asset_id: this.props.root.asset.id,
|
||||
cursor: this.props.asset.featuredComments.endCursor,
|
||||
asset_id: this.props.asset.id,
|
||||
sort: 'REVERSE_CHRONOLOGICAL',
|
||||
excludeIgnored: this.props.data.variables.excludeIgnored,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user