123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237 |
- import React, { Component } from "react";
- import classnames from "classnames";
- import { Tooltip, Divider } from "antd";
-
- import { LOCALE_DAYJS } from "./config/constant";
- import { CommentContext } from "./context";
- import { CollapseBtn } from "./common/CollapseBtn";
- import { ReplyCard } from "./common/ReplyCard";
- import IconFont from "./common/ScheduleIconFont";
- import ItemToolBar, { TOOL_ACTION_TYPE } from "./common/ItemToolBar";
- import { getUserType, AuthType } from "./utils";
- import dayjs from "./utils/dayjsImport";
-
- import styles from "./CommentItem.less";
- import AudioPlayer from "./common/AudioPlayer";
- import { ContentRender } from "./common/ContentRender";
- import { toggleFavor } from "./utils/commentAjaxLogi";
- import OldCommontEditor from '../editor/OldCommentEditor';
-
- export interface CommentItemData {
- content: string;
- created: number;
- favor_count: number;
- favored: boolean;
- id: string;
- is_speak: boolean;
- medias: any;
- replies: Array<any>;
- reply_count: number;
- user_avatar: string;
- user_id: number;
- user_name: string;
- }
-
- interface IP {
- data: CommentItemData;
- onChangeListItem({
- commentId,
- changeProp,
- }: {
- commentId: string;
- changeProp: any;
- }): any;
- }
-
- interface IS {
- showReply: boolean;
- showReplyEditor: boolean;
- }
-
- export default class CommentItem extends Component<IP, IS> {
- static contextType = CommentContext;
- context!: React.ContextType<typeof CommentContext>;
-
- constructor(props: IP) {
- super(props);
- this.state = {
- showReply: false,
- showReplyEditor: false,
- };
- }
-
- get authType(): AuthType {
- const { currentUser } = this.context;
- const { user_id } = this.props.data;
- return getUserType(currentUser, user_id);
- }
-
- renderCommentTime = (created: number) => {
- const { locale } = this.context;
- return (
- <Tooltip
- placement="top"
- title={dayjs(created * 1000).format("YYYY-MM-DD HH:mm:ss")}
- >
- <span>
- {LOCALE_DAYJS[locale]
- ? dayjs(created * 1000)
- .locale(LOCALE_DAYJS[locale])
- .fromNow()
- : dayjs(created * 1000).fromNow()}
- </span>
- </Tooltip>
- );
- };
-
- renderContent = () => {
- const { is_speak, medias } = this.props.data;
- if (is_speak) {
- return (
- <>
- <div className={styles.speakContent}>[跟读语音]</div>
- <div className={styles.speakMediaWrapper}>
- <AudioPlayer src={medias && medias[0] && medias[0].url} />
- </div>
- </>
- );
- }
- return (
- <div className={styles.commentContent}>
- <ContentRender data={this.props.data} />
- </div>
- );
- };
-
- renderToolBar = () => {
- const { currentUser }: { currentUser: any } = this.context;
- const { showReply, showReplyEditor } = this.state;
- const { onChangeListItem } = this.props;
- const { id, reply_count, favor_count, favored, user_id } = this.props.data;
- // TODO: normal action and private action
- // console.log('this.props.data: ', this.props.data);
- return (
- <ItemToolBar
- authType={this.authType}
- handleReplyClick={() => {
- this.setState({ showReply: !showReply });
- return true;
- }}
- handleNormalClick={async (actionType: string) => {
- console.log("actionType: ", actionType);
- if (actionType === TOOL_ACTION_TYPE.REPLY) {
- this.setState({ showReplyEditor: !showReplyEditor });
- }
- if (actionType === TOOL_ACTION_TYPE.FAVOR) {
- if (currentUser) {
- const res = await toggleFavor({
- favored,
- id,
- commentId: id,
- userId: currentUser.id,
- });
- console.log("res: ", res);
- if (res) {
- onChangeListItem({
- commentId: res.id,
- changeProp: { favor_count: res.favor_count, favored: !favored },
- });
- }
- }
- }
- return true;
- }}
- handlePrivateClick={(actionType: string) => {
- return true;
- }}
- replyCount={reply_count}
- favorCount={favor_count}
- favored={favored}
- />
- );
- };
-
- renderCollapseReplyEditor = () => {
- const { showReplyEditor } = this.state;
- if (!showReplyEditor) return null;
- return <div className={styles.replyEditorWrapper}>
- <OldCommontEditor />
- </div>;
- };
-
- renderCollapseReplyContent = (replyList: Array<any>) => {
- const { locale } = this.context;
- const { showReply } = this.state;
- const { onChangeListItem } = this.props;
- const { id: commentId, replies } = this.props.data;
- if (!showReply) {
- return null;
- }
- return (
- <div className={styles.replyWrapper}>
- <Divider />
- {replyList.map((i, index) => {
- return (
- <div key={`reply_${i.id}`}>
- <ReplyCard
- commentId={commentId}
- replyContent={i}
- locale={locale}
- renderTime={this.renderCommentTime}
- onChangeListItem={async ({ replyId, changeProps }) => {
- const newReplies = replies.map(r => {
- if (r.id === replyId) {
- return {
- ...r,
- ...changeProps,
- }
- }
- return r;
- });
- return onChangeListItem({ commentId, changeProp: { replies: newReplies }, })
- }}
- />
- {index === replyList.length - 1 ? null : <Divider />}
- </div>
- );
- })}
- </div>
- );
- };
-
- render() {
- console.log(`data: `, this.props.data);
- const {
- id,
- user_avatar,
- content,
- user_name,
- created,
- replies,
- } = this.props.data;
- return (
- <article className={styles.wrapper}>
- <div className={styles.avatar}>
- {/* <img src={user_avatar} alt={`avatar_${id}`} /> */}
- <div
- className={styles.avatarImg}
- style={{
- backgroundImage: `url(${user_avatar})`,
- }}
- />
- </div>
- <section className={styles.content}>
- <header>
- <h4>{user_name}</h4>
- {this.renderCommentTime(created)}
- </header>
- {this.renderContent()}
- {this.renderToolBar()}
- {this.renderCollapseReplyEditor()}
- {this.renderCollapseReplyContent(replies)}
- </section>
- </article>
- );
- }
- }
|