mirror of
https://github.com/wassname/talk.git
synced 2026-07-12 07:30:27 +08:00
137 lines
3.7 KiB
TypeScript
137 lines
3.7 KiB
TypeScript
import React from "react";
|
|
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";
|
|
import { User } from "../containers/UserBoxContainer";
|
|
|
|
interface InnerProps {
|
|
asset: Data;
|
|
user: User | null;
|
|
relay: RelayPaginationProp;
|
|
}
|
|
|
|
export class StreamContainer extends React.Component<InnerProps> {
|
|
public state = {
|
|
disableLoadMore: false,
|
|
};
|
|
|
|
public render() {
|
|
const comments = this.props.asset.comments.edges.map(edge => edge.node);
|
|
return (
|
|
<Stream
|
|
assetID={this.props.asset.id}
|
|
isClosed={this.props.asset.isClosed}
|
|
comments={comments}
|
|
onLoadMore={this.loadMore}
|
|
hasMore={this.props.relay.hasMore()}
|
|
disableLoadMore={this.state.disableLoadMore}
|
|
user={this.props.user}
|
|
/>
|
|
);
|
|
}
|
|
|
|
private loadMore = () => {
|
|
if (!this.props.relay.hasMore() || this.props.relay.isLoading()) {
|
|
return;
|
|
}
|
|
this.setState({ disableLoadMore: true });
|
|
this.props.relay.loadMore(
|
|
10, // Fetch the next 10 feed items
|
|
error => {
|
|
this.setState({ disableLoadMore: false });
|
|
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<
|
|
{ asset: Data },
|
|
InnerProps,
|
|
FragmentVariables,
|
|
StreamContainerPaginationQueryVariables
|
|
>(
|
|
{
|
|
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
|
|
...ReplyListContainer_comment
|
|
}
|
|
}
|
|
}
|
|
}
|
|
`,
|
|
},
|
|
{
|
|
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<typeof enhanced>;
|
|
export default enhanced;
|