From 796d24db3d2f8b129341431c216f43b736f4cb3e Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Mon, 2 Jul 2018 19:13:13 -0300
Subject: [PATCH 001/101] 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 70b88de51af14791843af8baf1976d3b42d1e3b0 Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Tue, 3 Jul 2018 15:49:35 -0300
Subject: [PATCH 002/101] Do not rerun relay compiler on its own changes
---
config/watcher.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/watcher.ts b/config/watcher.ts
index 305193045..0d3bf23c1 100644
--- a/config/watcher.ts
+++ b/config/watcher.ts
@@ -15,7 +15,7 @@ const config: Config = {
"core/client/stream/**/*.graphql",
"core/client/server/**/*.graphql",
],
- ignore: ["core/**/*.d.ts"],
+ ignore: ["core/**/*.d.ts", "core/**/*.graphql.ts"],
executor: new CommandExecutor("npm run compile:relay-stream", {
runOnInit: true,
}),
From 0784e7dd6346cf02ef5fd07f2db8150e682db416 Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Tue, 3 Jul 2018 15:49:35 -0300
Subject: [PATCH 003/101] Do not rerun relay compiler on its own changes
---
config/watcher.ts | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/config/watcher.ts b/config/watcher.ts
index 305193045..0d3bf23c1 100644
--- a/config/watcher.ts
+++ b/config/watcher.ts
@@ -15,7 +15,7 @@ const config: Config = {
"core/client/stream/**/*.graphql",
"core/client/server/**/*.graphql",
],
- ignore: ["core/**/*.d.ts"],
+ ignore: ["core/**/*.d.ts", "core/**/*.graphql.ts"],
executor: new CommandExecutor("npm run compile:relay-stream", {
runOnInit: true,
}),
From 9afc322314bdb8f1bc30053c9d2162773f5efeaa Mon Sep 17 00:00:00 2001
From: Wyatt Johnson
Date: Wed, 4 Jul 2018 10:50:10 -0600
Subject: [PATCH 004/101] feat: added support for --only flag
---
scripts/watcher/bin/watcher.ts | 12 ++++++++++--
scripts/watcher/types.ts | 4 ++++
scripts/watcher/watch.ts | 17 +++++++++++++++--
3 files changed, 29 insertions(+), 4 deletions(-)
diff --git a/scripts/watcher/bin/watcher.ts b/scripts/watcher/bin/watcher.ts
index 32209c064..a3a50e6c3 100644
--- a/scripts/watcher/bin/watcher.ts
+++ b/scripts/watcher/bin/watcher.ts
@@ -4,16 +4,24 @@ import program from "commander";
import path from "path";
import watch from "../";
+function list(val: string) {
+ return val.split(",");
+}
+
program
.version("0.1.0")
.usage("")
+ .option("-o, --only ", "only run the specified watcher", list)
.arguments("")
.description("Run watchers defined in ")
- .action(configFile => {
+ .action((configFile, cmd) => {
+ const { only = [] } = cmd;
+
let config: any = require(path.resolve(configFile));
if (config.__esModule) {
config = config.default;
}
- watch(config);
+
+ watch(config, { only });
})
.parse(process.argv);
diff --git a/scripts/watcher/types.ts b/scripts/watcher/types.ts
index f78daee24..15bd6090b 100644
--- a/scripts/watcher/types.ts
+++ b/scripts/watcher/types.ts
@@ -17,6 +17,10 @@ export interface Executor {
execute(filePath: string): void;
}
+export interface Options {
+ only?: string[];
+}
+
export interface Config {
rootDir?: string;
backend?: Watcher;
diff --git a/scripts/watcher/watch.ts b/scripts/watcher/watch.ts
index 572f7107b..8a3feac75 100644
--- a/scripts/watcher/watch.ts
+++ b/scripts/watcher/watch.ts
@@ -2,7 +2,7 @@ import Joi from "joi";
import path from "path";
import ChokidarWatcher from "./ChokidarWatcher";
-import { Config, configSchema, WatchConfig, Watcher } from "./types";
+import { Config, configSchema, Options, WatchConfig, Watcher } from "./types";
// Polyfill the asyncIterator symbol.
if (Symbol.asyncIterator === undefined) {
@@ -43,9 +43,22 @@ function setupCleanup(config: Config) {
);
}
-export default async function watch(config: Config) {
+function filterOnly(config: Config, only: string[]) {
+ for (const key of Object.keys(config.watchers)) {
+ if (only.indexOf(key) === -1) {
+ // tslint:disable-next-line:no-console
+ console.log(`Disabled watcher "${key}"`);
+ delete config.watchers[key];
+ }
+ }
+}
+
+export default async function watch(config: Config, options?: Options) {
Joi.assert(config, configSchema);
const watcher = config.backend || new ChokidarWatcher();
+ if (options && options.only && options.only.length > 0) {
+ filterOnly(config, options.only);
+ }
setupCleanup(config);
for (const key of Object.keys(config.watchers)) {
// tslint:disable-next-line:no-console
From ed97f80a00af77bb7f94e0d8c6f08b6b7161b057 Mon Sep 17 00:00:00 2001
From: Kiwi
Date: Wed, 4 Jul 2018 14:01:08 -0300
Subject: [PATCH 005/101] Use JSDocs comments (#1727)
---
scripts/watcher/CommandExecutor.ts | 6 +++---
scripts/watcher/LongRunningExecutor.ts | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/scripts/watcher/CommandExecutor.ts b/scripts/watcher/CommandExecutor.ts
index 60cf15e6a..fddba0b8b 100644
--- a/scripts/watcher/CommandExecutor.ts
+++ b/scripts/watcher/CommandExecutor.ts
@@ -5,13 +5,13 @@ import { Executor } from "./types";
interface CommandExecutorOptions {
args?: ReadonlyArray;
- // If true, allow spawning multiple processes.
+ /** If true, allow spawning multiple processes. */
spawnMutiple?: boolean;
- // Specify the period in which the process is started at max once.
+ /** Specify the period in which the process is started at max once. */
debounce?: number | false;
- // If true, will run command upon initialization.
+ /** If true, will run command upon initialization. */
runOnInit?: boolean;
}
diff --git a/scripts/watcher/LongRunningExecutor.ts b/scripts/watcher/LongRunningExecutor.ts
index cffe6f7db..7019c1fb3 100644
--- a/scripts/watcher/LongRunningExecutor.ts
+++ b/scripts/watcher/LongRunningExecutor.ts
@@ -6,7 +6,7 @@ import { Executor } from "./types";
interface LongRunningExecutorOptions {
args?: ReadonlyArray;
- // Specify the period in which the process is restarted at max once.
+ /** Specify the period in which the process is restarted at max once. */
debounce?: number;
}
From 1a14c131051dde2572b95e63f57ebca1b8a23617 Mon Sep 17 00:00:00 2001
From: Kiwi
Date: Wed, 4 Jul 2018 14:01:08 -0300
Subject: [PATCH 006/101] Use JSDocs comments (#1727)
---
scripts/watcher/CommandExecutor.ts | 6 +++---
scripts/watcher/LongRunningExecutor.ts | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/scripts/watcher/CommandExecutor.ts b/scripts/watcher/CommandExecutor.ts
index 60cf15e6a..fddba0b8b 100644
--- a/scripts/watcher/CommandExecutor.ts
+++ b/scripts/watcher/CommandExecutor.ts
@@ -5,13 +5,13 @@ import { Executor } from "./types";
interface CommandExecutorOptions {
args?: ReadonlyArray;
- // If true, allow spawning multiple processes.
+ /** If true, allow spawning multiple processes. */
spawnMutiple?: boolean;
- // Specify the period in which the process is started at max once.
+ /** Specify the period in which the process is started at max once. */
debounce?: number | false;
- // If true, will run command upon initialization.
+ /** If true, will run command upon initialization. */
runOnInit?: boolean;
}
diff --git a/scripts/watcher/LongRunningExecutor.ts b/scripts/watcher/LongRunningExecutor.ts
index cffe6f7db..7019c1fb3 100644
--- a/scripts/watcher/LongRunningExecutor.ts
+++ b/scripts/watcher/LongRunningExecutor.ts
@@ -6,7 +6,7 @@ import { Executor } from "./types";
interface LongRunningExecutorOptions {
args?: ReadonlyArray;
- // Specify the period in which the process is restarted at max once.
+ /** Specify the period in which the process is restarted at max once. */
debounce?: number;
}
From 52594dc02802390c8e68c979014a9095b2b76139 Mon Sep 17 00:00:00 2001
From: Kiwi
Date: Wed, 4 Jul 2018 14:12:43 -0300
Subject: [PATCH 007/101] [next] Remove nodemon (#1725)
* Remove old nodemon configs
* Remove nodemon
---
config/nodemon/relay-stream.json | 8 ----
config/nodemon/server.json | 10 -----
package-lock.json | 77 --------------------------------
package.json | 3 +-
4 files changed, 1 insertion(+), 97 deletions(-)
delete mode 100644 config/nodemon/relay-stream.json
delete mode 100644 config/nodemon/server.json
diff --git a/config/nodemon/relay-stream.json b/config/nodemon/relay-stream.json
deleted file mode 100644
index dc9556823..000000000
--- a/config/nodemon/relay-stream.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "exec": "npm-run-all compile:relay-stream",
- "ext": "ts,tsx,graphql",
- "watch": [
- "./src/core/client/stream",
- "./src/core/**/*.graphql"
- ]
-}
diff --git a/config/nodemon/server.json b/config/nodemon/server.json
deleted file mode 100644
index 08472086e..000000000
--- a/config/nodemon/server.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "exec": "npm run start:development",
- "ext": "ts,graphql",
- "watch": [
- "./src"
- ],
- "ignore": [
- "./src/client"
- ]
-}
diff --git a/package-lock.json b/package-lock.json
index b3622a48d..6038504da 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9820,12 +9820,6 @@
"integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
"dev": true
},
- "ignore-by-default": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
- "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
- "dev": true
- },
"immutable": {
"version": "3.7.6",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
@@ -12790,50 +12784,6 @@
"which": "^1.3.0"
}
},
- "nodemon": {
- "version": "1.17.5",
- "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.17.5.tgz",
- "integrity": "sha512-FG2mWJU1Y58a9ktgMJ/RZpsiPz3b7ge77t/okZHEa4NbrlXGKZ8s1A6Q+C7+JPXohAfcPALRwvxcAn8S874pmw==",
- "dev": true,
- "requires": {
- "chokidar": "^2.0.2",
- "debug": "^3.1.0",
- "ignore-by-default": "^1.0.1",
- "minimatch": "^3.0.4",
- "pstree.remy": "^1.1.0",
- "semver": "^5.5.0",
- "supports-color": "^5.2.0",
- "touch": "^3.1.0",
- "undefsafe": "^2.0.2",
- "update-notifier": "^2.3.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "dev": true
- },
- "supports-color": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
- "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- }
- }
- },
"nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
@@ -15936,15 +15886,6 @@
"integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw==",
"dev": true
},
- "pstree.remy": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz",
- "integrity": "sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q==",
- "dev": true,
- "requires": {
- "ps-tree": "^1.1.0"
- }
- },
"public-encrypt": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
@@ -18801,15 +18742,6 @@
"integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=",
"dev": true
},
- "touch": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
- "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
- "dev": true,
- "requires": {
- "nopt": "~1.0.10"
- }
- },
"tough-cookie": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
@@ -19684,15 +19616,6 @@
"integrity": "sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==",
"dev": true
},
- "undefsafe": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
- "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=",
- "dev": true,
- "requires": {
- "debug": "^2.2.0"
- }
- },
"unherit": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.1.tgz",
diff --git a/package.json b/package.json
index 5f615b41f..707d65836 100644
--- a/package.json
+++ b/package.json
@@ -102,7 +102,6 @@
"html-webpack-plugin": "^3.2.0",
"jest": "^23.2.0",
"loader-utils": "^1.1.0",
- "nodemon": "^1.17.5",
"npm-run-all": "^4.1.3",
"postcss-flexbugs-fixes": "^3.3.1",
"postcss-font-magician": "^2.2.1",
@@ -141,4 +140,4 @@
"webpack-hot-client": "^4.0.3",
"webpack-manifest-plugin": "^2.0.3"
}
-}
\ No newline at end of file
+}
From c9c99623bc50820a308697fe224711643784628f Mon Sep 17 00:00:00 2001
From: Kiwi
Date: Wed, 4 Jul 2018 14:12:43 -0300
Subject: [PATCH 008/101] [next] Remove nodemon (#1725)
* Remove old nodemon configs
* Remove nodemon
---
config/nodemon/relay-stream.json | 8 ----
config/nodemon/server.json | 10 -----
package-lock.json | 77 --------------------------------
package.json | 3 +-
4 files changed, 1 insertion(+), 97 deletions(-)
delete mode 100644 config/nodemon/relay-stream.json
delete mode 100644 config/nodemon/server.json
diff --git a/config/nodemon/relay-stream.json b/config/nodemon/relay-stream.json
deleted file mode 100644
index dc9556823..000000000
--- a/config/nodemon/relay-stream.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "exec": "npm-run-all compile:relay-stream",
- "ext": "ts,tsx,graphql",
- "watch": [
- "./src/core/client/stream",
- "./src/core/**/*.graphql"
- ]
-}
diff --git a/config/nodemon/server.json b/config/nodemon/server.json
deleted file mode 100644
index 08472086e..000000000
--- a/config/nodemon/server.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- "exec": "npm run start:development",
- "ext": "ts,graphql",
- "watch": [
- "./src"
- ],
- "ignore": [
- "./src/client"
- ]
-}
diff --git a/package-lock.json b/package-lock.json
index b3622a48d..6038504da 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9820,12 +9820,6 @@
"integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==",
"dev": true
},
- "ignore-by-default": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
- "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
- "dev": true
- },
"immutable": {
"version": "3.7.6",
"resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz",
@@ -12790,50 +12784,6 @@
"which": "^1.3.0"
}
},
- "nodemon": {
- "version": "1.17.5",
- "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.17.5.tgz",
- "integrity": "sha512-FG2mWJU1Y58a9ktgMJ/RZpsiPz3b7ge77t/okZHEa4NbrlXGKZ8s1A6Q+C7+JPXohAfcPALRwvxcAn8S874pmw==",
- "dev": true,
- "requires": {
- "chokidar": "^2.0.2",
- "debug": "^3.1.0",
- "ignore-by-default": "^1.0.1",
- "minimatch": "^3.0.4",
- "pstree.remy": "^1.1.0",
- "semver": "^5.5.0",
- "supports-color": "^5.2.0",
- "touch": "^3.1.0",
- "undefsafe": "^2.0.2",
- "update-notifier": "^2.3.0"
- },
- "dependencies": {
- "debug": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
- "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- },
- "has-flag": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
- "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
- "dev": true
- },
- "supports-color": {
- "version": "5.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
- "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
- "dev": true,
- "requires": {
- "has-flag": "^3.0.0"
- }
- }
- }
- },
"nopt": {
"version": "1.0.10",
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
@@ -15936,15 +15886,6 @@
"integrity": "sha512-+AqO1Ae+N/4r7Rvchrdm432afjT9hqJRyBN3DQv9At0tPz4hIFSGKbq64fN9dVoCow4oggIIax5/iONx0r9hZw==",
"dev": true
},
- "pstree.remy": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz",
- "integrity": "sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q==",
- "dev": true,
- "requires": {
- "ps-tree": "^1.1.0"
- }
- },
"public-encrypt": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
@@ -18801,15 +18742,6 @@
"integrity": "sha1-LmhELZ9k7HILjMieZEOsbKqVACk=",
"dev": true
},
- "touch": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
- "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
- "dev": true,
- "requires": {
- "nopt": "~1.0.10"
- }
- },
"tough-cookie": {
"version": "2.4.3",
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
@@ -19684,15 +19616,6 @@
"integrity": "sha512-keqHubrlpvT6G2wH0OEfSW4mquYRcbe/J8NMmveoQOjUqmo+hXtO+ORCpWhdbZ7k72UtY61BL7haGxW6enBnjw==",
"dev": true
},
- "undefsafe": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
- "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=",
- "dev": true,
- "requires": {
- "debug": "^2.2.0"
- }
- },
"unherit": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.1.tgz",
diff --git a/package.json b/package.json
index 5f615b41f..707d65836 100644
--- a/package.json
+++ b/package.json
@@ -102,7 +102,6 @@
"html-webpack-plugin": "^3.2.0",
"jest": "^23.2.0",
"loader-utils": "^1.1.0",
- "nodemon": "^1.17.5",
"npm-run-all": "^4.1.3",
"postcss-flexbugs-fixes": "^3.3.1",
"postcss-font-magician": "^2.2.1",
@@ -141,4 +140,4 @@
"webpack-hot-client": "^4.0.3",
"webpack-manifest-plugin": "^2.0.3"
}
-}
\ No newline at end of file
+}
From 9f79ee1c6da9e9f5d1acce21111bc34d8e6dbe37 Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Wed, 4 Jul 2018 15:01:47 -0300
Subject: [PATCH 009/101] 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 010/101] 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 011/101] 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 012/101] 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 && (
-
-
-
-
- {
- console.log("ey");
- }}
- >
- Copy
-
-
+ Share
+
);
diff --git a/src/core/client/tslint.json b/src/core/client/tslint.json
index 9abc9b921..0079a6de1 100644
--- a/src/core/client/tslint.json
+++ b/src/core/client/tslint.json
@@ -1,20 +1,13 @@
{
- "extends": [
- "../../../tslint.json",
- "tslint-react"
- ],
+ "extends": ["../../../tslint.json", "tslint-react"],
"rules": {
+ "jsx-curly-spacing": false,
"jsx-no-multiline-js": false,
- "jsx-boolean-value": [
- true,
- "never"
- ]
+ "jsx-boolean-value": [true, "never"]
},
"jsRules": {
+ "jsx-curly-spacing": false,
"jsx-no-multiline-js": false,
- "jsx-boolean-value": [
- true,
- "never"
- ]
+ "jsx-boolean-value": [true, "never"]
}
-}
\ No newline at end of file
+}
diff --git a/src/core/client/ui/components/Tooltip/Tooltip.css b/src/core/client/ui/components/Popover/Popover.css
similarity index 100%
rename from src/core/client/ui/components/Tooltip/Tooltip.css
rename to src/core/client/ui/components/Popover/Popover.css
diff --git a/src/core/client/ui/components/Popover/Popover.tsx b/src/core/client/ui/components/Popover/Popover.tsx
new file mode 100644
index 000000000..a3c2b9b4b
--- /dev/null
+++ b/src/core/client/ui/components/Popover/Popover.tsx
@@ -0,0 +1,32 @@
+import React from "react";
+import { Manager, Popper, Reference } from "react-popper";
+// import * as styles from "./Popover.css";
+
+interface InnerProps {
+ body: React.ReactElement;
+ children: React.ReactElement;
+}
+
+class Popover extends React.Component {
+ public render() {
+ const { children, body } = this.props;
+ return (
+
+
+ {({ ref }) => React.cloneElement(children, { ref })}
+
+
+ {({ ref, style, placement, arrowProps }) =>
+ React.cloneElement(body, {
+ ref,
+ style,
+ "data-placement": placement,
+ })
+ }
+
+
+ );
+ }
+}
+
+export default Popover;
diff --git a/src/core/client/ui/components/Popover/index.ts b/src/core/client/ui/components/Popover/index.ts
new file mode 100644
index 000000000..7e46e3708
--- /dev/null
+++ b/src/core/client/ui/components/Popover/index.ts
@@ -0,0 +1,2 @@
+export * from "./Popover";
+export { default } from "./Popover";
diff --git a/src/core/client/ui/components/TextField/TextField.css b/src/core/client/ui/components/TextField/TextField.css
new file mode 100644
index 000000000..4d2e9e88a
--- /dev/null
+++ b/src/core/client/ui/components/TextField/TextField.css
@@ -0,0 +1,11 @@
+.root {
+ font-family: "Source Sans Pro";
+ font-weight: 400;
+ font-size: 16px;
+ letter-spacing: calc(0.57em / 16);
+ background: #ffffff;
+ border: 1px solid #979797;
+ box-sizing: border-box;
+ border-radius: 1px;
+ padding: 5px 20px;
+}
diff --git a/src/core/client/ui/components/TextField/TextField.d.ts b/src/core/client/ui/components/TextField/TextField.d.ts
new file mode 100644
index 000000000..f99662ba2
--- /dev/null
+++ b/src/core/client/ui/components/TextField/TextField.d.ts
@@ -0,0 +1 @@
+export const root: string;
diff --git a/src/core/client/ui/components/TextField/TextField.tsx b/src/core/client/ui/components/TextField/TextField.tsx
new file mode 100644
index 000000000..d1a623662
--- /dev/null
+++ b/src/core/client/ui/components/TextField/TextField.tsx
@@ -0,0 +1,14 @@
+import cn from "classnames";
+import React, { InputHTMLAttributes, StatelessComponent } from "react";
+
+import * as styles from "./TextField";
+
+interface InnerProps extends InputHTMLAttributes {
+ classes?: typeof styles;
+}
+
+const Input: StatelessComponent = ({ className, ...rest }) => {
+ return ;
+};
+
+export default Input;
diff --git a/src/core/client/ui/components/TextField/index.ts b/src/core/client/ui/components/TextField/index.ts
new file mode 100644
index 000000000..e38acd4ea
--- /dev/null
+++ b/src/core/client/ui/components/TextField/index.ts
@@ -0,0 +1,2 @@
+export * from "./TextField";
+export { default } from "./TextField";
diff --git a/src/core/client/ui/components/Tooltip/Tooltip.tsx b/src/core/client/ui/components/Tooltip/Tooltip.tsx
deleted file mode 100644
index f6e1a9cf0..000000000
--- a/src/core/client/ui/components/Tooltip/Tooltip.tsx
+++ /dev/null
@@ -1,22 +0,0 @@
-import cn from "classnames";
-import React from "react";
-import ReactTooltip from "react-tooltip";
-import * as styles from "./Tooltip.css";
-
-interface InnerProps extends ReactTooltip.Props {
- clickable: boolean;
-}
-
-class Tooltip extends React.Component {
- public render() {
- const { clickable } = this.props;
- return (
-
- );
- }
-}
-
-export default Tooltip;
diff --git a/src/core/client/ui/components/Tooltip/index.ts b/src/core/client/ui/components/Tooltip/index.ts
deleted file mode 100644
index 9474b3888..000000000
--- a/src/core/client/ui/components/Tooltip/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from "./Tooltip";
-export { default } from "./Tooltip";
diff --git a/src/core/client/ui/components/index.ts b/src/core/client/ui/components/index.ts
index 6e1fcd8a6..9f16ee536 100644
--- a/src/core/client/ui/components/index.ts
+++ b/src/core/client/ui/components/index.ts
@@ -2,5 +2,5 @@ export { default as BaseButton } from "./BaseButton";
export { default as Button } from "./Button";
export { default as Center } from "./Center";
export { default as Typography } from "./Typography";
-export { default as Tooltip } from "./Tooltip";
+export { default as Popover } from "./Popover";
export { default as Input } from "./Input";
diff --git a/src/tsconfig.json b/src/tsconfig.json
index eddf98d29..857892f4d 100644
--- a/src/tsconfig.json
+++ b/src/tsconfig.json
@@ -9,26 +9,13 @@
"outDir": "../dist",
// See https://github.com/prismagraphql/graphql-request/issues/26 for why we
// have to include "dom" here.
- "lib": [
- "es6",
- "esnext.asynciterable",
- "dom"
- ],
+ "lib": ["es6", "esnext.asynciterable", "dom"],
"baseUrl": "./",
"paths": {
- "talk-server/*": [
- "./core/server/*"
- ],
- "talk-common/*": [
- "./core/common/*"
- ]
+ "talk-server/*": ["./core/server/*"],
+ "talk-common/*": ["./core/common/*"]
}
},
- "include": [
- "./**/*"
- ],
- "exclude": [
- "node_modules",
- "./core/client"
- ]
-}
\ No newline at end of file
+ "include": ["./**/*"],
+ "exclude": ["node_modules", "./core/client"]
+}
diff --git a/tslint.json b/tslint.json
index 68001f8c6..853208eb0 100644
--- a/tslint.json
+++ b/tslint.json
@@ -7,10 +7,7 @@
"rules": {
"prettier": true,
"object-literal-sort-keys": false,
- "interface-name": [
- true,
- "never-prefix"
- ],
+ "interface-name": [true, "never-prefix"],
"no-switch-case-fall-through": true,
"member-ordering": false,
"variable-name": [
@@ -35,8 +32,6 @@
]
},
"linterOptions": {
- "exclude": [
- "**/node_modules/**/*"
- ]
+ "exclude": ["**/node_modules/**/*"]
}
-}
\ No newline at end of file
+}
From 155b8c731673f3f63dcacefe0de81387ff8f232e Mon Sep 17 00:00:00 2001
From: okbel
Date: Mon, 9 Jul 2018 16:39:04 -0300
Subject: [PATCH 031/101] progress
---
package-lock.json | 67 ++++++++++++++-----
package.json | 1 +
src/core/client/stream/components/Comment.tsx | 22 ++++++
.../client/ui/components/Popover/Popover.tsx | 9 ++-
.../ui/components/TextField/TextField.tsx | 2 +-
5 files changed, 83 insertions(+), 18 deletions(-)
diff --git a/package-lock.json b/package-lock.json
index 9f3848257..2321cd2cf 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -2390,8 +2390,7 @@
"asap": {
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
- "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=",
- "dev": true
+ "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"asn1": {
"version": "0.2.3",
@@ -5876,6 +5875,15 @@
"sha.js": "^2.4.8"
}
},
+ "create-react-context": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/create-react-context/-/create-react-context-0.2.2.tgz",
+ "integrity": "sha512-KkpaLARMhsTsgp0d2NA/R94F/eDLbhXERdIq3LvX2biCAXcDvHYoOqHfWCHf1+OLj+HKBotLG3KqaOOf+C1C+A==",
+ "requires": {
+ "fbjs": "^0.8.0",
+ "gud": "^1.0.0"
+ }
+ },
"cross-fetch": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.0.0.tgz",
@@ -7288,7 +7296,6 @@
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
- "dev": true,
"requires": {
"iconv-lite": "~0.4.13"
}
@@ -7958,7 +7965,6 @@
"version": "0.8.17",
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.17.tgz",
"integrity": "sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=",
- "dev": true,
"requires": {
"core-js": "^1.0.0",
"isomorphic-fetch": "^2.1.1",
@@ -7972,8 +7978,7 @@
"core-js": {
"version": "1.2.7",
"resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
- "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=",
- "dev": true
+ "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
}
}
},
@@ -9278,6 +9283,11 @@
"integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=",
"dev": true
},
+ "gud": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gud/-/gud-1.0.0.tgz",
+ "integrity": "sha512-zGEOVKFM5sVPPrYs7J5/hYEw2Pof8KCyOwyhG8sAF26mCAeUFAcYPu1mwB7hhpIP29zOIBaDqwuHdLp0jvZXjw=="
+ },
"gzip-size": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-3.0.0.tgz",
@@ -10604,8 +10614,7 @@
"is-stream": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
- "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
- "dev": true
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ="
},
"is-svg": {
"version": "2.1.0",
@@ -10715,7 +10724,6 @@
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
- "dev": true,
"requires": {
"node-fetch": "^1.0.1",
"whatwg-fetch": ">=0.10.0"
@@ -10725,7 +10733,6 @@
"version": "1.7.3",
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
- "dev": true,
"requires": {
"encoding": "^0.1.11",
"is-stream": "^1.0.1"
@@ -13542,6 +13549,11 @@
"integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
"dev": true
},
+ "popper.js": {
+ "version": "1.14.3",
+ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.14.3.tgz",
+ "integrity": "sha1-FDj5jQRqz3tNeM1QK/QYrGTU8JU="
+ },
"portfinder": {
"version": "1.0.13",
"resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.13.tgz",
@@ -15895,7 +15907,6 @@
"version": "7.3.1",
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
- "dev": true,
"requires": {
"asap": "~2.0.3"
}
@@ -16537,6 +16548,29 @@
"integrity": "sha512-OQvgdiPfWbAjudT8Q+V2aWsySCJW0aQ3wNjfOw1ooamydEQkDxRfWqfnEhCYLneCz67d+r3kBYoZlpAx5S+VWA==",
"dev": true
},
+ "react-popper": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.0.0.tgz",
+ "integrity": "sha1-uZRSFE6P5KzHf6PZWajHngemUIQ=",
+ "requires": {
+ "babel-runtime": "6.x.x",
+ "create-react-context": "^0.2.1",
+ "popper.js": "^1.14.1",
+ "prop-types": "^15.6.1",
+ "typed-styles": "^0.0.5",
+ "warning": "^3.0.0"
+ },
+ "dependencies": {
+ "warning": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
+ "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
+ "requires": {
+ "loose-envify": "^1.0.0"
+ }
+ }
+ }
+ },
"react-powerplug": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/react-powerplug/-/react-powerplug-0.1.6.tgz",
@@ -17842,8 +17876,7 @@
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
- "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=",
- "dev": true
+ "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
},
"setprototypeof": {
"version": "1.1.0",
@@ -19711,6 +19744,11 @@
}
}
},
+ "typed-styles": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/typed-styles/-/typed-styles-0.0.5.tgz",
+ "integrity": "sha512-ht+rEe5UsdEBAa3gr64+QjUOqjOLJfWLvl5HZR5Ev9uo/OnD3p43wPeFSB1hNFc13GXQF/JU1Bn0YHLUqBRIlw=="
+ },
"typedarray": {
"version": "0.0.6",
"resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
@@ -19726,8 +19764,7 @@
"ua-parser-js": {
"version": "0.7.18",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz",
- "integrity": "sha512-LtzwHlVHwFGTptfNSgezHp7WUlwiqb0gA9AALRbKaERfxwJoiX0A73QbTToxteIAuIaFshhgIZfqK8s7clqgnA==",
- "dev": true
+ "integrity": "sha512-LtzwHlVHwFGTptfNSgezHp7WUlwiqb0gA9AALRbKaERfxwJoiX0A73QbTToxteIAuIaFshhgIZfqK8s7clqgnA=="
},
"uglify-js": {
"version": "3.4.2",
diff --git a/package.json b/package.json
index d2defed61..49b0d6ea4 100644
--- a/package.json
+++ b/package.json
@@ -49,6 +49,7 @@
"performance-now": "^2.1.0",
"rc-tooltip": "^3.7.2",
"react-copy-to-clipboard": "^5.0.1",
+ "react-popper": "^1.14.3",
"react-tooltip": "^3.6.1",
"subscriptions-transport-ws": "^0.9.11",
"uuid": "^3.2.1"
diff --git a/src/core/client/stream/components/Comment.tsx b/src/core/client/stream/components/Comment.tsx
index cc13ae115..7bb017b42 100644
--- a/src/core/client/stream/components/Comment.tsx
+++ b/src/core/client/stream/components/Comment.tsx
@@ -2,6 +2,7 @@ import cn from "classnames";
import React from "react";
import { StatelessComponent } from "react";
import CopyToClipboard from "react-copy-to-clipboard";
+import { Manager, Popper, Reference } from "react-popper";
import { Button, Input, Popover, Typography } from "talk-ui/components";
import * as styles from "./Comment.css";
@@ -27,6 +28,27 @@ const Comment: StatelessComponent = props => {
{props.author && props.author.username}
{props.body}
+
+
+ {({ ref }) => (
+
+ Reference element
+
+ )}
+
+
+ {({ ref, style, placement, arrowProps }) => (
+
+ Popper element
+
+ )}
+
+
{
{({ ref }) => React.cloneElement(children, { ref })}
-
- {({ ref, style, placement, arrowProps }) =>
+
+ {({ ref, placement, style }) =>
React.cloneElement(body, {
ref,
style,
diff --git a/src/core/client/ui/components/TextField/TextField.tsx b/src/core/client/ui/components/TextField/TextField.tsx
index d1a623662..ac980b102 100644
--- a/src/core/client/ui/components/TextField/TextField.tsx
+++ b/src/core/client/ui/components/TextField/TextField.tsx
@@ -1,7 +1,7 @@
import cn from "classnames";
import React, { InputHTMLAttributes, StatelessComponent } from "react";
-import * as styles from "./TextField";
+import * as styles from "./TextField.css";
interface InnerProps extends InputHTMLAttributes {
classes?: typeof styles;
From 25c931cc0570d70d8d47dab390f931a7b27a445f Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Mon, 9 Jul 2018 16:31:57 -0300
Subject: [PATCH 032/101] Implement Replies
---
config/watcher.ts | 7 +-
config/webpack.config.dev.js | 5 +
src/core/client/stream/components/Indent.tsx | 16 ++
.../stream/components/ReplyList.spec.tsx | 36 ++++
.../client/stream/components/ReplyList.tsx | 37 ++++
.../client/stream/components/Stream.spec.tsx | 8 +-
src/core/client/stream/components/Stream.tsx | 19 +-
.../__snapshots__/ReplyList.spec.tsx.snap | 56 ++++++
.../__snapshots__/Stream.spec.tsx.snap | 102 +++++++---
.../stream/containers/CommentContainer.tsx | 15 +-
.../containers/ReplyListContainer.spec.tsx | 37 ++++
.../stream/containers/ReplyListContainer.tsx | 125 ++++++++++++
.../containers/StreamContainer.spec.tsx | 2 +-
.../stream/containers/StreamContainer.tsx | 6 +-
.../ReplyListContainer.spec.tsx.snap | 20 ++
.../StreamContainer.spec.tsx.snap | 4 +-
.../test/__snapshots__/loadMore.spec.tsx.snap | 132 +++++++------
.../__snapshots__/renderReplies.spec.tsx.snap | 111 +++++++++++
.../__snapshots__/renderStream.spec.tsx.snap | 52 ++---
.../showAllReplies.spec.tsx.snap | 181 ++++++++++++++++++
.../client/stream/test/createEnvironment.ts | 1 -
src/core/client/stream/test/fixtures.ts | 30 +++
src/core/client/stream/test/loadMore.spec.tsx | 2 +-
.../client/stream/test/renderReplies.spec.tsx | 42 ++++
.../stream/test/showAllReplies.spec.tsx | 100 ++++++++++
25 files changed, 1007 insertions(+), 139 deletions(-)
create mode 100644 src/core/client/stream/components/Indent.tsx
create mode 100644 src/core/client/stream/components/ReplyList.spec.tsx
create mode 100644 src/core/client/stream/components/ReplyList.tsx
create mode 100644 src/core/client/stream/components/__snapshots__/ReplyList.spec.tsx.snap
create mode 100644 src/core/client/stream/containers/ReplyListContainer.spec.tsx
create mode 100644 src/core/client/stream/containers/ReplyListContainer.tsx
create mode 100644 src/core/client/stream/containers/__snapshots__/ReplyListContainer.spec.tsx.snap
create mode 100644 src/core/client/stream/test/__snapshots__/renderReplies.spec.tsx.snap
create mode 100644 src/core/client/stream/test/__snapshots__/showAllReplies.spec.tsx.snap
create mode 100644 src/core/client/stream/test/renderReplies.spec.tsx
create mode 100644 src/core/client/stream/test/showAllReplies.spec.tsx
diff --git a/config/watcher.ts b/config/watcher.ts
index 0d3bf23c1..9ff074e51 100644
--- a/config/watcher.ts
+++ b/config/watcher.ts
@@ -15,7 +15,12 @@ const config: Config = {
"core/client/stream/**/*.graphql",
"core/client/server/**/*.graphql",
],
- ignore: ["core/**/*.d.ts", "core/**/*.graphql.ts"],
+ ignore: [
+ "core/**/*.d.ts",
+ "core/**/*.graphql.ts",
+ "**/test/**/*",
+ "core/**/*.spec.*",
+ ],
executor: new CommandExecutor("npm run compile:relay-stream", {
runOnInit: true,
}),
diff --git a/config/webpack.config.dev.js b/config/webpack.config.dev.js
index 80872c5a4..fcbb75fe2 100644
--- a/config/webpack.config.dev.js
+++ b/config/webpack.config.dev.js
@@ -224,6 +224,11 @@ module.exports = {
jsx: "preserve",
noEmit: false,
},
+
+ // Overwrites the behavior of `include` and `exclude` to only
+ // include files that are actually being imported and which
+ // are necessary to compile the bundle.
+ onlyCompileBundledFiles: true,
},
},
],
diff --git a/src/core/client/stream/components/Indent.tsx b/src/core/client/stream/components/Indent.tsx
new file mode 100644
index 000000000..49222acff
--- /dev/null
+++ b/src/core/client/stream/components/Indent.tsx
@@ -0,0 +1,16 @@
+import React, { StatelessComponent } from "react";
+
+export interface IndentProps {
+ level?: number;
+ children: React.ReactNode;
+}
+
+const Indent: StatelessComponent = props => {
+ return (
+
+ {props.children}
+
+ );
+};
+
+export default Indent;
diff --git a/src/core/client/stream/components/ReplyList.spec.tsx b/src/core/client/stream/components/ReplyList.spec.tsx
new file mode 100644
index 000000000..2e5d6a984
--- /dev/null
+++ b/src/core/client/stream/components/ReplyList.spec.tsx
@@ -0,0 +1,36 @@
+import { shallow } from "enzyme";
+import { noop } from "lodash";
+import React from "react";
+import sinon from "sinon";
+
+import ReplyList from "./ReplyList";
+
+it("renders correctly", () => {
+ const props = {
+ commentID: "comment-id",
+ comments: [{ id: "comment-1" }, { id: "comment-2" }],
+ onLoadMore: noop,
+ hasMore: false,
+ };
+ const wrapper = shallow();
+ expect(wrapper).toMatchSnapshot();
+});
+
+describe("when there is more", () => {
+ const props = {
+ commentID: "comment-id",
+ comments: [{ id: "comment-1" }, { id: "comment-2" }],
+ onLoadMore: sinon.spy(),
+ hasMore: true,
+ };
+
+ const wrapper = shallow();
+ it("renders a load more button", () => {
+ expect(wrapper).toMatchSnapshot();
+ });
+
+ it("calls onLoadMore", () => {
+ wrapper.find("#talk-reply-list--show-all--comment-id").simulate("click");
+ expect(props.onLoadMore.calledOnce).toBe(true);
+ });
+});
diff --git a/src/core/client/stream/components/ReplyList.tsx b/src/core/client/stream/components/ReplyList.tsx
new file mode 100644
index 000000000..ce9aa13c5
--- /dev/null
+++ b/src/core/client/stream/components/ReplyList.tsx
@@ -0,0 +1,37 @@
+import * as React from "react";
+import { StatelessComponent } from "react";
+
+import { Button } from "talk-ui/components";
+
+import CommentContainer from "../containers/CommentContainer";
+import Indent from "./Indent";
+
+export interface ReplyListProps {
+ commentID: string;
+ comments: ReadonlyArray<{ id: string }>;
+ onLoadMore: () => void;
+ hasMore: boolean;
+}
+
+const ReplyList: StatelessComponent = props => {
+ return (
+
+ {props.comments.map(comment => (
+
+ ))}
+ {props.hasMore && (
+
+ )}
+
+ );
+};
+
+export default ReplyList;
diff --git a/src/core/client/stream/components/Stream.spec.tsx b/src/core/client/stream/components/Stream.spec.tsx
index 0c632d661..09ae7dfe3 100644
--- a/src/core/client/stream/components/Stream.spec.tsx
+++ b/src/core/client/stream/components/Stream.spec.tsx
@@ -7,7 +7,7 @@ import Stream from "./Stream";
it("renders correctly", () => {
const props = {
- id: "asset-id",
+ assetID: "asset-id",
isClosed: false,
comments: [{ id: "comment-1" }, { id: "comment-2" }],
onLoadMore: noop,
@@ -19,7 +19,7 @@ it("renders correctly", () => {
it("renders when comments is null", () => {
const props = {
- id: "asset-id",
+ assetID: "asset-id",
isClosed: false,
comments: null,
onLoadMore: noop,
@@ -31,7 +31,7 @@ it("renders when comments is null", () => {
describe("when there is more", () => {
const props = {
- id: "asset-id",
+ assetID: "asset-id",
isClosed: false,
comments: [{ id: "comment-1" }, { id: "comment-2" }],
onLoadMore: sinon.spy(),
@@ -44,7 +44,7 @@ describe("when there is more", () => {
});
it("calls onLoadMore", () => {
- wrapper.find("#talk-stream--loadmore").simulate("click");
+ wrapper.find("#talk-stream--load-more").simulate("click");
expect(props.onLoadMore.calledOnce).toBe(true);
});
});
diff --git a/src/core/client/stream/components/Stream.tsx b/src/core/client/stream/components/Stream.tsx
index e884cacc2..c8eff6337 100644
--- a/src/core/client/stream/components/Stream.tsx
+++ b/src/core/client/stream/components/Stream.tsx
@@ -1,13 +1,15 @@
import * as React from "react";
import { StatelessComponent } from "react";
-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";
+import CommentContainer from "../containers/CommentContainer";
+import PostCommentFormContainer from "../containers/PostCommentFormContainer";
+import ReplyListContainer from "../containers/ReplyListContainer";
+import Logo from "./Logo";
+
export interface StreamProps {
- id: string;
+ assetID: string;
isClosed: boolean;
comments: ReadonlyArray<{ id: string }> | null;
onLoadMore: () => void;
@@ -22,13 +24,16 @@ const Stream: StatelessComponent = props => {
return (
-
+
{props.comments.map(comment => (
-
+
+
+
+
))}
{props.hasMore && (
+
+
+
+`;
+
+exports[`when there is more renders a load more button 1`] = `
+
+
+
+
+
+`;
diff --git a/src/core/client/stream/components/__snapshots__/Stream.spec.tsx.snap b/src/core/client/stream/components/__snapshots__/Stream.spec.tsx.snap
index 5251bcd6d..624c0dc05 100644
--- a/src/core/client/stream/components/__snapshots__/Stream.spec.tsx.snap
+++ b/src/core/client/stream/components/__snapshots__/Stream.spec.tsx.snap
@@ -8,24 +8,44 @@ exports[`renders correctly 1`] = `
-
-
+
+
+
+
+ >
+
+
+
`;
@@ -43,27 +63,47 @@ exports[`when there is more renders a load more button 1`] = `
-
-
+
+
+
+
+ >
+
+
+
;
+// tslint:disable-next-line:no-unused-expression
+graphql`
+ fragment CommentContainer_comment on Comment {
+ author {
+ username
+ }
+ body
+ }
+`;
+
export const CommentContainer: StatelessComponent = props => {
const { data, ...rest } = props;
return ;
@@ -17,10 +27,7 @@ export const CommentContainer: StatelessComponent = props => {
const enhanced = withFragmentContainer<{ data: Data }>({
data: graphql`
fragment CommentContainer on Comment {
- author {
- username
- }
- body
+ ...CommentContainer_comment @relay(mask: false)
}
`,
})(CommentContainer);
diff --git a/src/core/client/stream/containers/ReplyListContainer.spec.tsx b/src/core/client/stream/containers/ReplyListContainer.spec.tsx
new file mode 100644
index 000000000..d2fbb7534
--- /dev/null
+++ b/src/core/client/stream/containers/ReplyListContainer.spec.tsx
@@ -0,0 +1,37 @@
+import { shallow } from "enzyme";
+import { noop } from "lodash";
+import React from "react";
+
+import { ReplyListContainer } from "./ReplyListContainer";
+
+it("renders correctly", () => {
+ const props: any = {
+ comment: {
+ id: "comment-id",
+ replies: {
+ edges: [{ node: { id: "comment-1" } }, { node: { id: "comment-2" } }],
+ },
+ },
+ relay: {
+ hasMore: noop,
+ isLoading: noop,
+ },
+ };
+ const wrapper = shallow();
+ expect(wrapper).toMatchSnapshot();
+});
+
+it("renders correctly when replies are null", () => {
+ const props: any = {
+ comment: {
+ id: "comment-id",
+ replies: null,
+ },
+ relay: {
+ hasMore: noop,
+ isLoading: noop,
+ },
+ };
+ const wrapper = shallow();
+ expect(wrapper).toMatchSnapshot();
+});
diff --git a/src/core/client/stream/containers/ReplyListContainer.tsx b/src/core/client/stream/containers/ReplyListContainer.tsx
new file mode 100644
index 000000000..47f940f54
--- /dev/null
+++ b/src/core/client/stream/containers/ReplyListContainer.tsx
@@ -0,0 +1,125 @@
+import React from "react";
+import { graphql, RelayPaginationProp } from "react-relay";
+
+import { withPaginationContainer } from "talk-framework/lib/relay";
+import { PropTypesOf } from "talk-framework/types";
+import { ReplyListContainer_comment as Data } from "talk-stream/__generated__/ReplyListContainer_comment.graphql";
+import {
+ COMMENT_SORT,
+ ReplyListContainerPaginationQueryVariables,
+} from "talk-stream/__generated__/ReplyListContainerPaginationQuery.graphql";
+
+import ReplyList from "../components/ReplyList";
+
+export interface InnerProps {
+ comment: Data;
+ relay: RelayPaginationProp;
+}
+
+export class ReplyListContainer extends React.Component {
+ public render() {
+ if (this.props.comment.replies === null) {
+ return null;
+ }
+ const comments = this.props.comment.replies.edges.map(edge => edge.node);
+ return (
+
+ );
+ }
+
+ private loadMore = () => {
+ if (!this.props.relay.hasMore() || this.props.relay.isLoading()) {
+ return;
+ }
+
+ this.props.relay.loadMore(
+ 999999999, // Fetch All Replies
+ error => {
+ if (error) {
+ // tslint:disable-next-line:no-console
+ console.error(error);
+ }
+ }
+ );
+ };
+}
+
+// TODO: (cvle) This should be autogenerated.
+interface FragmentVariables {
+ count: number;
+ cursor?: string;
+ orderBy: COMMENT_SORT;
+}
+
+const enhanced = withPaginationContainer<
+ { comment: Data },
+ InnerProps,
+ FragmentVariables,
+ ReplyListContainerPaginationQueryVariables
+>(
+ {
+ comment: graphql`
+ fragment ReplyListContainer_comment on Comment
+ @argumentDefinitions(
+ count: { type: "Int!", defaultValue: 5 }
+ cursor: { type: "Cursor" }
+ orderBy: { type: "COMMENT_SORT!", defaultValue: CREATED_AT_ASC }
+ ) {
+ id
+ replies(first: $count, after: $cursor, orderBy: $orderBy)
+ @connection(key: "ReplyList_replies") {
+ edges {
+ node {
+ id
+ ...CommentContainer
+ }
+ }
+ }
+ }
+ `,
+ },
+ {
+ direction: "forward",
+ getConnectionFromProps(props) {
+ return props.comment && props.comment.replies;
+ },
+ // 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,
+ commentID: props.comment.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 ReplyListContainerPaginationQuery(
+ $count: Int!
+ $cursor: Cursor
+ $orderBy: COMMENT_SORT!
+ $commentID: ID!
+ ) {
+ comment(id: $commentID) {
+ ...ReplyListContainer_comment
+ @arguments(count: $count, cursor: $cursor, orderBy: $orderBy)
+ }
+ }
+ `,
+ }
+)(ReplyListContainer);
+
+export type ReplyListContainerProps = PropTypesOf;
+export default enhanced;
diff --git a/src/core/client/stream/containers/StreamContainer.spec.tsx b/src/core/client/stream/containers/StreamContainer.spec.tsx
index 9e3bfebce..3ab0875d2 100644
--- a/src/core/client/stream/containers/StreamContainer.spec.tsx
+++ b/src/core/client/stream/containers/StreamContainer.spec.tsx
@@ -4,7 +4,7 @@ import React from "react";
import { StreamContainer } from "./StreamContainer";
-it("renders username and body", () => {
+it("renders correctly", () => {
const props: any = {
asset: {
id: "asset-id",
diff --git a/src/core/client/stream/containers/StreamContainer.tsx b/src/core/client/stream/containers/StreamContainer.tsx
index c948c5d84..e263337a2 100644
--- a/src/core/client/stream/containers/StreamContainer.tsx
+++ b/src/core/client/stream/containers/StreamContainer.tsx
@@ -11,7 +11,7 @@ import {
import Stream from "../components/Stream";
-export interface InnerProps {
+interface InnerProps {
asset: Data;
relay: RelayPaginationProp;
}
@@ -23,7 +23,8 @@ export class StreamContainer extends React.Component {
: null;
return (
+`;
+
+exports[`renders correctly when replies are null 1`] = `""`;
diff --git a/src/core/client/stream/containers/__snapshots__/StreamContainer.spec.tsx.snap b/src/core/client/stream/containers/__snapshots__/StreamContainer.spec.tsx.snap
index 5f9e72622..743ef5627 100644
--- a/src/core/client/stream/containers/__snapshots__/StreamContainer.spec.tsx.snap
+++ b/src/core/client/stream/containers/__snapshots__/StreamContainer.spec.tsx.snap
@@ -1,7 +1,8 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
-exports[`renders username and body 1`] = `
+exports[`renders correctly 1`] = `
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 075fd6e54..cbecb8711 100644
--- a/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap
+++ b/src/core/client/stream/test/__snapshots__/loadMore.spec.tsx.snap
@@ -36,47 +36,53 @@ exports[`loads more comments 1`] = `
-
-
+
- Markus
-
-
- Joining Too
-
+
+ Markus
+
+
+ Joining Too
+
+
-
-
+
- Lukas
-
-
- What's up?
-
+
+ Lukas
+
+
+ What's up?
+
+
-
-
+
- Isabelle
-
-
- Hey!
-
+
+ Isabelle
+
+
+ Hey!
+
+
@@ -118,37 +124,41 @@ exports[`renders comment stream 1`] = `
-
-
+
- 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 033/101] 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 7ee9f235421697e7b0bf3cf0e731fb9511345875 Mon Sep 17 00:00:00 2001
From: okbel
Date: Mon, 9 Jul 2018 18:37:46 -0300
Subject: [PATCH 034/101] work in progress
---
package-lock.json | 6 +--
package.json | 2 +-
src/core/client/stream/components/Comment.tsx | 39 ++-----------------
.../stream/components/PermalinkPopover.tsx | 25 ++++++++++++
.../client/ui/components/Button/Button.tsx | 1 +
.../client/ui/components/Popover/Popover.tsx | 23 +++++++++--
src/core/client/ui/hocs/withFowardedRefs.tsx | 9 +++++
7 files changed, 61 insertions(+), 44 deletions(-)
create mode 100644 src/core/client/stream/components/PermalinkPopover.tsx
create mode 100644 src/core/client/ui/hocs/withFowardedRefs.tsx
diff --git a/package-lock.json b/package-lock.json
index 2321cd2cf..a0c6f82dc 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -16549,9 +16549,9 @@
"dev": true
},
"react-popper": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.0.0.tgz",
- "integrity": "sha1-uZRSFE6P5KzHf6PZWajHngemUIQ=",
+ "version": "1.0.0-beta.6",
+ "resolved": "https://registry.npmjs.org/react-popper/-/react-popper-1.0.0-beta.6.tgz",
+ "integrity": "sha1-yyeirFatzLr1+cQTI4cokGkkCDQ=",
"requires": {
"babel-runtime": "6.x.x",
"create-react-context": "^0.2.1",
diff --git a/package.json b/package.json
index 49b0d6ea4..8dc74e5d8 100644
--- a/package.json
+++ b/package.json
@@ -49,7 +49,7 @@
"performance-now": "^2.1.0",
"rc-tooltip": "^3.7.2",
"react-copy-to-clipboard": "^5.0.1",
- "react-popper": "^1.14.3",
+ "react-popper": "^1.0.0-beta.6",
"react-tooltip": "^3.6.1",
"subscriptions-transport-ws": "^0.9.11",
"uuid": "^3.2.1"
diff --git a/src/core/client/stream/components/Comment.tsx b/src/core/client/stream/components/Comment.tsx
index 7bb017b42..014989a51 100644
--- a/src/core/client/stream/components/Comment.tsx
+++ b/src/core/client/stream/components/Comment.tsx
@@ -1,10 +1,9 @@
import cn from "classnames";
import React from "react";
import { StatelessComponent } from "react";
-import CopyToClipboard from "react-copy-to-clipboard";
-import { Manager, Popper, Reference } from "react-popper";
-import { Button, Input, Popover, Typography } from "talk-ui/components";
+import { Typography } from "talk-ui/components";
import * as styles from "./Comment.css";
+import PermalinkPopover from "./PermalinkPopover";
export interface CommentProps {
id: string;
@@ -28,40 +27,8 @@ const Comment: StatelessComponent = props => {
{props.author && props.author.username}
{props.body}
-
-
- {({ ref }) => (
-
- Reference element
-
- )}
-
-
- {({ ref, style, placement, arrowProps }) => (
-
- Popper element
-
- )}
-
-
- }
- >
- Share
-
+
);
diff --git a/src/core/client/stream/components/PermalinkPopover.tsx b/src/core/client/stream/components/PermalinkPopover.tsx
new file mode 100644
index 000000000..cd110dfe3
--- /dev/null
+++ b/src/core/client/stream/components/PermalinkPopover.tsx
@@ -0,0 +1,25 @@
+import React from "react";
+import CopyToClipboard from "react-copy-to-clipboard";
+import { Button, Input, Popover } from "talk-ui/components";
+
+class PermalinkPopover extends React.Component {
+ public render() {
+ const props = this.props;
+ return (
+
+
+
+ Copy
+
+
+ }
+ >
+ Reference element
+
+ );
+ }
+}
+
+export default PermalinkPopover;
diff --git a/src/core/client/ui/components/Button/Button.tsx b/src/core/client/ui/components/Button/Button.tsx
index dadb7a35d..127d16c2e 100644
--- a/src/core/client/ui/components/Button/Button.tsx
+++ b/src/core/client/ui/components/Button/Button.tsx
@@ -49,6 +49,7 @@ class Button extends React.Component {
[classes.secondary]: secondary,
});
+ console.log(this.props);
return (
;
children: React.ReactElement;
+ placement?:
+ | "auto-start"
+ | "auto"
+ | "auto-end"
+ | "top-start"
+ | "top"
+ | "top-end"
+ | "right-start"
+ | "right"
+ | "right-end"
+ | "bottom-end"
+ | "bottom"
+ | "bottom-start"
+ | "left-end"
+ | "left"
+ | "left-start";
}
class Popover extends React.Component {
public render() {
- const { children, body } = this.props;
+ const { children, body, placement = "top" } = this.props;
return (
{({ ref }) => React.cloneElement(children, { ref })}
- {({ ref, placement, style }) =>
+ {({ ref, style }) =>
React.cloneElement(body, {
ref,
style,
- "data-placement": placement,
})
}
diff --git a/src/core/client/ui/hocs/withFowardedRefs.tsx b/src/core/client/ui/hocs/withFowardedRefs.tsx
new file mode 100644
index 000000000..6fe7a726c
--- /dev/null
+++ b/src/core/client/ui/hocs/withFowardedRefs.tsx
@@ -0,0 +1,9 @@
+import React from "react";
+
+export function forwardRef(
+ WrappedComponent: React.ComponentType
+): React.RefForwardingComponent {
+ return React.forwardRef((props, ref) => {
+ return ;
+ });
+}
From 37fb9ece668cb6ec21df4f978f5096aeb8804ca4 Mon Sep 17 00:00:00 2001
From: okbel
Date: Mon, 9 Jul 2018 18:57:41 -0300
Subject: [PATCH 035/101] wip
---
src/core/client/stream/components/Comment.css | 8 --------
src/core/client/stream/components/Comment.tsx | 2 +-
.../stream/components/PermalinkPopover.css | 13 +++++++++++++
.../stream/components/PermalinkPopover.tsx | 19 ++++++++++++-------
src/core/client/ui/components/Input/Input.css | 11 -----------
src/core/client/ui/components/Input/Input.tsx | 14 --------------
src/core/client/ui/components/Input/index.ts | 2 --
src/core/client/ui/components/index.ts | 2 +-
src/core/client/ui/hocs/withFowardedRefs.tsx | 9 ---------
9 files changed, 27 insertions(+), 53 deletions(-)
create mode 100644 src/core/client/stream/components/PermalinkPopover.css
delete mode 100644 src/core/client/ui/components/Input/Input.css
delete mode 100644 src/core/client/ui/components/Input/Input.tsx
delete mode 100644 src/core/client/ui/components/Input/index.ts
delete mode 100644 src/core/client/ui/hocs/withFowardedRefs.tsx
diff --git a/src/core/client/stream/components/Comment.css b/src/core/client/stream/components/Comment.css
index 8e5301ecd..4e23b2d02 100644
--- a/src/core/client/stream/components/Comment.css
+++ b/src/core/client/stream/components/Comment.css
@@ -9,11 +9,3 @@
.author {
font-weight: $font-weight-medium;
}
-
-.shareButton {
- padding: 10px 0;
-}
-
-.input {
- margin-right: 5px;
-}
diff --git a/src/core/client/stream/components/Comment.tsx b/src/core/client/stream/components/Comment.tsx
index 014989a51..a332b42a3 100644
--- a/src/core/client/stream/components/Comment.tsx
+++ b/src/core/client/stream/components/Comment.tsx
@@ -28,7 +28,7 @@ const Comment: StatelessComponent = props => {
{props.body}
);
diff --git a/src/core/client/stream/components/PermalinkPopover.css b/src/core/client/stream/components/PermalinkPopover.css
new file mode 100644
index 000000000..ffc0a1b6c
--- /dev/null
+++ b/src/core/client/stream/components/PermalinkPopover.css
@@ -0,0 +1,13 @@
+.shareButton {
+ composes: button from "talk-ui/shared/typography.css";
+ composes: buttonReset from "talk-ui/shared/buttonReset.css";
+ padding: 10px 0;
+}
+
+.textField {
+ margin-right: 5px;
+}
+
+.root {
+ background-color: #fff;
+}
diff --git a/src/core/client/stream/components/PermalinkPopover.tsx b/src/core/client/stream/components/PermalinkPopover.tsx
index cd110dfe3..7d9bf8ade 100644
--- a/src/core/client/stream/components/PermalinkPopover.tsx
+++ b/src/core/client/stream/components/PermalinkPopover.tsx
@@ -1,22 +1,27 @@
import React from "react";
import CopyToClipboard from "react-copy-to-clipboard";
-import { Button, Input, Popover } from "talk-ui/components";
+import { Button, Popover, TextField } from "talk-ui/components";
+import * as styles from "./PermalinkPopover.css";
-class PermalinkPopover extends React.Component {
+interface InnerProps {
+ commentId: string;
+}
+
+class PermalinkPopover extends React.Component {
public render() {
- const props = this.props;
+ const { commentId } = this.props;
return (
-
-
+
+
+
Copy
}
>
- Reference element
+ Share
);
}
diff --git a/src/core/client/ui/components/Input/Input.css b/src/core/client/ui/components/Input/Input.css
deleted file mode 100644
index 4d2e9e88a..000000000
--- a/src/core/client/ui/components/Input/Input.css
+++ /dev/null
@@ -1,11 +0,0 @@
-.root {
- font-family: "Source Sans Pro";
- font-weight: 400;
- font-size: 16px;
- letter-spacing: calc(0.57em / 16);
- background: #ffffff;
- border: 1px solid #979797;
- box-sizing: border-box;
- border-radius: 1px;
- padding: 5px 20px;
-}
diff --git a/src/core/client/ui/components/Input/Input.tsx b/src/core/client/ui/components/Input/Input.tsx
deleted file mode 100644
index 261b3b1af..000000000
--- a/src/core/client/ui/components/Input/Input.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-import cn from "classnames";
-import React, { InputHTMLAttributes, StatelessComponent } from "react";
-
-import * as styles from "./Input.css";
-
-interface InnerProps extends InputHTMLAttributes {
- classes?: typeof styles;
-}
-
-const Input: StatelessComponent = ({ className, ...rest }) => {
- return ;
-};
-
-export default Input;
diff --git a/src/core/client/ui/components/Input/index.ts b/src/core/client/ui/components/Input/index.ts
deleted file mode 100644
index ae0d7a775..000000000
--- a/src/core/client/ui/components/Input/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export * from "./Input";
-export { default } from "./Input";
diff --git a/src/core/client/ui/components/index.ts b/src/core/client/ui/components/index.ts
index 9f16ee536..66ed5bee4 100644
--- a/src/core/client/ui/components/index.ts
+++ b/src/core/client/ui/components/index.ts
@@ -3,4 +3,4 @@ export { default as Button } from "./Button";
export { default as Center } from "./Center";
export { default as Typography } from "./Typography";
export { default as Popover } from "./Popover";
-export { default as Input } from "./Input";
+export { default as TextField } from "./TextField";
diff --git a/src/core/client/ui/hocs/withFowardedRefs.tsx b/src/core/client/ui/hocs/withFowardedRefs.tsx
deleted file mode 100644
index 6fe7a726c..000000000
--- a/src/core/client/ui/hocs/withFowardedRefs.tsx
+++ /dev/null
@@ -1,9 +0,0 @@
-import React from "react";
-
-export function forwardRef(
- WrappedComponent: React.ComponentType
-): React.RefForwardingComponent {
- return React.forwardRef((props, ref) => {
- return ;
- });
-}
From 50fdabc0c04f23e018c621c1e220346990bc75aa Mon Sep 17 00:00:00 2001
From: okbel
Date: Mon, 9 Jul 2018 19:42:24 -0300
Subject: [PATCH 036/101] ui functionality
---
.../stream/components/PermalinkPopover.tsx | 41 +++++++++++++++++--
.../client/ui/components/Popover/Popover.css | 4 --
.../client/ui/components/Popover/Popover.tsx | 34 ++++++++-------
3 files changed, 57 insertions(+), 22 deletions(-)
diff --git a/src/core/client/stream/components/PermalinkPopover.tsx b/src/core/client/stream/components/PermalinkPopover.tsx
index 7d9bf8ade..776edbccf 100644
--- a/src/core/client/stream/components/PermalinkPopover.tsx
+++ b/src/core/client/stream/components/PermalinkPopover.tsx
@@ -7,21 +7,56 @@ interface InnerProps {
commentId: string;
}
+interface State {
+ copied: boolean;
+ showBody: boolean;
+}
+
class PermalinkPopover extends React.Component {
+ public state: State = {
+ copied: false,
+ showBody: false,
+ };
+
+ public onCopy = async () => {
+ await this.toggleCopied();
+ setTimeout(() => {
+ this.toggleCopied();
+ }, 800);
+ };
+
+ public onClick = () => this.toggleShow();
+
+ public toggleShow = () => {
+ this.setState((state: State) => ({
+ showBody: !state.showBody,
+ }));
+ };
+
+ public toggleCopied = () => {
+ this.setState((state: State) => ({
+ copied: !state.copied,
+ }));
+ };
+
public render() {
const { commentId } = this.props;
+ const { copied, showBody } = this.state;
return (
-
- Copy
+
+ {copied ? "Copied!" : "Copy"}
}
>
- Share
+
+ Share
+
);
}
diff --git a/src/core/client/ui/components/Popover/Popover.css b/src/core/client/ui/components/Popover/Popover.css
index 1a1553256..708964cdb 100644
--- a/src/core/client/ui/components/Popover/Popover.css
+++ b/src/core/client/ui/components/Popover/Popover.css
@@ -13,7 +13,3 @@
border-top-color: transparent !important;
}
}
-
-.clickable {
- pointer-events: all;
-}
diff --git a/src/core/client/ui/components/Popover/Popover.tsx b/src/core/client/ui/components/Popover/Popover.tsx
index 8b55931c2..84be78c8f 100644
--- a/src/core/client/ui/components/Popover/Popover.tsx
+++ b/src/core/client/ui/components/Popover/Popover.tsx
@@ -1,10 +1,11 @@
import React from "react";
import { Manager, Popper, Reference } from "react-popper";
-// import * as styles from "./Popover.css";
+import * as styles from "./Popover.css";
interface InnerProps {
body: React.ReactElement;
children: React.ReactElement;
+ showBody: boolean;
placement?:
| "auto-start"
| "auto"
@@ -25,25 +26,28 @@ interface InnerProps {
class Popover extends React.Component {
public render() {
- const { children, body, placement = "top" } = this.props;
+ const { children, body, placement = "top", showBody = true } = this.props;
return (
{({ ref }) => React.cloneElement(children, { ref })}
-
- {({ ref, style }) =>
- React.cloneElement(body, {
- ref,
- style,
- })
- }
-
+ {showBody && (
+
+ {({ ref, style }) =>
+ React.cloneElement(body, {
+ ref,
+ style,
+ className: styles.root,
+ })
+ }
+
+ )}
);
}
From a18a9ab0c4c615aa2a54c6a84453e7243d971854 Mon Sep 17 00:00:00 2001
From: Chi Vinh Le
Date: Mon, 9 Jul 2018 20:55:36 -0300
Subject: [PATCH 037/101] 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 038/101] 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 039/101] 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 040/101] 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`] = `
>