import { Localized } from "fluent-react/compat"; import React, { Component } from "react"; import { graphql } from "react-relay"; import { isBeforeDate } from "talk-common/utils"; import withFragmentContainer from "talk-framework/lib/relay/withFragmentContainer"; import { PropTypesOf } from "talk-framework/types"; import { CommentContainer_asset as AssetData } from "talk-stream/__generated__/CommentContainer_asset.graphql"; import { CommentContainer_comment as CommentData } from "talk-stream/__generated__/CommentContainer_comment.graphql"; import { CommentContainer_me as MeData } from "talk-stream/__generated__/CommentContainer_me.graphql"; import { ShowAuthPopupMutation, withShowAuthPopupMutation, } from "talk-stream/mutations"; import { Button } from "talk-ui/components"; import Comment from "../components/Comment"; import ReplyButton from "../components/Comment/ReplyButton"; import EditCommentFormContainer from "./EditCommentFormContainer"; import PermalinkButtonContainer from "./PermalinkButtonContainer"; import ReplyCommentFormContainer from "./ReplyCommentFormContainer"; interface InnerProps { me: MeData | null; comment: CommentData; asset: AssetData; indentLevel?: number; showAuthPopup: ShowAuthPopupMutation; } interface State { showReplyDialog: boolean; showEditDialog: boolean; editable: boolean; } export class CommentContainer extends Component { private uneditableTimer: any; public state = { showReplyDialog: false, showEditDialog: false, editable: this.isEditable(), }; constructor(props: InnerProps) { super(props); if (this.isEditable()) { this.uneditableTimer = this.updateWhenNotEditable(); } } public componentWillUnmount() { clearTimeout(this.uneditableTimer); } private isEditable() { const isMyComment = !!( this.props.me && this.props.comment.author && this.props.me.id === this.props.comment.author.id ); return ( isMyComment && isBeforeDate(this.props.comment.editing.editableUntil) ); } private openReplyDialog = () => { if (this.props.me) { this.setState(state => ({ showReplyDialog: true, })); } else { this.props.showAuthPopup({ view: "SIGN_IN" }); } }; private openEditDialog = () => { if (this.props.me) { this.setState(state => ({ showEditDialog: true, })); } else { this.props.showAuthPopup({ view: "SIGN_IN" }); } }; private closeEditDialog = () => { this.setState(state => ({ showEditDialog: false, })); }; private closeReplyDialog = () => { this.setState(state => ({ showReplyDialog: false, })); }; private updateWhenNotEditable() { const ms = new Date(this.props.comment.editing.editableUntil).getTime() - Date.now(); if (ms > 0) { return setTimeout(() => this.setState({ editable: false }), ms); } return; } public render() { const { comment, asset, indentLevel } = this.props; const { showReplyDialog, showEditDialog, editable } = this.state; if (showEditDialog) { return ( ); } return ( <> )) || undefined } footer={ <> } /> {showReplyDialog && ( )} ); } } const enhanced = withShowAuthPopupMutation( withFragmentContainer({ me: graphql` fragment CommentContainer_me on User { id } `, asset: graphql` fragment CommentContainer_asset on Asset { ...ReplyCommentFormContainer_asset } `, comment: graphql` fragment CommentContainer_comment on Comment { id author { id username } body createdAt editing { edited editableUntil } pending ...ReplyCommentFormContainer_comment ...EditCommentFormContainer_comment } `, })(CommentContainer) ); export type CommentContainerProps = PropTypesOf; export default enhanced;