diff --git a/src/core/client/stream/components/App.spec.tsx b/src/core/client/stream/components/App.spec.tsx index 2afc61f74..01c0bec0b 100644 --- a/src/core/client/stream/components/App.spec.tsx +++ b/src/core/client/stream/components/App.spec.tsx @@ -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(); + const props: PropTypesOf = { + activeTab: "COMMENTS", + onTabClick: noop, + }; + const wrapper = shallow(); expect(wrapper).toMatchSnapshot(); }); diff --git a/src/core/client/stream/components/App.tsx b/src/core/client/stream/components/App.tsx index 006914ec8..3b6ccac08 100644 --- a/src/core/client/stream/components/App.tsx +++ b/src/core/client/stream/components/App.tsx @@ -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> = props => ( - - Comments - + ); const MyProfileTab: StatelessComponent> = props => ( - + My Profile - + ); const App: StatelessComponent = props => { diff --git a/src/core/client/stream/components/CommentCountTab.tsx b/src/core/client/stream/components/CommentCountTab.tsx new file mode 100644 index 000000000..d72ce465d --- /dev/null +++ b/src/core/client/stream/components/CommentCountTab.tsx @@ -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 { + commentCount: number; +} + +class CommentCountTab extends Component { + public render() { + const { commentCount, ...props } = this.props; + return ( + + {"{$commentCount} Comments"} + + ); + } +} + +export default CommentCountTab; diff --git a/src/core/client/stream/components/__snapshots__/App.spec.tsx.snap b/src/core/client/stream/components/__snapshots__/App.spec.tsx.snap index 9a2441a63..f99caa827 100644 --- a/src/core/client/stream/components/__snapshots__/App.spec.tsx.snap +++ b/src/core/client/stream/components/__snapshots__/App.spec.tsx.snap @@ -1,3 +1,34 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`renders comments 1`] = ``; +exports[`renders comments 1`] = ` + + + + + + + + + + + + + + +`; diff --git a/src/core/client/stream/containers/AppContainer.tsx b/src/core/client/stream/containers/AppContainer.tsx index e3e3918e5..eca6141a0 100644 --- a/src/core/client/stream/containers/AppContainer.tsx +++ b/src/core/client/stream/containers/AppContainer.tsx @@ -29,12 +29,14 @@ class AppContainer extends React.Component { } } -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; diff --git a/src/core/client/stream/containers/CommentsCountContainer.tsx b/src/core/client/stream/containers/CommentsCountContainer.tsx new file mode 100644 index 000000000..e69de29bb diff --git a/src/core/client/stream/mutations/CreateCommentMutation.ts b/src/core/client/stream/mutations/CreateCommentMutation.ts index 913606e8e..813563185 100644 --- a/src/core/client/stream/mutations/CreateCommentMutation.ts +++ b/src/core/client/stream/mutations/CreateCommentMutation.ts @@ -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")!; diff --git a/src/core/client/stream/queries/CommentsCountQuery.tsx b/src/core/client/stream/queries/CommentsCountQuery.tsx new file mode 100644 index 000000000..f589a26fc --- /dev/null +++ b/src/core/client/stream/queries/CommentsCountQuery.tsx @@ -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 { + local: Local; +} + +class CommentsCountQuery extends Component { + public render() { + const { assetID, assetURL } = this.props.local; + const { local: _, ...rest } = this.props; + return ( + + query={graphql` + query CommentsCountQuery($assetID: ID, $assetURL: String) { + asset(id: $assetID, url: $assetURL) { + commentCounts { + totalVisible + } + } + } + `} + variables={{ + assetID, + assetURL, + }} + render={({ error, props }) => { + if (error) { + return
{error.message}
; + } + + if (props && props.asset && props.asset.commentCounts.totalVisible) { + return ( + + ); + } + + return ; + }} + /> + ); + } +} + +const enhanced = withLocalStateContainer( + graphql` + fragment CommentsCountQueryLocal on Local { + assetID + assetURL + } + ` +)(CommentsCountQuery); + +export default enhanced; diff --git a/src/core/client/stream/containers/IfLoggedInContainer.tsx b/src/core/client/stream/queries/IfLoggedInQuery.tsx similarity index 80% rename from src/core/client/stream/containers/IfLoggedInContainer.tsx rename to src/core/client/stream/queries/IfLoggedInQuery.tsx index d22b8b60a..19687f631 100644 --- a/src/core/client/stream/containers/IfLoggedInContainer.tsx +++ b/src/core/client/stream/queries/IfLoggedInQuery.tsx @@ -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 ( query={graphql` - query IfLoggedInContainerQuery { + query IfLoggedInQuery { me { id } diff --git a/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap index f83e8d794..d08ad4599 100644 --- a/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/editComment.spec.tsx.snap @@ -27,7 +27,7 @@ exports[`cancel edit: edit canceled 1`] = ` role="tab" type="button" > - Comments + ⁨2⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • @@ -433,7 +433,7 @@ exports[`renders comment stream 1`] = ` role="tab" type="button" > - Comments + ⁨2⁩ Comments diff --git a/src/core/client/stream/test/comments/__snapshots__/permalinkView.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/permalinkView.spec.tsx.snap index e3465217b..dc408c24e 100644 --- a/src/core/client/stream/test/comments/__snapshots__/permalinkView.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/permalinkView.spec.tsx.snap @@ -27,7 +27,7 @@ exports[`renders permalink view 1`] = ` role="tab" type="button" > - Comments + ⁨2⁩ Comments @@ -158,7 +158,7 @@ exports[`show all comments 1`] = ` role="tab" type="button" > - Comments + ⁨2⁩ Comments diff --git a/src/core/client/stream/test/comments/__snapshots__/permalinkViewAssetNotFound.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/permalinkViewAssetNotFound.spec.tsx.snap index e5e570da7..209fbe533 100644 --- a/src/core/client/stream/test/comments/__snapshots__/permalinkViewAssetNotFound.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/permalinkViewAssetNotFound.spec.tsx.snap @@ -8,28 +8,23 @@ exports[`renders permalink view with unknown asset 1`] = ` className="TabBar-root TabBar-primary" role="tablist" > - + +
    - Comments + ⁨2⁩ Comments @@ -93,7 +93,7 @@ exports[`show all comments 1`] = ` role="tab" type="button" > - Comments + ⁨2⁩ Comments diff --git a/src/core/client/stream/test/comments/__snapshots__/postComment.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/postComment.spec.tsx.snap index 71f9f3bc2..b9c12183b 100644 --- a/src/core/client/stream/test/comments/__snapshots__/postComment.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/postComment.spec.tsx.snap @@ -27,7 +27,7 @@ exports[`post a comment: optimistic response 1`] = ` role="tab" type="button" > - Comments + ⁨3⁩ Comments
  • - Comments + ⁨3⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • - Comments + ⁨1⁩ Comments
  • - Comments + ⁨1⁩ Comments
  • - Comments + ⁨1⁩ Comments
  • - Comments + ⁨1⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • - Comments + ⁨3⁩ Comments
  • - Comments + ⁨3⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • - Comments + ⁨2⁩ Comments
  • diff --git a/src/core/client/stream/test/comments/__snapshots__/renderStream.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/renderStream.spec.tsx.snap index 1d6c3427e..dd39c45e0 100644 --- a/src/core/client/stream/test/comments/__snapshots__/renderStream.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/renderStream.spec.tsx.snap @@ -27,7 +27,7 @@ exports[`renders comment stream 1`] = ` role="tab" type="button" > - Comments + ⁨2⁩ Comments diff --git a/src/core/client/stream/test/comments/__snapshots__/showAllReplies.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/showAllReplies.spec.tsx.snap index 9c5c820bd..233b7810d 100644 --- a/src/core/client/stream/test/comments/__snapshots__/showAllReplies.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/showAllReplies.spec.tsx.snap @@ -27,7 +27,7 @@ exports[`renders comment stream 1`] = ` role="tab" type="button" > - Comments + ⁨2⁩ Comments @@ -389,7 +389,7 @@ exports[`show all replies 1`] = ` role="tab" type="button" > - Comments + ⁨2⁩ Comments diff --git a/src/core/client/stream/test/comments/__snapshots__/showConversation.spec.tsx.snap b/src/core/client/stream/test/comments/__snapshots__/showConversation.spec.tsx.snap index 2320b73fe..6fbd0d02b 100644 --- a/src/core/client/stream/test/comments/__snapshots__/showConversation.spec.tsx.snap +++ b/src/core/client/stream/test/comments/__snapshots__/showConversation.spec.tsx.snap @@ -27,7 +27,7 @@ exports[`renders comment stream 1`] = ` role="tab" type="button" > - Comments + ⁨1⁩ Comments @@ -701,7 +701,7 @@ exports[`shows conversation 1`] = ` role="tab" type="button" > - Comments + ⁨1⁩ Comments diff --git a/src/core/client/stream/test/create.tsx b/src/core/client/stream/test/create.tsx index f105162c4..432d9800a 100644 --- a/src/core/client/stream/test/create.tsx +++ b/src/core/client/stream/test/create.tsx @@ -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; diff --git a/src/core/client/stream/test/fixtures.ts b/src/core/client/stream/test/fixtures.ts index 0713db233..720b28c25 100644 --- a/src/core/client/stream/test/fixtures.ts +++ b/src/core/client/stream/test/fixtures.ts @@ -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, + }, }; diff --git a/src/locales/en-US/stream.ftl b/src/locales/en-US/stream.ftl index 486a7917b..c33aa9566 100644 --- a/src/locales/en-US/stream.ftl +++ b/src/locales/en-US/stream.ftl @@ -12,7 +12,7 @@ general-userBoxAuthenticated-signedInAs = general-userBoxAuthenticated-notYou = Not you? -general-app-commentsTab = Comments +general-app-commentsTab = {$commentCount} Comments general-app-myProfileTab = My Profile ## Comments Tab