<commit_before>import React from 'react'
import { Link } from 'react-router'
import * as MAPPING_TYPES from '../../constants/mapping_types'
import { getLinkObject } from '../base/json_helper'
import { body, regionItems, setModels } from './RegionParser'
import Avatar from '../assets/Avatar'
import ContentWarningButton from '../posts/ContentWarningButton'
import PostTools from '../posts/PostTools'
import { RepostIcon } from '../posts/PostIcons'
import RelationsGroup from '../relationships/RelationsGroup'

function getPostDetailPath(author, post) {
  return `/${author.username}/post/${post.token}`
}

function header(post, author) {
  if (!post || !author) { return null }
  return (
    <header className="PostHeader" key={`PostHeader_${post.id}`}>
      <div className="PostHeaderAuthor">
        <Link className="PostHeaderLink" to={`/${author.username}`}>
          <Avatar sources={author.avatar} />
          <span>{`@${author.username}`}</span>
        </Link>
      </div>
      <RelationsGroup user={author} />
    </header>
  )
}

function repostHeader(post, repostAuthor, repostSource, repostedBy) {
  if (!post || !repostedBy) { return null }
  return (
    <header className="RepostHeader" key={`RepostHeader_${post.id}`}>
      <div className="RepostHeaderAuthor">
        <Link className="PostHeaderLink" to={`/${repostAuthor.username}`}>
          <Avatar sources={repostAuthor.avatar} />
          <span>{`@${repostAuthor.username}`}</span>
        </Link>
      </div>
      <div className="RepostHeaderReposter">
        <Link className="PostHeaderLink" to={`/${repostedBy.username}`}>
          <RepostIcon />
          {` by @${repostedBy.username}`}
        </Link>
      </div>
      <RelationsGroup user={repostAuthor} />
    </header>
  )
}

function footer(post, author, currentUser) {
  if (!author) { return null }
  return (
    <PostTools
      author={author}
      post={post}
      currentUser={currentUser}
      key={`PostTools_${post.id}`}
    />
  )
}

export function parsePost(post, json, currentUser, isGridLayout = true) {
  if (!post) { return null }
  setModels(json)
  const author = json[MAPPING_TYPES.USERS][post.authorId]
  const cells = []
  const postDetailPath = getPostDetailPath(author, post)

  if (post.repostContent && post.repostContent.length) {
    const authorLinkObject = getLinkObject(post, 'repostAuthor', json)
    const sourceLinkObject = getLinkObject(post, 'repostedSource', json)
    cells.push(repostHeader(post, authorLinkObject, sourceLinkObject, author))
    if (post.contentWarning) {
      cells.push(<ContentWarningButton post={post}/>)
    }
    // this is weird, but the post summary is
    // actually the repost summary on reposts
    if (isGridLayout) {
      cells.push(body(post.summary, post.id, isGridLayout, postDetailPath))
    } else {
      cells.push(body(post.repostContent, `repost_${post.id}`, isGridLayout, postDetailPath))
      if (post.content && post.content.length) {
        cells.push(body(post.content, post.id, isGridLayout, postDetailPath))
      }
    }
  } else {
    cells.push(header(post, author))

    if (post.contentWarning) {
      cells.push(<ContentWarningButton post={post}/>)
    }

    const content = isGridLayout ? post.summary : post.content
    cells.push(body(content, post.id, isGridLayout, postDetailPath))
  }
  cells.push(footer(post, author, currentUser))
  setModels({})
  return cells
}

export function parseSummary(post, json, only = null) {
  setModels(json)
  return regionItems(post.summary, only, false)
}
<commit_msg>Add comments to page<commit_after>import React from 'react'
import { Link } from 'react-router'
import * as MAPPING_TYPES from '../../constants/mapping_types'
import { getLinkObject } from '../base/json_helper'
import { loadComments } from '../../actions/posts';
import { body, regionItems, setModels } from './RegionParser'
import Avatar from '../assets/Avatar'
import ContentWarningButton from '../posts/ContentWarningButton'
import PostTools from '../posts/PostTools'
import StreamComponent from '../streams/StreamComponent'
import { RepostIcon } from '../posts/PostIcons'
import RelationsGroup from '../relationships/RelationsGroup'

function getPostDetailPath(author, post) {
  return `/${author.username}/post/${post.token}`
}

function commentStream(post) {
  const action = loadComments(post)
  return (
    <StreamComponent key={`Comments_${post.id}`} action={action} />
  )
}

function header(post, author) {
  if (!post || !author) { return null }
  return (
    <header className="PostHeader" key={`PostHeader_${post.id}`}>
      <div className="PostHeaderAuthor">
        <Link className="PostHeaderLink" to={`/${author.username}`}>
          <Avatar sources={author.avatar} />
          <span>{`@${author.username}`}</span>
        </Link>
      </div>
      <RelationsGroup user={author} />
    </header>
  )
}

function repostHeader(post, repostAuthor, repostSource, repostedBy) {
  if (!post || !repostedBy) { return null }
  return (
    <header className="RepostHeader" key={`RepostHeader_${post.id}`}>
      <div className="RepostHeaderAuthor">
        <Link className="PostHeaderLink" to={`/${repostAuthor.username}`}>
          <Avatar sources={repostAuthor.avatar} />
          <span>{`@${repostAuthor.username}`}</span>
        </Link>
      </div>
      <div className="RepostHeaderReposter">
        <Link className="PostHeaderLink" to={`/${repostedBy.username}`}>
          <RepostIcon />
          {` by @${repostedBy.username}`}
        </Link>
      </div>
      <RelationsGroup user={repostAuthor} />
    </header>
  )
}

function footer(post, author, currentUser) {
  if (!author) { return null }
  return (
    <PostTools
      author={author}
      post={post}
      currentUser={currentUser}
      key={`PostTools_${post.id}`}
    />
  )
}

export function parsePost(post, json, currentUser, isGridLayout = true) {
  if (!post) { return null }
  setModels(json)
  const author = json[MAPPING_TYPES.USERS][post.authorId]
  const cells = []
  const postDetailPath = getPostDetailPath(author, post)

  if (post.repostContent && post.repostContent.length) {
    const authorLinkObject = getLinkObject(post, 'repostAuthor', json)
    const sourceLinkObject = getLinkObject(post, 'repostedSource', json)
    cells.push(repostHeader(post, authorLinkObject, sourceLinkObject, author))
    if (post.contentWarning) {
      cells.push(<ContentWarningButton post={post}/>)
    }
    // this is weird, but the post summary is
    // actually the repost summary on reposts
    if (isGridLayout) {
      cells.push(body(post.summary, post.id, isGridLayout, postDetailPath))
    } else {
      cells.push(body(post.repostContent, `repost_${post.id}`, isGridLayout, postDetailPath))
      if (post.content && post.content.length) {
        cells.push(body(post.content, post.id, isGridLayout, postDetailPath))
      }
    }
  } else {
    cells.push(header(post, author))

    if (post.contentWarning) {
      cells.push(<ContentWarningButton post={post}/>)
    }

    const content = isGridLayout ? post.summary : post.content
    cells.push(body(content, post.id, isGridLayout, postDetailPath))
  }
  cells.push(footer(post, author, currentUser))
  if (post.showComments) {
    cells.push(commentStream(post, author, currentUser))
  }
  setModels({})
  return cells
}

export function parseSummary(post, json, only = null) {
  setModels(json)
  return regionItems(post.summary, only, false)
}

{'fraction_non_alphanumeric': 0.14643287377861064, 'fraction_numerical': 0.0, 'mean_word_length': 3.635235732009926, 'pattern_counts': {'":': 0, '<': 60, '<?xml version=': 0, '>': 60, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2254550', 'n_tokens_mistral': 2306, 'n_tokens_neox': 2315, 'n_words': 487}