From 796d24db3d2f8b129341431c216f43b736f4cb3e Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Mon, 2 Jul 2018 19:13:13 -0300
Subject: [PATCH 01/42] Use pagination container
---
.../lib/relay/withPaginationContainer.ts | 15 ++-
src/core/client/stream/components/App.tsx | 12 +-
.../stream/components/PostCommentForm.css | 7 +-
.../stream/components/PostCommentForm.tsx | 12 +-
src/core/client/stream/components/Stream.tsx | 22 +++-
.../client/stream/containers/AppContainer.tsx | 6 +-
.../containers/PostCommentFormContainer.tsx | 2 +
.../stream/containers/StreamContainer.tsx | 108 +++++++++++++++---
.../server/graph/tenant/schema/schema.graphql | 5 +-
src/core/server/models/comment.ts | 1 +
src/core/server/models/connection.ts | 1 +
11 files changed, 148 insertions(+), 43 deletions(-)
diff --git a/src/core/client/framework/lib/relay/withPaginationContainer.ts b/src/core/client/framework/lib/relay/withPaginationContainer.ts
index 5f768c0a7..9c669123b 100644
--- a/src/core/client/framework/lib/relay/withPaginationContainer.ts
+++ b/src/core/client/framework/lib/relay/withPaginationContainer.ts
@@ -1,10 +1,23 @@
import {
- ConnectionConfig,
+ ConnectionConfig as OrigConnectionConfig,
createPaginationContainer,
GraphQLTaggedNode,
+ PageInfo,
RelayPaginationProp,
} from "react-relay";
import { InferableComponentEnhancerWithProps } from "recompose";
+import { Overwrite } from "talk-framework/types";
+
+// TODO: (cvle) Fix this type definition upstream.
+interface ConnectionData {
+ edges?: Readonly;
+ pageInfo?: PageInfo;
+}
+
+type ConnectionConfig = Overwrite<
+ OrigConnectionConfig,
+ { getConnectionFromProps?(props: T): ConnectionData | undefined | null }
+>;
/**
* withPaginationContainer is a curried version of `createPaginationContainers`
diff --git a/src/core/client/stream/components/App.tsx b/src/core/client/stream/components/App.tsx
index dde8e386c..3e2dc2692 100644
--- a/src/core/client/stream/components/App.tsx
+++ b/src/core/client/stream/components/App.tsx
@@ -4,17 +4,11 @@ import { StatelessComponent } from "react";
import { Center } from "talk-ui/components";
import AssetListContainer from "../containers/AssetListContainer";
-import PostCommentFormContainer from "../containers/PostCommentFormContainer";
import StreamContainer from "../containers/StreamContainer";
-import Logo from "./Logo";
export interface AppProps {
assets?: any | null;
- asset?: {
- id: string;
- isClosed: boolean;
- comments: any | null;
- } | null;
+ asset?: {} | null;
}
const App: StatelessComponent = props => {
@@ -24,9 +18,7 @@ const App: StatelessComponent = props => {
if (props.asset) {
return (
-
-
-
+
);
}
diff --git a/src/core/client/stream/components/PostCommentForm.css b/src/core/client/stream/components/PostCommentForm.css
index a536dcc8b..c776ca7c8 100644
--- a/src/core/client/stream/components/PostCommentForm.css
+++ b/src/core/client/stream/components/PostCommentForm.css
@@ -7,6 +7,7 @@
margin-bottom: calc(2px * $spacing-unit);
}
-.postButton {
- float: right;
-}
+.postButtonContainer {
+ display: flex;
+ justify-content: flex-end;
+}
\ No newline at end of file
diff --git a/src/core/client/stream/components/PostCommentForm.tsx b/src/core/client/stream/components/PostCommentForm.tsx
index 2187994be..018cc71dd 100644
--- a/src/core/client/stream/components/PostCommentForm.tsx
+++ b/src/core/client/stream/components/PostCommentForm.tsx
@@ -39,11 +39,13 @@ const PostCommentForm: StatelessComponent = props => (
)}
-
+
+
+
)}
diff --git a/src/core/client/stream/components/Stream.tsx b/src/core/client/stream/components/Stream.tsx
index c42bb21b3..ccda84eea 100644
--- a/src/core/client/stream/components/Stream.tsx
+++ b/src/core/client/stream/components/Stream.tsx
@@ -1,18 +1,36 @@
import * as React from "react";
import { StatelessComponent } from "react";
-import CommentContainer from "../containers/CommentContainer";
+import Logo from "talk-stream/components/Logo";
+import CommentContainer from "talk-stream/containers/CommentContainer";
+import PostCommentFormContainer from "talk-stream/containers/PostCommentFormContainer";
+import { Button } from "talk-ui/components";
export interface StreamProps {
- comments: ReadonlyArray<{ id: string }>;
+ id: string;
+ isClosed: boolean;
+ comments: ReadonlyArray<{ id: string }> | null;
+ onLoadMore: () => void;
+ hasMore: boolean;
}
const Stream: StatelessComponent = props => {
+ if (props.comments === null) {
+ // TODO: (@cvle) What's the reason for this being null?
+ return Comments unavailable
;
+ }
return (
+
+
{props.comments.map(comment => (
))}
+ {props.hasMore && (
+
+ )}
);
};
diff --git a/src/core/client/stream/containers/AppContainer.tsx b/src/core/client/stream/containers/AppContainer.tsx
index 02abbf314..256d860b4 100644
--- a/src/core/client/stream/containers/AppContainer.tsx
+++ b/src/core/client/stream/containers/AppContainer.tsx
@@ -26,11 +26,7 @@ const enhanced = withFragmentContainer<{ data: Data }>(
...AssetListContainer_assets
}
asset(id: $assetID) @skip(if: $showAssetList) {
- id
- isClosed
- comments {
- ...StreamContainer_comments
- }
+ ...StreamContainer_asset
}
}
`
diff --git a/src/core/client/stream/containers/PostCommentFormContainer.tsx b/src/core/client/stream/containers/PostCommentFormContainer.tsx
index d2da26f64..bf4ab8cf9 100644
--- a/src/core/client/stream/containers/PostCommentFormContainer.tsx
+++ b/src/core/client/stream/containers/PostCommentFormContainer.tsx
@@ -25,6 +25,8 @@ class PostCommentFormContainer extends Component {
if (error instanceof BadUserInputError) {
return error.invalidArgsLocalized;
}
+ // tslint:disable-next-line:no-console
+ console.error(error);
}
return undefined;
};
diff --git a/src/core/client/stream/containers/StreamContainer.tsx b/src/core/client/stream/containers/StreamContainer.tsx
index 771c25efa..8660dc7bb 100644
--- a/src/core/client/stream/containers/StreamContainer.tsx
+++ b/src/core/client/stream/containers/StreamContainer.tsx
@@ -1,32 +1,108 @@
-import React, { StatelessComponent } from "react";
-import { graphql } from "react-relay";
+import React from "react";
+import { graphql, RelayPaginationProp } from "react-relay";
-import { withFragmentContainer } from "talk-framework/lib/relay";
+import { withPaginationContainer } from "talk-framework/lib/relay";
import { PropTypesOf } from "talk-framework/types";
-import { StreamContainer_comments as Data } from "talk-stream/__generated__/StreamContainer_comments.graphql";
+import { StreamContainer_asset as Data } from "talk-stream/__generated__/StreamContainer_asset.graphql";
import Stream from "../components/Stream";
interface InnerProps {
- comments: Data;
+ asset: Data;
+ relay: RelayPaginationProp;
}
-const StreamContainer: StatelessComponent = props => {
- const comments = props.comments.edges.map(edge => edge.node);
- return ;
-};
+class StreamContainer extends React.Component {
+ public render() {
+ const comments = this.props.asset.comments
+ ? this.props.asset.comments.edges.map(edge => edge.node)
+ : null;
+ return (
+
+ );
+ }
-const enhanced = withFragmentContainer<{ comments: Data }>(
+ private loadMore = () => {
+ if (!this.props.relay.hasMore() || this.props.relay.isLoading()) {
+ return;
+ }
+
+ this.props.relay.loadMore(
+ 10, // Fetch the next 10 feed items
+ error => {
+ if (error) {
+ // tslint:disable-next-line:no-console
+ console.error(error);
+ }
+ }
+ );
+ };
+}
+
+const enhanced = withPaginationContainer<{ asset: Data }, InnerProps>(
graphql`
- fragment StreamContainer_comments on CommentsConnection {
- edges {
- node {
- id
- ...CommentContainer
+ fragment StreamContainer_asset on Asset
+ @argumentDefinitions(
+ count: { type: "Int", defaultValue: 5 }
+ cursor: { type: "Cursor" }
+ orderBy: { type: "COMMENT_SORT", defaultValue: CREATED_AT_DESC }
+ ) {
+ id
+ isClosed
+ comments(first: $count, after: $cursor, orderBy: $orderBy)
+ @connection(key: "Stream_comments") {
+ edges {
+ node {
+ id
+ ...CommentContainer
+ }
}
}
}
- `
+ `,
+ {
+ direction: "forward",
+ getConnectionFromProps(props) {
+ return props.asset && props.asset.comments;
+ },
+ // This is also the default implementation of `getFragmentVariables` if it isn't provided.
+ getFragmentVariables(prevVars, totalCount) {
+ return {
+ ...prevVars,
+ count: totalCount,
+ };
+ },
+ getVariables(props, { count, cursor }, fragmentVariables) {
+ return {
+ count,
+ cursor,
+ orderBy: fragmentVariables.orderBy,
+ // assetID isn't specified as an @argument for the fragment, but it should be a
+ // variable available for the fragment under the query root.
+ assetID: props.asset.id,
+ };
+ },
+ query: graphql`
+ # Pagination query to be fetched upon calling 'loadMore'.
+ # Notice that we re-use our fragment, and the shape of this query matches our fragment spec.
+ query StreamContainerPaginationQuery(
+ $count: Int!
+ $cursor: Cursor
+ $orderBy: COMMENT_SORT!
+ $assetID: ID!
+ ) {
+ asset(id: $assetID) {
+ ...StreamContainer_asset
+ @arguments(count: $count, cursor: $cursor, orderBy: $orderBy)
+ }
+ }
+ `,
+ }
)(StreamContainer);
export type StreamContainerProps = PropTypesOf;
diff --git a/src/core/server/graph/tenant/schema/schema.graphql b/src/core/server/graph/tenant/schema/schema.graphql
index eb060b6a4..b3bfb94eb 100644
--- a/src/core/server/graph/tenant/schema/schema.graphql
+++ b/src/core/server/graph/tenant/schema/schema.graphql
@@ -232,7 +232,10 @@ type PageInfo {
"""
Indicates that there are more nodes after this subset.
"""
- hasNextPage: Boolean!
+ hasNextPage: Boolean
+ hasPreviousPage: Boolean
+ startCursor: Cursor
+ endCursor: Cursor
}
"""
diff --git a/src/core/server/models/comment.ts b/src/core/server/models/comment.ts
index 81d046159..ca20647a5 100644
--- a/src/core/server/models/comment.ts
+++ b/src/core/server/models/comment.ts
@@ -280,6 +280,7 @@ async function retrieveConnection(
edges,
pageInfo: {
hasNextPage,
+ endCursor: (nodes.length && nodes[nodes.length - 1].created_at) || null,
},
};
diff --git a/src/core/server/models/connection.ts b/src/core/server/models/connection.ts
index 9ed8cac2b..cc69d1f2c 100644
--- a/src/core/server/models/connection.ts
+++ b/src/core/server/models/connection.ts
@@ -7,6 +7,7 @@ export interface Edge {
export interface PageInfo {
hasNextPage: boolean;
+ endCursor: Cursor;
}
export interface Connection {
From 9f79ee1c6da9e9f5d1acce21111bc34d8e6dbe37 Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Wed, 4 Jul 2018 15:01:47 -0300
Subject: [PATCH 02/42] Better relay types
---
.../lib/relay/withFragmentContainer.ts | 2 +-
.../lib/relay/withLocalStateContainer.tsx | 11 ++++--
.../lib/relay/withPaginationContainer.ts | 2 +-
.../lib/relay/withRefetchContainer.ts | 2 +-
.../client/stream/containers/AppContainer.tsx | 8 ++---
.../stream/containers/AssetListContainer.tsx | 8 ++---
.../stream/containers/CommentContainer.tsx | 8 ++---
.../stream/containers/StreamContainer.tsx | 36 ++++++++++---------
8 files changed, 42 insertions(+), 35 deletions(-)
diff --git a/src/core/client/framework/lib/relay/withFragmentContainer.ts b/src/core/client/framework/lib/relay/withFragmentContainer.ts
index c4636fe3c..2541b2001 100644
--- a/src/core/client/framework/lib/relay/withFragmentContainer.ts
+++ b/src/core/client/framework/lib/relay/withFragmentContainer.ts
@@ -6,7 +6,7 @@ import { InferableComponentEnhancerWithProps } from "recompose";
* from Relay.
*/
export default (
- fragmentSpec: GraphQLTaggedNode
+ fragmentSpec: { [P in keyof T]: GraphQLTaggedNode }
): InferableComponentEnhancerWithProps => (
component: React.ComponentType
) => createFragmentContainer(component, fragmentSpec) as any;
diff --git a/src/core/client/framework/lib/relay/withLocalStateContainer.tsx b/src/core/client/framework/lib/relay/withLocalStateContainer.tsx
index d08aa5d55..9de4180bb 100644
--- a/src/core/client/framework/lib/relay/withLocalStateContainer.tsx
+++ b/src/core/client/framework/lib/relay/withLocalStateContainer.tsx
@@ -1,6 +1,11 @@
import * as React from "react";
import { compose, hoistStatics, InferableComponentEnhancer } from "recompose";
-import { CSelector, CSnapshot, Environment } from "relay-runtime";
+import {
+ CSelector,
+ CSnapshot,
+ Environment,
+ GraphQLTaggedNode,
+} from "relay-runtime";
import { withContext } from "../bootstrap";
@@ -25,7 +30,7 @@ export const LOCAL_ID = "client:root.local";
* must have the `LOCAL_ID`.
*/
function withLocalStateContainer(
- fragmentSpec: any
+ fragmentSpec: GraphQLTaggedNode
): InferableComponentEnhancer<{ local: T }> {
return compose(
withContext(({ relayEnvironment }) => ({ relayEnvironment })),
@@ -33,7 +38,7 @@ function withLocalStateContainer(
class LocalStateContainer extends React.Component {
constructor(props: Props) {
super(props);
- const fragment = fragmentSpec.data().default;
+ const fragment = (fragmentSpec as any).data().default;
if (fragment.kind !== "Fragment") {
throw new Error("Expected fragment");
}
diff --git a/src/core/client/framework/lib/relay/withPaginationContainer.ts b/src/core/client/framework/lib/relay/withPaginationContainer.ts
index 9c669123b..a5d8e1231 100644
--- a/src/core/client/framework/lib/relay/withPaginationContainer.ts
+++ b/src/core/client/framework/lib/relay/withPaginationContainer.ts
@@ -24,7 +24,7 @@ type ConnectionConfig = Overwrite<
* from Relay.
*/
export default (
- fragmentSpec: GraphQLTaggedNode,
+ fragmentSpec: { [P in keyof T]: GraphQLTaggedNode },
connectionConfig: ConnectionConfig
): InferableComponentEnhancerWithProps<
T & { relay: RelayPaginationProp },
diff --git a/src/core/client/framework/lib/relay/withRefetchContainer.ts b/src/core/client/framework/lib/relay/withRefetchContainer.ts
index 7d11e0e16..9e9989758 100644
--- a/src/core/client/framework/lib/relay/withRefetchContainer.ts
+++ b/src/core/client/framework/lib/relay/withRefetchContainer.ts
@@ -10,7 +10,7 @@ import { InferableComponentEnhancerWithProps } from "recompose";
* from Relay.
*/
export default (
- fragmentSpec: GraphQLTaggedNode,
+ fragmentSpec: { [P in keyof T]: GraphQLTaggedNode },
refetchQuery: GraphQLTaggedNode
): InferableComponentEnhancerWithProps<
T & { relay: RelayRefetchProp },
diff --git a/src/core/client/stream/containers/AppContainer.tsx b/src/core/client/stream/containers/AppContainer.tsx
index 256d860b4..89acdea38 100644
--- a/src/core/client/stream/containers/AppContainer.tsx
+++ b/src/core/client/stream/containers/AppContainer.tsx
@@ -15,8 +15,8 @@ const AppContainer: StatelessComponent = props => {
return ;
};
-const enhanced = withFragmentContainer<{ data: Data }>(
- graphql`
+const enhanced = withFragmentContainer<{ data: Data }>({
+ data: graphql`
fragment AppContainer on Query
@argumentDefinitions(
assetID: { type: "ID!" }
@@ -29,8 +29,8 @@ const enhanced = withFragmentContainer<{ data: Data }>(
...StreamContainer_asset
}
}
- `
-)(AppContainer);
+ `,
+})(AppContainer);
export type AppContainerProps = PropTypesOf;
export default enhanced;
diff --git a/src/core/client/stream/containers/AssetListContainer.tsx b/src/core/client/stream/containers/AssetListContainer.tsx
index 6e441f00e..42345cc16 100644
--- a/src/core/client/stream/containers/AssetListContainer.tsx
+++ b/src/core/client/stream/containers/AssetListContainer.tsx
@@ -16,8 +16,8 @@ const AssetListContainer: StatelessComponent = props => {
return ;
};
-const enhanced = withFragmentContainer<{ assets: Data }>(
- graphql`
+const enhanced = withFragmentContainer<{ assets: Data }>({
+ assets: graphql`
fragment AssetListContainer_assets on AssetsConnection {
edges {
node {
@@ -26,8 +26,8 @@ const enhanced = withFragmentContainer<{ assets: Data }>(
}
}
}
- `
-)(AssetListContainer);
+ `,
+})(AssetListContainer);
export type AssetListContainerProps = PropTypesOf;
export default enhanced;
diff --git a/src/core/client/stream/containers/CommentContainer.tsx b/src/core/client/stream/containers/CommentContainer.tsx
index 9a4d03cd8..e80793e49 100644
--- a/src/core/client/stream/containers/CommentContainer.tsx
+++ b/src/core/client/stream/containers/CommentContainer.tsx
@@ -14,16 +14,16 @@ const CommentContainer: StatelessComponent = props => {
return ;
};
-const enhanced = withFragmentContainer<{ data: Data }>(
- graphql`
+const enhanced = withFragmentContainer<{ data: Data }>({
+ data: graphql`
fragment CommentContainer on Comment {
author {
username
}
body
}
- `
-)(CommentContainer);
+ `,
+})(CommentContainer);
export type CommentContainerProps = PropTypesOf;
export default enhanced;
diff --git a/src/core/client/stream/containers/StreamContainer.tsx b/src/core/client/stream/containers/StreamContainer.tsx
index 8660dc7bb..2ef8d72b5 100644
--- a/src/core/client/stream/containers/StreamContainer.tsx
+++ b/src/core/client/stream/containers/StreamContainer.tsx
@@ -45,26 +45,28 @@ class StreamContainer extends React.Component {
}
const enhanced = withPaginationContainer<{ asset: Data }, InnerProps>(
- graphql`
- fragment StreamContainer_asset on Asset
- @argumentDefinitions(
- count: { type: "Int", defaultValue: 5 }
- cursor: { type: "Cursor" }
- orderBy: { type: "COMMENT_SORT", defaultValue: CREATED_AT_DESC }
- ) {
- id
- isClosed
- comments(first: $count, after: $cursor, orderBy: $orderBy)
- @connection(key: "Stream_comments") {
- edges {
- node {
- id
- ...CommentContainer
+ {
+ asset: graphql`
+ fragment StreamContainer_asset on Asset
+ @argumentDefinitions(
+ count: { type: "Int", defaultValue: 5 }
+ cursor: { type: "Cursor" }
+ orderBy: { type: "COMMENT_SORT", defaultValue: CREATED_AT_DESC }
+ ) {
+ id
+ isClosed
+ comments(first: $count, after: $cursor, orderBy: $orderBy)
+ @connection(key: "Stream_comments") {
+ edges {
+ node {
+ id
+ ...CommentContainer
+ }
}
}
}
- }
- `,
+ `,
+ },
{
direction: "forward",
getConnectionFromProps(props) {
From 94588951d3ed5efda25e2950350effb7442a2922 Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Wed, 4 Jul 2018 17:16:51 -0300
Subject: [PATCH 03/42] Cleanup Relay Types
---
package-lock.json | 11 ++------
package.json | 2 +-
.../framework/lib/relay/QueryRenderer.tsx | 28 ++++++++-----------
.../lib/relay/withPaginationContainer.ts | 15 +---------
.../stream/containers/StreamContainer.tsx | 4 +--
src/core/client/stream/queries/AppQuery.tsx | 2 +-
6 files changed, 19 insertions(+), 43 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 6038504da..ad599b648 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1628,14 +1628,9 @@
}
},
"@types/react-relay": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/@types/react-relay/-/react-relay-1.3.6.tgz",
- "integrity": "sha512-X0qv3nGlE4TStFLLKxgj+6MgHZEExB1N/RDcVcyCauAojV5byD0c6VhuqAluYaTKaL2FBuxdtDL405IhIIjEbQ==",
- "dev": true,
- "requires": {
- "@types/react": "*",
- "@types/relay-runtime": "*"
- }
+ "version": "github:coralproject/patched#ba4c8d01bb737e5f073534b32d870294e39cc5a8",
+ "from": "github:coralproject/patched#types/react-relay",
+ "dev": true
},
"@types/recompose": {
"version": "0.26.1",
diff --git a/package.json b/package.json
index 707d65836..c6f02b53d 100644
--- a/package.json
+++ b/package.json
@@ -72,7 +72,7 @@
"@types/passport": "^0.4.5",
"@types/query-string": "^6.1.0",
"@types/react-dom": "^16.0.6",
- "@types/react-relay": "^1.3.6",
+ "@types/react-relay": "github:coralproject/patched#types/react-relay",
"@types/recompose": "^0.26.1",
"@types/relay-runtime": "github:coralproject/patched#types/relay-runtime",
"@types/uuid": "^3.4.3",
diff --git a/src/core/client/framework/lib/relay/QueryRenderer.tsx b/src/core/client/framework/lib/relay/QueryRenderer.tsx
index 30a42dbe0..a5845c0b6 100644
--- a/src/core/client/framework/lib/relay/QueryRenderer.tsx
+++ b/src/core/client/framework/lib/relay/QueryRenderer.tsx
@@ -1,24 +1,18 @@
import React, { Component } from "react";
-import { QueryRenderer } from "react-relay";
-import { CacheConfig, GraphQLTaggedNode, RerunParam } from "relay-runtime";
+import {
+ QueryRenderer,
+ QueryRendererProps as QueryRendererPropsOrig,
+} from "react-relay";
+
+import { Omit } from "talk-framework/types";
import { TalkContextConsumer } from "../bootstrap/TalkContext";
-// Taken from relay types and added Generic support for Variables and Response
-export interface QueryRendererProps {
- cacheConfig?: CacheConfig;
- query?: GraphQLTaggedNode | null;
- render(readyState: ReadyState): React.ReactElement | undefined | null;
- variables: V;
- rerunParamExperimental?: RerunParam;
-}
-
-// Taken from relay types and added Generic support for Variables and Response
-export interface ReadyState {
- error: Error | undefined | null;
- props: R | undefined | null;
- retry?(): void;
-}
+// Omit environment as we are passing this from the context.
+export type QueryRendererProps = Omit<
+ QueryRendererPropsOrig,
+ "environment"
+>;
/**
* TalkQueryRenderer is a wrappper around Relay's `QueryRenderer`.
diff --git a/src/core/client/framework/lib/relay/withPaginationContainer.ts b/src/core/client/framework/lib/relay/withPaginationContainer.ts
index a5d8e1231..0d01887b5 100644
--- a/src/core/client/framework/lib/relay/withPaginationContainer.ts
+++ b/src/core/client/framework/lib/relay/withPaginationContainer.ts
@@ -1,23 +1,10 @@
import {
- ConnectionConfig as OrigConnectionConfig,
+ ConnectionConfig,
createPaginationContainer,
GraphQLTaggedNode,
- PageInfo,
RelayPaginationProp,
} from "react-relay";
import { InferableComponentEnhancerWithProps } from "recompose";
-import { Overwrite } from "talk-framework/types";
-
-// TODO: (cvle) Fix this type definition upstream.
-interface ConnectionData {
- edges?: Readonly;
- pageInfo?: PageInfo;
-}
-
-type ConnectionConfig = Overwrite<
- OrigConnectionConfig,
- { getConnectionFromProps?(props: T): ConnectionData | undefined | null }
->;
/**
* withPaginationContainer is a curried version of `createPaginationContainers`
diff --git a/src/core/client/stream/containers/StreamContainer.tsx b/src/core/client/stream/containers/StreamContainer.tsx
index 2ef8d72b5..63920a410 100644
--- a/src/core/client/stream/containers/StreamContainer.tsx
+++ b/src/core/client/stream/containers/StreamContainer.tsx
@@ -49,9 +49,9 @@ const enhanced = withPaginationContainer<{ asset: Data }, InnerProps>(
asset: graphql`
fragment StreamContainer_asset on Asset
@argumentDefinitions(
- count: { type: "Int", defaultValue: 5 }
+ count: { type: "Int!", defaultValue: 5 }
cursor: { type: "Cursor" }
- orderBy: { type: "COMMENT_SORT", defaultValue: CREATED_AT_DESC }
+ orderBy: { type: "COMMENT_SORT!", defaultValue: CREATED_AT_DESC }
) {
id
isClosed
diff --git a/src/core/client/stream/queries/AppQuery.tsx b/src/core/client/stream/queries/AppQuery.tsx
index 4dc61115c..96d260568 100644
--- a/src/core/client/stream/queries/AppQuery.tsx
+++ b/src/core/client/stream/queries/AppQuery.tsx
@@ -1,10 +1,10 @@
import * as React from "react";
import { StatelessComponent } from "react";
+import { ReadyState } from "react-relay";
import {
graphql,
QueryRenderer,
- ReadyState,
withLocalStateContainer,
} from "talk-framework/lib/relay";
import {
From 67790ac9e1ac1fe84f4dc453c1c7d130b44979a3 Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Wed, 4 Jul 2018 17:24:05 -0300
Subject: [PATCH 04/42] Strict typing for pagination container
---
.../lib/relay/withPaginationContainer.ts | 8 ++++++--
.../stream/containers/StreamContainer.tsx | 18 +++++++++++++++++-
2 files changed, 23 insertions(+), 3 deletions(-)
diff --git a/src/core/client/framework/lib/relay/withPaginationContainer.ts b/src/core/client/framework/lib/relay/withPaginationContainer.ts
index 0d01887b5..bb2740d01 100644
--- a/src/core/client/framework/lib/relay/withPaginationContainer.ts
+++ b/src/core/client/framework/lib/relay/withPaginationContainer.ts
@@ -10,9 +10,13 @@ import { InferableComponentEnhancerWithProps } from "recompose";
* withPaginationContainer is a curried version of `createPaginationContainers`
* from Relay.
*/
-export default (
+export default (
fragmentSpec: { [P in keyof T]: GraphQLTaggedNode },
- connectionConfig: ConnectionConfig
+ connectionConfig: ConnectionConfig<
+ InnerProps,
+ FragmentVariables,
+ QueryVariables
+ >
): InferableComponentEnhancerWithProps<
T & { relay: RelayPaginationProp },
{ [P in keyof T]: any }
diff --git a/src/core/client/stream/containers/StreamContainer.tsx b/src/core/client/stream/containers/StreamContainer.tsx
index 63920a410..0a169ad3a 100644
--- a/src/core/client/stream/containers/StreamContainer.tsx
+++ b/src/core/client/stream/containers/StreamContainer.tsx
@@ -4,6 +4,10 @@ import { graphql, RelayPaginationProp } from "react-relay";
import { withPaginationContainer } from "talk-framework/lib/relay";
import { PropTypesOf } from "talk-framework/types";
import { StreamContainer_asset as Data } from "talk-stream/__generated__/StreamContainer_asset.graphql";
+import {
+ COMMENT_SORT,
+ StreamContainerPaginationQueryVariables,
+} from "talk-stream/__generated__/StreamContainerPaginationQuery.graphql";
import Stream from "../components/Stream";
@@ -44,7 +48,19 @@ class StreamContainer extends React.Component {
};
}
-const enhanced = withPaginationContainer<{ asset: Data }, InnerProps>(
+// TODO: (cvle) This should be autogenerated.
+interface FragmentVariables {
+ count: number;
+ cursor?: string;
+ orderBy: COMMENT_SORT;
+}
+
+const enhanced = withPaginationContainer<
+ { asset: Data },
+ InnerProps,
+ FragmentVariables,
+ StreamContainerPaginationQueryVariables
+>(
{
asset: graphql`
fragment StreamContainer_asset on Asset
From bdd4702a8f7b9d0d591f36b5f2af396ef623f39d Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Wed, 4 Jul 2018 17:26:37 -0300
Subject: [PATCH 05/42] Invert and full width
---
src/core/client/stream/components/Stream.tsx | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/core/client/stream/components/Stream.tsx b/src/core/client/stream/components/Stream.tsx
index ccda84eea..454b1f38f 100644
--- a/src/core/client/stream/components/Stream.tsx
+++ b/src/core/client/stream/components/Stream.tsx
@@ -27,7 +27,7 @@ const Stream: StatelessComponent = props => {
))}
{props.hasMore && (
-
-
-
+
- Markus
-
-
- Joining Too
-
+
+ Markus
+
+
+ Joining Too
+
+
-
-
+
- Lukas
-
-
- What's up?
-
+
+ Lukas
+
+
+ What's up?
+
+
+
+
+ Talk NEO
+
+
+
+
+
+ Markus
+
+
+ Joining Too
+
+
+
+
+
+
+ Markus
+
+
+ I like yoghurt
+
+
+
+
+
+ Markus
+
+
+ Joining Too
+
+
+
+
+ Lukas
+
+
+ What's up?
+
+
+
+
+
+
+`;
diff --git a/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap
index 20b7f7b83..c49e46241 100644
--- a/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap
+++ b/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap
@@ -36,33 +36,37 @@ exports[`renders comment stream 1`] = `
-
-
+
- Markus
-
-
- Joining Too
-
+
+ Markus
+
+
+ Joining Too
+
+
-
-
+
- Lukas
-
-
- What's up?
-
+
+ Lukas
+
+
+ What's up?
+
+
diff --git a/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
new file mode 100644
index 000000000..b9acbb5cd
--- /dev/null
+++ b/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
@@ -0,0 +1,181 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders comment stream 1`] = `
+
+
+
+ Talk NEO
+
+
+
+
+
+ Markus
+
+
+ Joining Too
+
+
+
+
+
+ Lukas
+
+
+ What's up?
+
+
+
+
+
+
+
+`;
+
+exports[`show all replies 1`] = `
+
+
+
+ Talk NEO
+
+
+
+
+
+ Markus
+
+
+ Joining Too
+
+
+
+
+
+ Lukas
+
+
+ What's up?
+
+
+
+
+
+
+
+`;
diff --git a/src/core/client/stream/test/createEnvironment.ts b/src/core/client/stream/test/createEnvironment.ts
index 7ad42d9eb..0276c0b4e 100644
--- a/src/core/client/stream/test/createEnvironment.ts
+++ b/src/core/client/stream/test/createEnvironment.ts
@@ -3,7 +3,6 @@ import { createFetch } from "relay-local-schema";
import {
commitLocalUpdate,
Environment,
- FetchFunction,
Network,
RecordProxy,
RecordSource,
diff --git a/src/core/client/stream/test/fixtures.ts b/src/core/client/stream/test/fixtures.ts
index 059f8f716..755adfe37 100644
--- a/src/core/client/stream/test/fixtures.ts
+++ b/src/core/client/stream/test/fixtures.ts
@@ -49,3 +49,33 @@ export const assets = [
},
},
];
+
+export const commentWithReplies = {
+ id: "comment-with-replies",
+ author: users[0],
+ body: "I like yoghurt",
+ createdAt: "2018-07-06T18:24:00",
+ replies: {
+ edges: [
+ { node: comments[0], cursor: comments[0].createdAt },
+ { node: comments[1], cursor: comments[1].createdAt },
+ ],
+ pageInfo: {
+ hasNextPage: false,
+ },
+ },
+};
+
+export const assetWithReplies = {
+ id: "asset-with-replies",
+ isClosed: false,
+ comments: {
+ edges: [
+ { node: comments[0], cursor: comments[0].createdAt },
+ { node: commentWithReplies, cursor: commentWithReplies.createdAt },
+ ],
+ pageInfo: {
+ hasNextPage: false,
+ },
+ },
+};
diff --git a/src/core/client/stream/test/loadMore.spec.tsx b/src/core/client/stream/test/loadMore.spec.tsx
index 9221643a3..2ff3d5a87 100644
--- a/src/core/client/stream/test/loadMore.spec.tsx
+++ b/src/core/client/stream/test/loadMore.spec.tsx
@@ -82,7 +82,7 @@ it("renders comment stream", async () => {
it("loads more comments", async () => {
testRenderer.root
- .findByProps({ id: "talk-stream--loadmore" })
+ .findByProps({ id: "talk-stream--load-more" })
.props.onClick();
// Wait for loading.
diff --git a/src/core/client/stream/test/renderReplies.spec.tsx b/src/core/client/stream/test/renderReplies.spec.tsx
new file mode 100644
index 000000000..359c2465d
--- /dev/null
+++ b/src/core/client/stream/test/renderReplies.spec.tsx
@@ -0,0 +1,42 @@
+import React from "react";
+import TestRenderer from "react-test-renderer";
+import { RecordProxy } from "relay-runtime";
+
+import { timeout } from "talk-common/utils";
+import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
+import AppQuery from "talk-stream/queries/AppQuery";
+
+import createEnvironment from "./createEnvironment";
+import { assetWithReplies } from "./fixtures";
+
+const resolvers = {
+ Query: {
+ asset: () => assetWithReplies,
+ },
+};
+
+const environment = createEnvironment({
+ // Set this to true, to see graphql responses.
+ logNetwork: false,
+ resolvers,
+ initLocalState: (localRecord: RecordProxy) => {
+ localRecord.setValue(assetWithReplies.id, "assetID");
+ },
+});
+
+const context: TalkContext = {
+ relayEnvironment: environment,
+ localeMessages: [],
+};
+
+const testRenderer = TestRenderer.create(
+
+
+
+);
+
+it("renders comment stream", async () => {
+ // Wait for loading.
+ await timeout();
+ expect(testRenderer.toJSON()).toMatchSnapshot();
+});
diff --git a/src/core/client/stream/test/showAllReplies.spec.tsx b/src/core/client/stream/test/showAllReplies.spec.tsx
new file mode 100644
index 000000000..98501d7dc
--- /dev/null
+++ b/src/core/client/stream/test/showAllReplies.spec.tsx
@@ -0,0 +1,100 @@
+import React from "react";
+import TestRenderer from "react-test-renderer";
+import { RecordProxy } from "relay-runtime";
+import sinon from "sinon";
+
+import { timeout } from "talk-common/utils";
+import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
+import AppQuery from "talk-stream/queries/AppQuery";
+
+import createEnvironment from "./createEnvironment";
+import { assets, comments } from "./fixtures";
+
+const assetStub = {
+ ...assets[0],
+ comments: {
+ pageInfo: {
+ hasNextPage: false,
+ },
+ edges: [
+ {
+ node: {
+ ...comments[0],
+ replies: {
+ edges: sinon
+ .stub()
+ .onFirstCall()
+ .returns([
+ {
+ node: comments[1],
+ cursor: comments[1].createdAt,
+ },
+ ])
+ .onSecondCall()
+ .returns([
+ {
+ node: comments[2],
+ cursor: comments[2].createdAt,
+ },
+ ]),
+ pageInfo: sinon
+ .stub()
+ .onFirstCall()
+ .returns({
+ endCursor: comments[1].createdAt,
+ hasNextPage: true,
+ })
+ .onSecondCall()
+ .returns({
+ endCursor: comments[2].createdAt,
+ hasNextPage: false,
+ }),
+ },
+ },
+ cursor: comments[0].createdAt,
+ },
+ ],
+ },
+};
+
+const resolvers = {
+ Query: {
+ asset: () => assetStub,
+ },
+};
+
+const environment = createEnvironment({
+ // Set this to true, to see graphql responses.
+ logNetwork: false,
+ resolvers,
+ initLocalState: (localRecord: RecordProxy) => {
+ localRecord.setValue(assetStub.id, "assetID");
+ },
+});
+
+const context: TalkContext = {
+ relayEnvironment: environment,
+ localeMessages: [],
+};
+
+const testRenderer = TestRenderer.create(
+
+
+
+);
+
+it("renders comment stream", async () => {
+ // Wait for loading.
+ await timeout();
+ expect(testRenderer.toJSON()).toMatchSnapshot();
+});
+
+it("show all replies", async () => {
+ testRenderer.root
+ .findByProps({ id: `talk-reply-list--show-all--${comments[0].id}` })
+ .props.onClick();
+
+ // Wait for loading.
+ await timeout();
+ expect(testRenderer.toJSON()).toMatchSnapshot();
+});
From 11de453aacdba799c90ab6201cdfda85f4a61c3c Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Mon, 9 Jul 2018 17:41:39 -0300
Subject: [PATCH 15/42] Fix showAllReplies test
---
.../showAllReplies.spec.tsx.snap | 22 +++---
.../stream/test/showAllReplies.spec.tsx | 71 ++++++++++---------
2 files changed, 50 insertions(+), 43 deletions(-)
diff --git a/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
index b9acbb5cd..ced8cfb6a 100644
--- a/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
+++ b/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
@@ -164,16 +164,20 @@ exports[`show all replies 1`] = `
What's up?
-
+
+ Isabelle
+
+
+ Hey!
+
+
diff --git a/src/core/client/stream/test/showAllReplies.spec.tsx b/src/core/client/stream/test/showAllReplies.spec.tsx
index 98501d7dc..df7ac1ebb 100644
--- a/src/core/client/stream/test/showAllReplies.spec.tsx
+++ b/src/core/client/stream/test/showAllReplies.spec.tsx
@@ -10,6 +10,40 @@ import AppQuery from "talk-stream/queries/AppQuery";
import createEnvironment from "./createEnvironment";
import { assets, comments } from "./fixtures";
+const commentStub = {
+ ...comments[0],
+ replies: {
+ edges: sinon
+ .stub()
+ .onFirstCall()
+ .returns([
+ {
+ node: comments[1],
+ cursor: comments[1].createdAt,
+ },
+ ])
+ .onSecondCall()
+ .returns([
+ {
+ node: comments[2],
+ cursor: comments[2].createdAt,
+ },
+ ]),
+ pageInfo: sinon
+ .stub()
+ .onFirstCall()
+ .returns({
+ endCursor: comments[1].createdAt,
+ hasNextPage: true,
+ })
+ .onSecondCall()
+ .returns({
+ endCursor: comments[2].createdAt,
+ hasNextPage: false,
+ }),
+ },
+};
+
const assetStub = {
...assets[0],
comments: {
@@ -18,40 +52,8 @@ const assetStub = {
},
edges: [
{
- node: {
- ...comments[0],
- replies: {
- edges: sinon
- .stub()
- .onFirstCall()
- .returns([
- {
- node: comments[1],
- cursor: comments[1].createdAt,
- },
- ])
- .onSecondCall()
- .returns([
- {
- node: comments[2],
- cursor: comments[2].createdAt,
- },
- ]),
- pageInfo: sinon
- .stub()
- .onFirstCall()
- .returns({
- endCursor: comments[1].createdAt,
- hasNextPage: true,
- })
- .onSecondCall()
- .returns({
- endCursor: comments[2].createdAt,
- hasNextPage: false,
- }),
- },
- },
- cursor: comments[0].createdAt,
+ node: commentStub,
+ cursor: commentStub.createdAt,
},
],
},
@@ -59,6 +61,7 @@ const assetStub = {
const resolvers = {
Query: {
+ comment: () => commentStub,
asset: () => assetStub,
},
};
From a18a9ab0c4c615aa2a54c6a84453e7243d971854 Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Mon, 9 Jul 2018 20:55:36 -0300
Subject: [PATCH 16/42] Narrow down arguments in stub
---
src/core/client/stream/test/loadMore.spec.tsx | 76 ++++++++++---------
.../client/stream/test/renderReplies.spec.tsx | 6 +-
.../client/stream/test/renderStream.spec.tsx | 6 +-
.../stream/test/showAllReplies.spec.tsx | 73 ++++++++++--------
4 files changed, 92 insertions(+), 69 deletions(-)
diff --git a/src/core/client/stream/test/loadMore.spec.tsx b/src/core/client/stream/test/loadMore.spec.tsx
index 2ff3d5a87..0971e899e 100644
--- a/src/core/client/stream/test/loadMore.spec.tsx
+++ b/src/core/client/stream/test/loadMore.spec.tsx
@@ -10,47 +10,53 @@ import AppQuery from "talk-stream/queries/AppQuery";
import createEnvironment from "./createEnvironment";
import { assets, comments } from "./fixtures";
+const connectionStub = sinon.stub();
+connectionStub.withArgs({ first: 5, orderBy: "CREATED_AT_DESC" }).returns({
+ edges: [
+ {
+ node: comments[0],
+ cursor: comments[0].createdAt,
+ },
+ {
+ node: comments[1],
+ cursor: comments[1].createdAt,
+ },
+ ],
+ pageInfo: {
+ endCursor: comments[1].createdAt,
+ hasNextPage: true,
+ },
+});
+connectionStub
+ .withArgs({
+ first: 10,
+ orderBy: "CREATED_AT_DESC",
+ after: comments[1].createdAt,
+ })
+ .returns({
+ edges: [
+ {
+ node: comments[2],
+ cursor: comments[2].createdAt,
+ },
+ ],
+ pageInfo: {
+ endCursor: comments[2].createdAt,
+ hasNextPage: false,
+ },
+ });
+
const assetStub = {
...assets[0],
- comments: {
- edges: sinon
- .stub()
- .onFirstCall()
- .returns([
- {
- node: comments[0],
- cursor: comments[0].createdAt,
- },
- {
- node: comments[1],
- cursor: comments[1].createdAt,
- },
- ])
- .onSecondCall()
- .returns([
- {
- node: comments[2],
- cursor: comments[2].createdAt,
- },
- ]),
- pageInfo: sinon
- .stub()
- .onFirstCall()
- .returns({
- endCursor: comments[1].createdAt,
- hasNextPage: true,
- })
- .onSecondCall()
- .returns({
- endCursor: comments[2].createdAt,
- hasNextPage: false,
- }),
- },
+ comments: connectionStub,
};
const resolvers = {
Query: {
- asset: () => assetStub,
+ asset: sinon
+ .stub()
+ .withArgs(undefined, { id: assetStub.id })
+ .returns(assetStub),
},
};
diff --git a/src/core/client/stream/test/renderReplies.spec.tsx b/src/core/client/stream/test/renderReplies.spec.tsx
index 359c2465d..b1d6b43c2 100644
--- a/src/core/client/stream/test/renderReplies.spec.tsx
+++ b/src/core/client/stream/test/renderReplies.spec.tsx
@@ -1,6 +1,7 @@
import React from "react";
import TestRenderer from "react-test-renderer";
import { RecordProxy } from "relay-runtime";
+import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
@@ -11,7 +12,10 @@ import { assetWithReplies } from "./fixtures";
const resolvers = {
Query: {
- asset: () => assetWithReplies,
+ asset: sinon
+ .stub()
+ .withArgs(undefined, { id: assetWithReplies.id })
+ .returns(assetWithReplies),
},
};
diff --git a/src/core/client/stream/test/renderStream.spec.tsx b/src/core/client/stream/test/renderStream.spec.tsx
index d30e32d51..c5027bd7f 100644
--- a/src/core/client/stream/test/renderStream.spec.tsx
+++ b/src/core/client/stream/test/renderStream.spec.tsx
@@ -1,6 +1,7 @@
import React from "react";
import TestRenderer from "react-test-renderer";
import { RecordProxy } from "relay-runtime";
+import sinon from "sinon";
import { timeout } from "talk-common/utils";
import { TalkContext, TalkContextProvider } from "talk-framework/lib/bootstrap";
@@ -11,7 +12,10 @@ import { assets } from "./fixtures";
const resolvers = {
Query: {
- asset: () => assets[0],
+ asset: sinon
+ .stub()
+ .withArgs(undefined, { id: assets[0].id })
+ .returns(assets[0]),
},
};
diff --git a/src/core/client/stream/test/showAllReplies.spec.tsx b/src/core/client/stream/test/showAllReplies.spec.tsx
index df7ac1ebb..665679b76 100644
--- a/src/core/client/stream/test/showAllReplies.spec.tsx
+++ b/src/core/client/stream/test/showAllReplies.spec.tsx
@@ -10,38 +10,41 @@ import AppQuery from "talk-stream/queries/AppQuery";
import createEnvironment from "./createEnvironment";
import { assets, comments } from "./fixtures";
+const connectionStub = sinon.stub();
+connectionStub.withArgs({ first: 5, orderBy: "CREATED_AT_ASC" }).returns({
+ edges: [
+ {
+ node: comments[1],
+ cursor: comments[1].createdAt,
+ },
+ ],
+ pageInfo: {
+ endCursor: comments[1].createdAt,
+ hasNextPage: true,
+ },
+});
+connectionStub
+ .withArgs({
+ first: sinon.match(n => n > 10000),
+ orderBy: "CREATED_AT_ASC",
+ after: comments[1].createdAt,
+ })
+ .returns({
+ edges: [
+ {
+ node: comments[2],
+ cursor: comments[2].createdAt,
+ },
+ ],
+ pageInfo: {
+ endCursor: comments[2].createdAt,
+ hasNextPage: false,
+ },
+ });
+
const commentStub = {
...comments[0],
- replies: {
- edges: sinon
- .stub()
- .onFirstCall()
- .returns([
- {
- node: comments[1],
- cursor: comments[1].createdAt,
- },
- ])
- .onSecondCall()
- .returns([
- {
- node: comments[2],
- cursor: comments[2].createdAt,
- },
- ]),
- pageInfo: sinon
- .stub()
- .onFirstCall()
- .returns({
- endCursor: comments[1].createdAt,
- hasNextPage: true,
- })
- .onSecondCall()
- .returns({
- endCursor: comments[2].createdAt,
- hasNextPage: false,
- }),
- },
+ replies: connectionStub,
};
const assetStub = {
@@ -61,8 +64,14 @@ const assetStub = {
const resolvers = {
Query: {
- comment: () => commentStub,
- asset: () => assetStub,
+ comment: sinon
+ .stub()
+ .withArgs(undefined, { id: commentStub.id })
+ .returns(commentStub),
+ asset: sinon
+ .stub()
+ .withArgs(undefined, { id: assetStub.id })
+ .returns(assetStub),
},
};
From ca12ec652d69b65f573916436aeaa9cec26815da Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Mon, 9 Jul 2018 21:01:45 -0300
Subject: [PATCH 17/42] Throw when wrong args are provided
---
src/core/client/stream/test/loadMore.spec.tsx | 3 ++-
src/core/client/stream/test/renderReplies.spec.tsx | 1 +
src/core/client/stream/test/renderStream.spec.tsx | 1 +
src/core/client/stream/test/showAllReplies.spec.tsx | 4 +++-
4 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/core/client/stream/test/loadMore.spec.tsx b/src/core/client/stream/test/loadMore.spec.tsx
index 0971e899e..fdc901f4a 100644
--- a/src/core/client/stream/test/loadMore.spec.tsx
+++ b/src/core/client/stream/test/loadMore.spec.tsx
@@ -10,7 +10,7 @@ import AppQuery from "talk-stream/queries/AppQuery";
import createEnvironment from "./createEnvironment";
import { assets, comments } from "./fixtures";
-const connectionStub = sinon.stub();
+const connectionStub = sinon.stub().throws();
connectionStub.withArgs({ first: 5, orderBy: "CREATED_AT_DESC" }).returns({
edges: [
{
@@ -55,6 +55,7 @@ const resolvers = {
Query: {
asset: sinon
.stub()
+ .throws()
.withArgs(undefined, { id: assetStub.id })
.returns(assetStub),
},
diff --git a/src/core/client/stream/test/renderReplies.spec.tsx b/src/core/client/stream/test/renderReplies.spec.tsx
index b1d6b43c2..9c535520f 100644
--- a/src/core/client/stream/test/renderReplies.spec.tsx
+++ b/src/core/client/stream/test/renderReplies.spec.tsx
@@ -14,6 +14,7 @@ const resolvers = {
Query: {
asset: sinon
.stub()
+ .throws()
.withArgs(undefined, { id: assetWithReplies.id })
.returns(assetWithReplies),
},
diff --git a/src/core/client/stream/test/renderStream.spec.tsx b/src/core/client/stream/test/renderStream.spec.tsx
index c5027bd7f..998058cce 100644
--- a/src/core/client/stream/test/renderStream.spec.tsx
+++ b/src/core/client/stream/test/renderStream.spec.tsx
@@ -14,6 +14,7 @@ const resolvers = {
Query: {
asset: sinon
.stub()
+ .throws()
.withArgs(undefined, { id: assets[0].id })
.returns(assets[0]),
},
diff --git a/src/core/client/stream/test/showAllReplies.spec.tsx b/src/core/client/stream/test/showAllReplies.spec.tsx
index 665679b76..a3802c49e 100644
--- a/src/core/client/stream/test/showAllReplies.spec.tsx
+++ b/src/core/client/stream/test/showAllReplies.spec.tsx
@@ -10,7 +10,7 @@ import AppQuery from "talk-stream/queries/AppQuery";
import createEnvironment from "./createEnvironment";
import { assets, comments } from "./fixtures";
-const connectionStub = sinon.stub();
+const connectionStub = sinon.stub().throws();
connectionStub.withArgs({ first: 5, orderBy: "CREATED_AT_ASC" }).returns({
edges: [
{
@@ -66,10 +66,12 @@ const resolvers = {
Query: {
comment: sinon
.stub()
+ .throws()
.withArgs(undefined, { id: commentStub.id })
.returns(commentStub),
asset: sinon
.stub()
+ .throws()
.withArgs(undefined, { id: assetStub.id })
.returns(assetStub),
},
From d89d4c25b7912ba1092fd9256af922a2a6010503 Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Tue, 10 Jul 2018 12:15:39 -0300
Subject: [PATCH 18/42] Extract Username, Add indent styles
---
src/core/client/stream/components/Comment.css | 4 ---
src/core/client/stream/components/Comment.tsx | 5 ++--
src/core/client/stream/components/Indent.css | 9 +++++++
src/core/client/stream/components/Indent.tsx | 9 +++----
.../client/stream/components/Username.css | 3 +++
.../stream/components/Username.spec.tsx | 12 +++++++++
.../client/stream/components/Username.tsx | 20 ++++++++++++++
.../__snapshots__/Comment.spec.tsx.snap | 14 +++-------
.../__snapshots__/Username.spec.tsx.snap | 10 +++++++
.../test/__snapshots__/loadMore.spec.tsx.snap | 10 +++----
.../__snapshots__/renderReplies.spec.tsx.snap | 16 ++++--------
.../__snapshots__/renderStream.spec.tsx.snap | 4 +--
.../showAllReplies.spec.tsx.snap | 26 +++++--------------
src/core/client/ui/theme/variables.ts | 8 +++---
14 files changed, 87 insertions(+), 63 deletions(-)
create mode 100644 src/core/client/stream/components/Indent.css
create mode 100644 src/core/client/stream/components/Username.css
create mode 100644 src/core/client/stream/components/Username.spec.tsx
create mode 100644 src/core/client/stream/components/Username.tsx
create mode 100644 src/core/client/stream/components/__snapshots__/Username.spec.tsx.snap
diff --git a/src/core/client/stream/components/Comment.css b/src/core/client/stream/components/Comment.css
index d43780d8f..3981c1eee 100644
--- a/src/core/client/stream/components/Comment.css
+++ b/src/core/client/stream/components/Comment.css
@@ -5,7 +5,3 @@
.gutterBottom {
margin-bottom: calc(2px * $spacing-unit);
}
-
-.author {
- font-weight: $font-weight-medium;
-}
diff --git a/src/core/client/stream/components/Comment.tsx b/src/core/client/stream/components/Comment.tsx
index c1b3f9303..2f91166ed 100644
--- a/src/core/client/stream/components/Comment.tsx
+++ b/src/core/client/stream/components/Comment.tsx
@@ -5,6 +5,7 @@ import { StatelessComponent } from "react";
import { Typography } from "talk-ui/components";
import * as styles from "./Comment.css";
+import Username from "./Username";
export interface CommentProps {
className?: string;
@@ -21,9 +22,7 @@ const Comment: StatelessComponent = props => {
});
return (
-
- {props.author && props.author.username}
-
+ {props.author && {props.author.username}}
{props.body}
);
diff --git a/src/core/client/stream/components/Indent.css b/src/core/client/stream/components/Indent.css
new file mode 100644
index 000000000..c8b46961a
--- /dev/null
+++ b/src/core/client/stream/components/Indent.css
@@ -0,0 +1,9 @@
+.root {
+ margin-left: 2px;
+ border-left: 2px solid;
+ padding-left: 5px;
+}
+
+.level0 {
+ border-color: $palette-secondary-darkest;
+}
diff --git a/src/core/client/stream/components/Indent.tsx b/src/core/client/stream/components/Indent.tsx
index 49222acff..7ea8fddf3 100644
--- a/src/core/client/stream/components/Indent.tsx
+++ b/src/core/client/stream/components/Indent.tsx
@@ -1,16 +1,15 @@
+import cn from "classnames";
import React, { StatelessComponent } from "react";
+import * as styles from "./Indent.css";
+
export interface IndentProps {
level?: number;
children: React.ReactNode;
}
const Indent: StatelessComponent = props => {
- return (
-
- {props.children}
-
- );
+ return {props.children}
;
};
export default Indent;
diff --git a/src/core/client/stream/components/Username.css b/src/core/client/stream/components/Username.css
new file mode 100644
index 000000000..5f84423cd
--- /dev/null
+++ b/src/core/client/stream/components/Username.css
@@ -0,0 +1,3 @@
+.root {
+ font-weight: $font-weight-medium;
+}
diff --git a/src/core/client/stream/components/Username.spec.tsx b/src/core/client/stream/components/Username.spec.tsx
new file mode 100644
index 000000000..c4f1c1dfe
--- /dev/null
+++ b/src/core/client/stream/components/Username.spec.tsx
@@ -0,0 +1,12 @@
+import { shallow } from "enzyme";
+import React from "react";
+
+import Username from "./Username";
+
+it("renders correctly", () => {
+ const props = {
+ children: "Marvin",
+ };
+ const wrapper = shallow();
+ expect(wrapper).toMatchSnapshot();
+});
diff --git a/src/core/client/stream/components/Username.tsx b/src/core/client/stream/components/Username.tsx
new file mode 100644
index 000000000..3424e1f62
--- /dev/null
+++ b/src/core/client/stream/components/Username.tsx
@@ -0,0 +1,20 @@
+import React from "react";
+import { StatelessComponent } from "react";
+
+import { Typography } from "talk-ui/components";
+
+import * as styles from "./Username.css";
+
+export interface CommentProps {
+ children: string;
+}
+
+const Username: StatelessComponent = props => {
+ return (
+
+ {props.children}
+
+ );
+};
+
+export default Username;
diff --git a/src/core/client/stream/components/__snapshots__/Comment.spec.tsx.snap b/src/core/client/stream/components/__snapshots__/Comment.spec.tsx.snap
index 4b009e257..ce67dff86 100644
--- a/src/core/client/stream/components/__snapshots__/Comment.spec.tsx.snap
+++ b/src/core/client/stream/components/__snapshots__/Comment.spec.tsx.snap
@@ -4,12 +4,9 @@ exports[`renders username and body 1`] = `
-
+
Marvin
-
+
Woof
@@ -20,12 +17,9 @@ exports[`renders with gutterBottom 1`] = `
-
+
Marvin
-
+
Woof
diff --git a/src/core/client/stream/components/__snapshots__/Username.spec.tsx.snap b/src/core/client/stream/components/__snapshots__/Username.spec.tsx.snap
new file mode 100644
index 000000000..2323b1c31
--- /dev/null
+++ b/src/core/client/stream/components/__snapshots__/Username.spec.tsx.snap
@@ -0,0 +1,10 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`renders correctly 1`] = `
+
+ Marvin
+
+`;
diff --git a/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap
index cbecb8711..b9595be1b 100644
--- a/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap
+++ b/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap
@@ -41,7 +41,7 @@ exports[`loads more comments 1`] = `
className="root gutterBottom"
>
Markus
@@ -57,7 +57,7 @@ exports[`loads more comments 1`] = `
className="root gutterBottom"
>
Lukas
@@ -73,7 +73,7 @@ exports[`loads more comments 1`] = `
className="root gutterBottom"
>
Isabelle
@@ -129,7 +129,7 @@ exports[`renders comment stream 1`] = `
className="root gutterBottom"
>
Markus
@@ -145,7 +145,7 @@ exports[`renders comment stream 1`] = `
className="root gutterBottom"
>
Lukas
diff --git a/src/core/client/stream/test/__snapshots__/renderReplies.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/renderReplies.spec.tsx.snap
index 3e6552967..1dbd60833 100644
--- a/src/core/client/stream/test/__snapshots__/renderReplies.spec.tsx.snap
+++ b/src/core/client/stream/test/__snapshots__/renderReplies.spec.tsx.snap
@@ -41,7 +41,7 @@ exports[`renders comment stream 1`] = `
className="root gutterBottom"
>
Markus
@@ -57,7 +57,7 @@ exports[`renders comment stream 1`] = `
className="root gutterBottom"
>
Markus
@@ -68,19 +68,13 @@ exports[`renders comment stream 1`] = `
Markus
@@ -94,7 +88,7 @@ exports[`renders comment stream 1`] = `
className="root gutterBottom"
>
Lukas
diff --git a/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap
index c49e46241..a7610a65c 100644
--- a/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap
+++ b/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap
@@ -41,7 +41,7 @@ exports[`renders comment stream 1`] = `
className="root gutterBottom"
>
Markus
@@ -57,7 +57,7 @@ exports[`renders comment stream 1`] = `
className="root gutterBottom"
>
Lukas
diff --git a/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
index ced8cfb6a..c744dd323 100644
--- a/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
+++ b/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
@@ -41,7 +41,7 @@ exports[`renders comment stream 1`] = `
className="root gutterBottom"
>
Markus
@@ -52,19 +52,13 @@ exports[`renders comment stream 1`] = `
Lukas
@@ -131,7 +125,7 @@ exports[`show all replies 1`] = `
className="root gutterBottom"
>
Markus
@@ -142,19 +136,13 @@ exports[`show all replies 1`] = `
Lukas
@@ -168,7 +156,7 @@ exports[`show all replies 1`] = `
className="root gutterBottom"
>
Isabelle
diff --git a/src/core/client/ui/theme/variables.ts b/src/core/client/ui/theme/variables.ts
index dc5fd9ed7..4c4a54332 100644
--- a/src/core/client/ui/theme/variables.ts
+++ b/src/core/client/ui/theme/variables.ts
@@ -7,7 +7,7 @@ const variables = {
palette: {
/* Primary colors */
primary: {
- darker: "#0D5B8F",
+ darkest: "#0D5B8F",
dark: "#2B7EB5",
main: "#3498DB",
light: "#67B2E4",
@@ -15,7 +15,7 @@ const variables = {
},
/* Secondary colors */
secondary: {
- darker: "#404345",
+ darkest: "#404345",
dark: "#65696B",
main: "#787D80",
light: "#9A9DA0",
@@ -23,7 +23,7 @@ const variables = {
},
/* Success colors */
success: {
- darker: "#03AB61",
+ darkest: "#03AB61",
dark: "#02BD6B",
main: "#00CD73",
light: "#40D996",
@@ -31,7 +31,7 @@ const variables = {
},
/* Error colors */
error: {
- darker: "#F50F0C",
+ darkest: "#F50F0C",
dark: "#FF1F1C",
main: "#FA4643",
light: "#F26563",
From 86906464099b087f55233a4a254641887347273e Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Tue, 10 Jul 2018 12:29:42 -0300
Subject: [PATCH 19/42] Better css classnames in snapshots
---
config/jest/cssTransform.js | 13 ++++-
.../__snapshots__/Comment.spec.tsx.snap | 4 +-
.../__snapshots__/Username.spec.tsx.snap | 2 +-
.../test/__snapshots__/loadMore.spec.tsx.snap | 52 ++++++++---------
.../__snapshots__/renderReplies.spec.tsx.snap | 36 ++++++------
.../__snapshots__/renderStream.spec.tsx.snap | 22 ++++----
.../showAllReplies.spec.tsx.snap | 56 +++++++++----------
7 files changed, 97 insertions(+), 88 deletions(-)
diff --git a/config/jest/cssTransform.js b/config/jest/cssTransform.js
index 90b6bfa63..ca4c0c0ee 100644
--- a/config/jest/cssTransform.js
+++ b/config/jest/cssTransform.js
@@ -4,7 +4,7 @@
// Copyright https://github.com/Connormiha/jest-css-modules-transform/graphs/contributors
// This oututs `module.exports = cssObject` instead of `module.exports = { default: cssObject }`;
-const { sep: pathSep, resolve } = require("path");
+const { sep: pathSep, resolve, basename, extname } = require("path");
const postcss = require("postcss");
const postcssNested = postcss([require("postcss-nested")]);
@@ -88,7 +88,16 @@ module.exports = {
process(src, path, config) {
const filename = path.slice(path.lastIndexOf(pathSep) + 1);
const textCSS = postcssNested.process(src).css;
- const exprt = JSON.stringify(getCSSSelectors(textCSS, path));
+ const selectors = getCSSSelectors(textCSS, path);
+ const component = basename(path, extname(path));
+
+ Object.keys(selectors).forEach(k => {
+ selectors[k] = selectors[k]
+ .split(/\s+/)
+ .map(v => `${component}-${v}`)
+ .join(" ");
+ });
+ const exprt = JSON.stringify(selectors);
return `module.exports = ${exprt}`;
},
};
diff --git a/src/core/client/stream/components/__snapshots__/Comment.spec.tsx.snap b/src/core/client/stream/components/__snapshots__/Comment.spec.tsx.snap
index ce67dff86..48a1c0464 100644
--- a/src/core/client/stream/components/__snapshots__/Comment.spec.tsx.snap
+++ b/src/core/client/stream/components/__snapshots__/Comment.spec.tsx.snap
@@ -2,7 +2,7 @@
exports[`renders username and body 1`] = `
Marvin
@@ -15,7 +15,7 @@ exports[`renders username and body 1`] = `
exports[`renders with gutterBottom 1`] = `
Marvin
diff --git a/src/core/client/stream/components/__snapshots__/Username.spec.tsx.snap b/src/core/client/stream/components/__snapshots__/Username.spec.tsx.snap
index 2323b1c31..187895843 100644
--- a/src/core/client/stream/components/__snapshots__/Username.spec.tsx.snap
+++ b/src/core/client/stream/components/__snapshots__/Username.spec.tsx.snap
@@ -2,7 +2,7 @@
exports[`renders correctly 1`] = `
Marvin
diff --git a/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap
index b9595be1b..e349723c8 100644
--- a/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap
+++ b/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap
@@ -2,11 +2,11 @@
exports[`loads more comments 1`] = `
Talk NEO
@@ -16,17 +16,17 @@ exports[`loads more comments 1`] = `
>
Markus
Joining Too
@@ -54,15 +54,15 @@ exports[`loads more comments 1`] = `
Lukas
What's up?
@@ -70,15 +70,15 @@ exports[`loads more comments 1`] = `
Isabelle
Hey!
@@ -90,11 +90,11 @@ exports[`loads more comments 1`] = `
exports[`renders comment stream 1`] = `
Talk NEO
@@ -104,17 +104,17 @@ exports[`renders comment stream 1`] = `
>
Markus
Joining Too
@@ -142,22 +142,22 @@ exports[`renders comment stream 1`] = `
Talk NEO
@@ -16,17 +16,17 @@ exports[`renders comment stream 1`] = `
>
Markus
Joining Too
@@ -54,46 +54,46 @@ exports[`renders comment stream 1`] = `
Lukas
What's up?
diff --git a/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap
index a7610a65c..bbfe65dd0 100644
--- a/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap
+++ b/src/core/client/stream/test/__snapshots__/renderStream.spec.tsx.snap
@@ -2,11 +2,11 @@
exports[`renders comment stream 1`] = `
Talk NEO
@@ -16,17 +16,17 @@ exports[`renders comment stream 1`] = `
>
Markus
Joining Too
@@ -54,15 +54,15 @@ exports[`renders comment stream 1`] = `
Lukas
What's up?
diff --git a/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap b/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
index c744dd323..dcd2108c2 100644
--- a/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
+++ b/src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
@@ -2,11 +2,11 @@
exports[`renders comment stream 1`] = `
Talk NEO
@@ -16,17 +16,17 @@ exports[`renders comment stream 1`] = `
>