mirror of
https://github.com/wassname/talk.git
synced 2026-08-16 11:29:31 +08:00
Merge pull request #1968 from coralproject/next-comment-counts
[next] Comments Count
This commit is contained in:
@@ -1,9 +1,16 @@
|
||||
import { shallow } from "enzyme";
|
||||
import noop from "lodash";
|
||||
import React from "react";
|
||||
|
||||
import AppContainer from "../containers/AppContainer";
|
||||
import { PropTypesOf } from "talk-framework/types";
|
||||
|
||||
import App from "./App";
|
||||
|
||||
it("renders comments", () => {
|
||||
const wrapper = shallow(<AppContainer />);
|
||||
const props: PropTypesOf<typeof App> = {
|
||||
activeTab: "COMMENTS",
|
||||
onTabClick: noop,
|
||||
};
|
||||
const wrapper = shallow(<App {...props} />);
|
||||
expect(wrapper).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@@ -10,7 +10,8 @@ import {
|
||||
} from "talk-ui/components";
|
||||
|
||||
import { PropTypesOf } from "talk-ui/types";
|
||||
import IfLoggedInContainer from "../containers/IfLoggedInContainer";
|
||||
import CommentsCountQuery from "../queries/CommentsCountQuery";
|
||||
import IfLoggedInQuery from "../queries/IfLoggedInQuery";
|
||||
import CommentsPaneContainer from "../tabs/comments/containers/CommentsPaneContainer";
|
||||
import ProfileQuery from "../tabs/profile/queries/ProfileQuery";
|
||||
import * as styles from "./App.css";
|
||||
@@ -23,17 +24,15 @@ export interface AppProps {
|
||||
}
|
||||
|
||||
const CommentsTab: StatelessComponent<PropTypesOf<typeof Tab>> = props => (
|
||||
<Localized id="general-app-commentsTab">
|
||||
<Tab {...props}>Comments</Tab>
|
||||
</Localized>
|
||||
<CommentsCountQuery {...props} />
|
||||
);
|
||||
|
||||
const MyProfileTab: StatelessComponent<PropTypesOf<typeof Tab>> = props => (
|
||||
<IfLoggedInContainer>
|
||||
<IfLoggedInQuery>
|
||||
<Localized id="general-app-myProfileTab">
|
||||
<Tab {...props}>My Profile</Tab>
|
||||
</Localized>
|
||||
</IfLoggedInContainer>
|
||||
</IfLoggedInQuery>
|
||||
);
|
||||
|
||||
const App: StatelessComponent<AppProps> = props => {
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
import { Localized } from "fluent-react/compat";
|
||||
import React, { Component } from "react";
|
||||
import { Tab } from "talk-ui/components";
|
||||
import { PropTypesOf } from "talk-ui/types";
|
||||
|
||||
interface CommentCountTabProps extends PropTypesOf<typeof Tab> {
|
||||
commentCount: number;
|
||||
}
|
||||
|
||||
class CommentCountTab extends Component<CommentCountTabProps> {
|
||||
public render() {
|
||||
const { commentCount, ...props } = this.props;
|
||||
return (
|
||||
<Localized id="general-app-commentsTab" $commentCount={commentCount}>
|
||||
<Tab {...props}>{"{$commentCount} Comments"}</Tab>
|
||||
</Localized>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CommentCountTab;
|
||||
@@ -1,3 +1,34 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders comments 1`] = `<Consumer />`;
|
||||
exports[`renders comments 1`] = `
|
||||
<withPropsOnChange(HorizontalGutter)
|
||||
className="App-root"
|
||||
>
|
||||
<withPropsOnChange(TabBar)
|
||||
activeTab="COMMENTS"
|
||||
onTabClick={[Function]}
|
||||
>
|
||||
<CommentsTab
|
||||
tabId="COMMENTS"
|
||||
/>
|
||||
<MyProfileTab
|
||||
tabId="PROFILE"
|
||||
/>
|
||||
</withPropsOnChange(TabBar)>
|
||||
<TabContent
|
||||
activeTab="COMMENTS"
|
||||
className="App-tabContent"
|
||||
>
|
||||
<TabPane
|
||||
tabId="COMMENTS"
|
||||
>
|
||||
<withContext(withLocalStateContainer(CommentsPaneContainer)) />
|
||||
</TabPane>
|
||||
<TabPane
|
||||
tabId="PROFILE"
|
||||
>
|
||||
<withContext(withLocalStateContainer(ProfileQuery)) />
|
||||
</TabPane>
|
||||
</TabContent>
|
||||
</withPropsOnChange(HorizontalGutter)>
|
||||
`;
|
||||
|
||||
@@ -29,12 +29,14 @@ class AppContainer extends React.Component<InnerProps> {
|
||||
}
|
||||
}
|
||||
|
||||
const enhanced = withLocalStateContainer(
|
||||
graphql`
|
||||
fragment AppContainerLocal on Local {
|
||||
activeTab
|
||||
}
|
||||
`
|
||||
)(withSetActiveTabMutation(AppContainer));
|
||||
const enhanced = withSetActiveTabMutation(
|
||||
withLocalStateContainer(
|
||||
graphql`
|
||||
fragment AppContainerLocal on Local {
|
||||
activeTab
|
||||
}
|
||||
`
|
||||
)(AppContainer)
|
||||
);
|
||||
|
||||
export default enhanced;
|
||||
|
||||
@@ -35,6 +35,17 @@ function sharedUpdater(
|
||||
* update integrates new comment into the CommentConnection.
|
||||
*/
|
||||
function update(store: RecordSourceSelectorProxy, input: CreateCommentInput) {
|
||||
// Updating Comment Count
|
||||
const asset = store.get(input.assetID);
|
||||
if (asset) {
|
||||
const record = asset.getLinkedRecord("commentCounts");
|
||||
if (record) {
|
||||
// TODO: when we have moderation, we'll need to be careful here.
|
||||
const currentCount = record.getValue("totalVisible");
|
||||
record.setValue(currentCount + 1, "totalVisible");
|
||||
}
|
||||
}
|
||||
|
||||
// Get the payload returned from the server.
|
||||
const payload = store.getRootField("createComment")!;
|
||||
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
import React, { Component } from "react";
|
||||
import {
|
||||
graphql,
|
||||
QueryRenderer,
|
||||
withLocalStateContainer,
|
||||
} from "talk-framework/lib/relay";
|
||||
import { CommentsCountQuery as QueryTypes } from "talk-stream/__generated__/CommentsCountQuery.graphql";
|
||||
import { CommentsCountQueryLocal as Local } from "talk-stream/__generated__/CommentsCountQueryLocal.graphql";
|
||||
import { Spinner } from "talk-ui/components";
|
||||
import { Tab } from "talk-ui/components";
|
||||
import { PropTypesOf } from "talk-ui/types";
|
||||
import CommentCountTab from "../components/CommentCountTab";
|
||||
|
||||
interface InnerProps extends PropTypesOf<typeof Tab> {
|
||||
local: Local;
|
||||
}
|
||||
|
||||
class CommentsCountQuery extends Component<InnerProps> {
|
||||
public render() {
|
||||
const { assetID, assetURL } = this.props.local;
|
||||
const { local: _, ...rest } = this.props;
|
||||
return (
|
||||
<QueryRenderer<QueryTypes>
|
||||
query={graphql`
|
||||
query CommentsCountQuery($assetID: ID, $assetURL: String) {
|
||||
asset(id: $assetID, url: $assetURL) {
|
||||
commentCounts {
|
||||
totalVisible
|
||||
}
|
||||
}
|
||||
}
|
||||
`}
|
||||
variables={{
|
||||
assetID,
|
||||
assetURL,
|
||||
}}
|
||||
render={({ error, props }) => {
|
||||
if (error) {
|
||||
return <div>{error.message}</div>;
|
||||
}
|
||||
|
||||
if (props && props.asset && props.asset.commentCounts.totalVisible) {
|
||||
return (
|
||||
<CommentCountTab
|
||||
commentCount={props.asset.commentCounts.totalVisible}
|
||||
{...rest}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
return <Spinner />;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const enhanced = withLocalStateContainer(
|
||||
graphql`
|
||||
fragment CommentsCountQueryLocal on Local {
|
||||
assetID
|
||||
assetURL
|
||||
}
|
||||
`
|
||||
)(CommentsCountQuery);
|
||||
|
||||
export default enhanced;
|
||||
+2
-2
@@ -1,14 +1,14 @@
|
||||
import React, { Component } from "react";
|
||||
|
||||
import { graphql, QueryRenderer } from "talk-framework/lib/relay";
|
||||
import { IfLoggedInContainerQuery as QueryTypes } from "talk-stream/__generated__/IfLoggedInContainerQuery.graphql";
|
||||
import { IfLoggedInQuery as QueryTypes } from "talk-stream/__generated__/IfLoggedInQuery.graphql";
|
||||
|
||||
class IfLoggedInContainer extends Component {
|
||||
public render() {
|
||||
return (
|
||||
<QueryRenderer<QueryTypes>
|
||||
query={graphql`
|
||||
query IfLoggedInContainerQuery {
|
||||
query IfLoggedInQuery {
|
||||
me {
|
||||
id
|
||||
}
|
||||
@@ -27,7 +27,7 @@ exports[`cancel edit: edit canceled 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -466,7 +466,7 @@ exports[`edit a comment: edit form 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -965,7 +965,7 @@ exports[`edit a comment: optimistic response 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -1464,7 +1464,7 @@ exports[`edit a comment: render stream 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -1903,7 +1903,7 @@ exports[`edit a comment: server response 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -2351,7 +2351,7 @@ exports[`shows expiry message: edit form closed 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -2790,7 +2790,7 @@ exports[`shows expiry message: edit time expired 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
|
||||
@@ -27,7 +27,7 @@ exports[`loads more comments 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -433,7 +433,7 @@ exports[`renders comment stream 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -27,7 +27,7 @@ exports[`renders permalink view 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -158,7 +158,7 @@ exports[`show all comments 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
+16
-21
@@ -8,28 +8,23 @@ exports[`renders permalink view with unknown asset 1`] = `
|
||||
className="TabBar-root TabBar-primary"
|
||||
role="tablist"
|
||||
>
|
||||
<li
|
||||
className="Tab-root"
|
||||
id="tab-COMMENTS"
|
||||
role="presentation"
|
||||
<svg
|
||||
className="Spinner-spinner"
|
||||
height="40px"
|
||||
viewBox="0 0 66 66"
|
||||
width="40px"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<button
|
||||
aria-controls="tabPane-COMMENTS"
|
||||
aria-selected={true}
|
||||
className="BaseButton-root Tab-button Tab-primary Tab-active"
|
||||
onBlur={[Function]}
|
||||
onClick={[Function]}
|
||||
onFocus={[Function]}
|
||||
onMouseDown={[Function]}
|
||||
onMouseOut={[Function]}
|
||||
onMouseOver={[Function]}
|
||||
onTouchEnd={[Function]}
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
</button>
|
||||
</li>
|
||||
<circle
|
||||
className="Spinner-path"
|
||||
cx="33"
|
||||
cy="33"
|
||||
fill="none"
|
||||
r="30"
|
||||
strokeLinecap="round"
|
||||
strokeWidth="6"
|
||||
/>
|
||||
</svg>
|
||||
</ul>
|
||||
<section
|
||||
aria-labelledby="tab-COMMENTS"
|
||||
|
||||
+2
-2
@@ -27,7 +27,7 @@ exports[`renders permalink view with unknown comment 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -93,7 +93,7 @@ exports[`show all comments 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -27,7 +27,7 @@ exports[`post a comment: optimistic response 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
3 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -549,7 +549,7 @@ exports[`post a comment: server response 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
3 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -1061,7 +1061,7 @@ exports[`renders comment stream 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
|
||||
@@ -27,7 +27,7 @@ exports[`post a reply: open reply form 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
1 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -979,7 +979,7 @@ exports[`post a reply: optimistic response 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
1 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -2020,7 +2020,7 @@ exports[`post a reply: server response 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
1 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -2924,7 +2924,7 @@ exports[`renders comment stream 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
1 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
|
||||
@@ -27,7 +27,7 @@ exports[`post a reply: open reply form 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -577,7 +577,7 @@ exports[`post a reply: optimistic response 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
3 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -1232,7 +1232,7 @@ exports[`post a reply: server response 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
3 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
@@ -1750,7 +1750,7 @@ exports[`renders comment stream 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
<li
|
||||
|
||||
@@ -27,7 +27,7 @@ exports[`renders comment stream 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -27,7 +27,7 @@ exports[`renders comment stream 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -27,7 +27,7 @@ exports[`renders comment stream 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -389,7 +389,7 @@ exports[`show all replies 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
2 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -27,7 +27,7 @@ exports[`renders comment stream 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
1 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -701,7 +701,7 @@ exports[`shows conversation 1`] = `
|
||||
role="tab"
|
||||
type="button"
|
||||
>
|
||||
Comments
|
||||
1 Comments
|
||||
</button>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
@@ -10,12 +10,13 @@ import { PostMessageService } from "talk-framework/lib/postMessage";
|
||||
import { RestClient } from "talk-framework/lib/rest";
|
||||
import { createPromisifiedStorage } from "talk-framework/lib/storage";
|
||||
import { createUUIDGenerator } from "talk-framework/testHelpers";
|
||||
import AppContainer from "talk-stream/containers/AppContainer";
|
||||
|
||||
import createEnvironment from "./createEnvironment";
|
||||
import createFluentBundle from "./createFluentBundle";
|
||||
import createNodeMock from "./createNodeMock";
|
||||
|
||||
import AppContainer from "../containers/AppContainer";
|
||||
|
||||
export interface CreateParams {
|
||||
logNetwork?: boolean;
|
||||
resolvers: IResolvers<any, any>;
|
||||
|
||||
@@ -215,6 +215,9 @@ export const baseAsset = {
|
||||
hasNextPage: false,
|
||||
},
|
||||
},
|
||||
commentCounts: {
|
||||
totalVisible: 0,
|
||||
},
|
||||
};
|
||||
|
||||
export const assets = [
|
||||
@@ -231,6 +234,9 @@ export const assets = [
|
||||
hasNextPage: false,
|
||||
},
|
||||
},
|
||||
commentCounts: {
|
||||
totalVisible: 2,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -247,6 +253,9 @@ export const assetWithReplies = {
|
||||
hasNextPage: false,
|
||||
},
|
||||
},
|
||||
commentCounts: {
|
||||
totalVisible: 2,
|
||||
},
|
||||
};
|
||||
|
||||
export const assetWithDeepReplies = {
|
||||
@@ -265,6 +274,9 @@ export const assetWithDeepReplies = {
|
||||
hasNextPage: false,
|
||||
},
|
||||
},
|
||||
commentCounts: {
|
||||
totalVisible: 2,
|
||||
},
|
||||
};
|
||||
|
||||
export const assetWithDeepestReplies = {
|
||||
@@ -282,4 +294,7 @@ export const assetWithDeepestReplies = {
|
||||
hasNextPage: false,
|
||||
},
|
||||
},
|
||||
commentCounts: {
|
||||
totalVisible: 1,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -12,7 +12,7 @@ general-userBoxAuthenticated-signedInAs =
|
||||
general-userBoxAuthenticated-notYou =
|
||||
Not you? <button>Sign Out</button>
|
||||
|
||||
general-app-commentsTab = Comments
|
||||
general-app-commentsTab = {$commentCount} Comments
|
||||
general-app-myProfileTab = My Profile
|
||||
|
||||
## Comments Tab
|
||||
|
||||
Reference in New Issue
Block a user