import React, { Component } from 'react'; import { Redirect } from 'react-router'; import { BrowserRouter as Router, Route, Link, Switch } from "react-router-dom"; import PropTypes from 'prop-types'; import classNames from 'classnames' import axios from 'axios' import moment from 'moment' import Comments from '../comment/Comments' import update from 'immutability-helper' // import Tooltip from 'material-ui/Tooltip'; import RewardDialog from '../common/RewardDialog'; import {ImageLayerOfCommentHOC} from '../page/layers/ImageLayerOfCommentHOC' import MemoDetailKEEditor from './MemoDetailKEEditor' import MemoDetailMDEditor from './MemoDetailMDEditor' import { bytesToSize } from 'educoder' import { Tooltip } from 'antd' const $ = window.$ function urlStringify(params) { let noParams = true; let paramsUrl = ''; for (let key in params) { noParams = false; paramsUrl += `${key}=${params[key]}&` } if (noParams) { return ''; } paramsUrl = paramsUrl.substring(0, paramsUrl.length - 1); return paramsUrl; } class MemoDetail extends Component { constructor(props) { super(props) this.state = { memoLoading: true, hasMoreComments: false, pageCount: 2, goldRewardDialogOpen: false } } componentDidMount() { window.$("html,body").animate({"scrollTop":0}) const { match } = this.props const memoUrl = `/memos/${match.params.memoId}.json`; this.setState({ memoLoading: true }) axios.get(memoUrl,{ // withCredentials: true, }) .then((response) => { const memo = response.data.memo if (response.data.status === -1) { setTimeout(() => { this.props.showNotification('帖子不存在!') }, 300) this.props.history.push(`/forums`) return; } else if (memo) { // this.setState({...response.data}) const { memo_replies, memo } = response.data; let hasMoreComments = false; if (memo_replies && memo_replies.length === 10 && memo.replies_count > 10) { // 遍历一遍,计算下是否还有评论未加载 let totalCount = 10; memo_replies.forEach(item=>{ totalCount += item.children.length }) if (totalCount < memo.replies_count) { hasMoreComments = true; } } this.setState({ hasMoreComments, pageCount: 2, comments: memo_replies }) delete response.data.memo_replies; // reset response.data.memo.praise_count = response.data.memo.memo_praise_count this.props.initForumState(response.data) // const user = response.data.current_user; // user.tidding_count = response.data.tidding_count; // this.props.initCommonState(user) } this.setState({ memoLoading: false }) }).catch((error) => { console.log(error) }) $('body>#root').on('onMemoDelete', (event) => { // const val = $('body>#root').data('onMemoDelete') const val = window.onMemoDelete ; this.onMemoDelete( JSON.parse(decodeURIComponent(val)) ) }) } componentWillUnmount() { $('body>#root').off('onMemoDelete') } onMemoDelete(memo) { const deleteUrl = `/memos/${memo.id}.json`; // 获取memo list axios.delete(deleteUrl, { // withCredentials: true, }) .then((response) => { const status = response.data.status if (status === 0) { this.props.showNotification('删除成功'); this.props.history.push(`/forums`) } else if (status === -1) { this.props.showNotification('帖子已被删除'); this.props.history.push(`/forums`) } }).catch((error) => { console.log(error) }) } componentDidUpdate(prevProps, prevState, snapshot) { // if (this.props.memo && this.props.memo.content // && (!prevProps.memo || prevProps.memo.content != this.props.memo.content) ) { if (this.props.memo && this.props.memo.content && prevState.memoLoading === true && this.state.memoLoading === false) { // md渲染content,等xhr执行完(即memoLoading变化),memo.content更新后初始化md if (this.props.memo.is_md) { setTimeout(()=>{ var shixunDescr = window.editormd.markdownToHTML("memo_content_editorMd", { htmlDecode: "style,script,iframe", // you can filter tags decode taskList: true, tex: true, // 默认不解析 flowChart: true, // 默认不解析 sequenceDiagram: true // 默认不解析 }); }, 200) } } } clickPraise(){ const { memo } = this.props; const url = `/discusses/${memo.id}/plus.json`; console.log(url) axios.post(url, { container_type: 'Memo', type: 1 // "踩0;赞1" }, { // withCredentials: true } ).then((response) => { console.log(response); const newMemo = Object.assign({}, this.props.memo) newMemo.praise_count = response.data.praise_count newMemo.user_praise = !newMemo.user_praise this.props.initForumState({memo : newMemo }) }).catch((error) => { console.log(error) }) } renderAttachment() { const { memo, attachments_list } = this.props; const attachments = [] attachments_list.forEach((item, index) => { const ar = item.url.split('/') const fileName = item.title let filesize = item.filesize attachments.push(

{fileName}{filesize? ` ${filesize}` : ''}

) }) return attachments; } // ------------------------------------------------------------------------------------------- comments START // ------------------------------------------------------------------------------------------- comments START _getUser() { const { current_user } = this.props; current_user.user_url = `/users/${current_user.login}`; return current_user; } _findById(id, arg_comments) { const comments = arg_comments; for(let i = 0; i < comments.length; i++) { if (id === comments[i].id) { return i; } } } replyComment = (commentContent, id, editor) => { const { showNotification } = this.props; if (!commentContent || commentContent.length === 0) { showNotification('必须填写内容!') return; } if (this.props.memo.id === id ) { // 回复帖子 this.createNewComment(commentContent, id, editor); return; } // /${id} const url = `/memos/reply.json`; const { comments } = this.state; const user = this._getUser(); /* 移除末尾的空行 .replace(/(\n

\n\t
\n<\/p>)*$/g,''); */ if (commentContent) { commentContent = commentContent.replace(/(\n

\n\t
\n<\/p>)*$/g,''); } axios.post(url, { parent_id: id, content: commentContent }, { // withCredentials: true } ).then((response) => { response.data.memo = response.data if (response.data.memo) { let newDiscuss = response.data.memo; var commentIndex = this._findById(id, comments); let comment = comments[commentIndex]; if (!comment.children ) { comment.children = [] } // TODO userName iamge_url comment.children.push( { "can_delete": true, "content": commentContent, "image_url": user.image_url, "username": user.username, "user_login": user.login, "id": newDiscuss.id, // "position": newDiscuss.position, "time": "1分钟前", "praise_count": 0, "user_id": newDiscuss.author_id, }) comments[commentIndex] = comment // ke editor.html && editor.html('') // md if (editor.setValue) { editor.setValue('') const $ = window.$ var view_selector = `.commentItemMDEditorView_${id}` $(view_selector).hide(); } this.setState({ // runTesting: false, comments: comments }, ()=>{ // keditor代码美化 editor.html && window.prettyPrint() }) const newMemo2 = Object.assign({}, this.props.memo); newMemo2.replies_count = newMemo2.replies_count + 1; this.props.initForumState({ memo: newMemo2 }) } console.log(response) }).catch((error) => { console.log(error) }) } deleteComment = (parrentComment, childCommentId) => { let deleteCommentId = parrentComment.id if (childCommentId) { deleteCommentId = childCommentId; } const url = `/memos/${deleteCommentId}.json` let comments = this.state.comments; axios.delete(url, { // withCredentials: true } ).then((response) => { // TODO 删除成功或失败 if (response.data && response.data.status === 0) { const commentIndex = this._findById(parrentComment.id, comments); // https://stackoverflow.com/questions/29527385/removing-element-from-array-in-component-state if (!childCommentId) { this.setState((prevState) => ({ comments: update(prevState.comments, {$splice: [[commentIndex, 1]]}) })) // if (this.state.comments.length <= 5) { // this.fetchComment() // } } else { let childCommentIndex = this._findById(childCommentId, comments[commentIndex].children); comments[commentIndex].children = update(comments[commentIndex].children, {$splice: [[childCommentIndex, 1]]}) this.setState({ comments }) } const newMemo = Object.assign({}, this.props.memo); newMemo.replies_count = newMemo.replies_count - 1; this.props.initForumState({ memo: newMemo }) } console.log(response) }).catch((error) => { console.log(error) }) } // 评论点赞 commentPraise = (discussId) => { const { comments } = this.state; const commentIndex = this._findById(discussId, comments); const url = `/discusses/${discussId}/plus.json` axios.post(url, { // id: discussId, // container_id: challenge.id, container_type: 'Memo', //Discuss type: comments[commentIndex].user_praise === true ? 0 : 1, // "踩0;赞1" }, { // withCredentials: true } ).then((response) => { if (response.data.praise_count === 0 || response.data.praise_count) { comments[commentIndex].user_praise = !comments[commentIndex].user_praise; comments[commentIndex].praise_count = response.data.praise_count; this.setState({ comments }) } console.log(response) }).catch((error) => { console.log(error) }) } rewardCode = (parrentComment, childComment, amount) => { const { showNotification } = this.props; const { comments } = this.state; let handleComment = parrentComment if (childComment) { handleComment = childComment; } let handleCommentId = handleComment.id; const url = `/discusses/${handleCommentId}/reward_code.json` axios.post(url, { id: handleCommentId, container_type: 'Memo', score: amount, user_id: handleComment.user_id }, { // withCredentials: true } ).then((response) => { if (response.data && response.data.code) { const commentIndex = this._findById(parrentComment.id, comments); if (childComment) { const childCommentIndex = this._findById(handleComment.id, parrentComment.children); const newChildComment = Object.assign({}, childComment); newChildComment.reward = response.data.code parrentComment.children[childCommentIndex] = newChildComment comments[commentIndex] = parrentComment; this.setState({ comments }) } else { comments[commentIndex].reward = response.data.code; this.setState({ comments }) } } }).catch((error) => { console.log(error) showNotification('奖励失败,请联系系统管理员!') }) } hiddenComment = (item, childCommentId) => { const id = item.id const { showNotification } = this.props; const user = this._getUser(); const url = `/memos/${id}/hidden.json` const { comments } = this.state; const commentIndex = this._findById(id, comments); const comment = comments[commentIndex]; axios.post(url, { hidden: !comment.hidden ? "1" : "0" }, { // withCredentials: true } ).then((response) => { if (response.data.status === -1) { showNotification(response.data.message) return; } if (response.data.status === 0) { if (!childCommentId) { comment.hidden = !comment.hidden; this.setState({ comments: comments }) } else { // TODO 目前子回复没hidden字段 let childCommentIndex = this._findById(childCommentId, comments[commentIndex].children); const childComment = comments[commentIndex].children[childCommentIndex] childComment.hidden = !childComment.hidden; this.setState({ comments }) } } // {"message":"Couldn't find Discuss with id=911","status":-1} console.log(response) }).catch((error) => { console.log(error) }) } createNewComment = (commentContent, id, editor) => { let content = commentContent; const { memo } = this.props; if(content != undefined){ content = content.replace(/(\n

\n\t
\n<\/p>)*$/g,''); var beforeImage = content.split(""); if(beforeImage[0] == "" && afterImage[1] == ""){ window.notice_box('不支持纯图片评论
请在评论中增加文字信息'); return; } } // /${memo.id} const url = `/memos/reply.json`; let { comments } = this.state; const user = this._getUser(); axios.post(url, { parent_id: memo.id, content: content }, { // withCredentials: true } ).then((response) => { if (response.data.status === -1) { console.error('服务端异常') return; } if (response.data) { response.data.memo = response.data const newMemo = response.data.memo; // ke editor.html && editor.html(''); editor.afterBlur && editor.afterBlur() // md editor.setValue && editor.setValue('') if (!comments) { comments = []; } comments.unshift( { "can_delete": true, "admin": user.admin, "content": content, "image_url": user.image_url, "username": user.username, "user_login": user.login, "id": newMemo.id, "reward": null, "hidden": newMemo.hidden, "user_praise": false, "time": "1分钟前", "praise_count": 0, "user_id": user.user_id, }) this.setState({ comments }) const newMemo2 = Object.assign({}, this.props.memo); newMemo2.replies_count = newMemo2.replies_count + 1; this.props.initForumState({ memo: newMemo2 }) console.log(response) } }).catch((error) => { console.log(error) }) } moreMemos = () => { let { comments, pageCount } = this.state; let { memo } = this.props; const user = this._getUser(); const url = `/memos/${memo.id}/more_reply.json?page=${pageCount}`; axios.get(url, { }, { // withCredentials: true } ).then((response) => { if (response.data.status === -1) { console.error('服务端异常') return; } let { memo_replies } = response.data; if (!memo_replies || memo_replies.length === 0) { this.setState({ hasMoreComments: false }) return; } if (response.data.memos_count) { const newComments = comments.concat(memo_replies); const hasMoreComments = memo_replies.length === 10 this.setState({ comments: newComments, hasMoreComments, pageCount: pageCount+1 }) } }).catch((error) => { console.log(error) }) } // ------------------------------------------------------------------------------------------- comments END // ------------------------------------------------------------------------------------------- comments END // 置顶 setTop(memo) { const params = { sticky: memo.sticky ? 0 : 1, } if (this.state.p_s_order) { params.order = this.state.p_s_order; } if (this.state.p_forum_id) { params.forum_id = this.state.p_forum_id; } let paramsUrl = urlStringify(params) const set_top_or_down_Url = `/memos/${memo.id}/sticky_or_cancel.json?${paramsUrl}`; // 获取memo list axios.post(set_top_or_down_Url, { // withCredentials: true, }) .then((response) => { const status = response.data.status if (status === 0) { this.props.showNotification( memo.sticky ? '取消置顶成功' : '置顶成功'); memo.sticky = memo.sticky ? false : true this.setState({ memo: Object.assign({}, memo) }) } }).catch((error) => { console.log(error) }) } // --------------------------------------------------------------------------------------------帖子獎勵 rewardCodeMemo = (inputVal) => { console.log(inputVal) const { memo, author_info } = this.props; const newMemo = Object.assign({}, memo); const _reward = parseInt(inputVal) const url = `/discusses/${memo.id}/reward_code.json` axios.post(url, { id: memo.id, container_type: 'Memo', score: _reward, user_id: author_info.user_id }, { // withCredentials: true, }) .then((response) => { const { code } = response.data; if (code > 0) { newMemo.reward = code this.props.initForumState({ memo: newMemo }) this.props.showNotification( '奖励成功' ); } else { this.props.showNotification( '奖励失败,请联系系统管理员!' ); } }).catch((error) => { console.log(error) }) } setRewardDialogVisible = (visible) => { this.setState({ goldRewardDialogOpen: visible }) } showRewardDialog = () => { this.setState({ goldRewardDialogOpen: true }) } // --------------------------------------------------------------------------------------------帖子獎勵 END showCommentInput = () => { if (window.__useKindEditor === true) { this.refs.editor.showEditor(); } else { this.refs.editor.showEditor(); } } render() { const { match, history } = this.props const { memo, recommend_shixun, current_user,author_info } = this.props; const { comments, hasMoreComments, goldRewardDialogOpen } = this.state; if (!memo || this.state.memoLoading) { return

} let _current_user = {} if (current_user) { _current_user = current_user } (_current_user.user_url = `/users/${_current_user.login}`); memo.isDetailPage = true; // TODO 图片上传地址 return (
{/* fl with100 */}
{/* overflowHidden1 */} {memo.subject + memo.subject} { memo.sticky && 置顶} { !!memo.reward && {memo.reward} }
{ _current_user && (_current_user.admin === true || _current_user.user_id === author_info.user_id) && } 返回
{moment(memo.time).fromNow()} 发布
{ _current_user.admin && } {memo.viewed_count} { !!memo.replies_count && {memo.replies_count} }
{ !memo.is_md ?
:
}

{this.clickPraise()}} >
{memo.praise_count}

{ this.props.attachments_list &&
{this.renderAttachment()}
}
{ window.__useKindEditor === true ? : } {/* onClick={ this.createNewComment } */}
全部回复 {memo.replies_count}
{ hasMoreComments ?
查看更多评论
写评论
:
写评论
}
); } } export default ImageLayerOfCommentHOC() (MemoDetail);