<commit_before># Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the GNU Affero General Public License v3.0.
# See the LICENCE file in the repository root for full licence text.

import ClickToCopy from 'click-to-copy'
import { CommentEditor } from 'comment-editor'
import { CommentShowMore } from 'comment-show-more'
import DeletedCommentsCount from 'deleted-comments-count'
import { Observer } from 'mobx-react'
import core from 'osu-core-singleton'
import * as React from 'react'
import { a, button, div, span, textarea } from 'react-dom-factories'
import { ReportReportable } from 'report-reportable'
import { ShowMoreLink } from 'show-more-link'
import { Spinner } from 'spinner'
import { UserAvatar } from 'user-avatar'
import { countMinLines } from 'utils/count-min-lines'

el = React.createElement

deletedUser = username: osu.trans('users.deleted')
commentableMetaStore = core.dataStore.commentableMetaStore
store = core.dataStore.commentStore
userStore = core.dataStore.userStore

uiState = core.dataStore.uiState

export class Comment extends React.PureComponent
  CLIP_LINES = 7
  MAX_DEPTH = 6

  makePreviewElement = document.createElement('div')

  makePreview = (comment) ->
    if comment.isDeleted
      osu.trans('comments.deleted')
    else
      makePreviewElement.innerHTML = comment.messageHtml
      _.truncate makePreviewElement.textContent, length: 100


  constructor: (props) ->
    super props

    @xhr = {}
    @loadMoreRef = React.createRef()

    if osu.isMobile()
      # There's no indentation on mobile so don't expand by default otherwise it will be confusing.
      expandReplies = false
    else if @props.comment.isDeleted
      expandReplies = false
    else if @props.expandReplies?
      expandReplies = @props.expandReplies
    else
      children = uiState.getOrderedCommentsByParentId(@props.comment.id)
      # Collapse if either no children is loaded or current level doesn't add indentation.
      expandReplies = children?.length > 0 && @props.depth < MAX_DEPTH

    @state =
      clipped: true
      postingVote: false
      editing: false
      showNewReply: false
      expandReplies: expandReplies
      lines: null


  componentWillUnmount: =>
    xhr?.abort() for own _name, xhr of @xhr


  componentDidMount: =>
    @setState lines: countMinLines(@props.comment.messageHtml)


  componentDidUpdate: (prevProps) =>
    if prevProps.comment.messageHtml != @props.comment.messageHtml
      @setState lines: countMinLines(@props.comment.messageHtml)


  render: =>
    el Observer, null, () =>
      @children = uiState.getOrderedCommentsByParentId(@props.comment.id) ? []
      parent = store.comments.get(@props.comment.parentId)
      user = @userFor(@props.comment)
      meta = commentableMetaStore.get(@props.comment.commentableType, @props.comment.commentableId)
      longContent = @state.lines? && @state.lines.count >= CLIP_LINES + 2

      modifiers = @props.modifiers?[..] ? []
      modifiers.push 'top' if @props.depth == 0
      modifiers.push 'clip' if @state.clipped && longContent

      repliesClass = 'comment__replies'
      repliesClass += ' comment__replies--indented' if @props.depth < MAX_DEPTH
      repliesClass += ' comment__replies--hidden' if !@state.expandReplies

      div
        className: osu.classWithModifiers 'comment', modifiers
        style:
          '--line-height': if @state.lines? then "#{@state.lines.lineHeight}px" else undefined<commit_msg>Add comment on +2<commit_after># Copyright (c) ppy Pty Ltd <<EMAIL>>. Licensed under the GNU Affero General Public License v3.0.
# See the LICENCE file in the repository root for full licence text.

import ClickToCopy from 'click-to-copy'
import { CommentEditor } from 'comment-editor'
import { CommentShowMore } from 'comment-show-more'
import DeletedCommentsCount from 'deleted-comments-count'
import { Observer } from 'mobx-react'
import core from 'osu-core-singleton'
import * as React from 'react'
import { a, button, div, span, textarea } from 'react-dom-factories'
import { ReportReportable } from 'report-reportable'
import { ShowMoreLink } from 'show-more-link'
import { Spinner } from 'spinner'
import { UserAvatar } from 'user-avatar'
import { countMinLines } from 'utils/count-min-lines'

el = React.createElement

deletedUser = username: osu.trans('users.deleted')
commentableMetaStore = core.dataStore.commentableMetaStore
store = core.dataStore.commentStore
userStore = core.dataStore.userStore

uiState = core.dataStore.uiState

export class Comment extends React.PureComponent
  CLIP_LINES = 7
  MAX_DEPTH = 6

  makePreviewElement = document.createElement('div')

  makePreview = (comment) ->
    if comment.isDeleted
      osu.trans('comments.deleted')
    else
      makePreviewElement.innerHTML = comment.messageHtml
      _.truncate makePreviewElement.textContent, length: 100


  constructor: (props) ->
    super props

    @xhr = {}
    @loadMoreRef = React.createRef()

    if osu.isMobile()
      # There's no indentation on mobile so don't expand by default otherwise it will be confusing.
      expandReplies = false
    else if @props.comment.isDeleted
      expandReplies = false
    else if @props.expandReplies?
      expandReplies = @props.expandReplies
    else
      children = uiState.getOrderedCommentsByParentId(@props.comment.id)
      # Collapse if either no children is loaded or current level doesn't add indentation.
      expandReplies = children?.length > 0 && @props.depth < MAX_DEPTH

    @state =
      clipped: true
      postingVote: false
      editing: false
      showNewReply: false
      expandReplies: expandReplies
      lines: null


  componentWillUnmount: =>
    xhr?.abort() for own _name, xhr of @xhr


  componentDidMount: =>
    @setState lines: countMinLines(@props.comment.messageHtml)


  componentDidUpdate: (prevProps) =>
    if prevProps.comment.messageHtml != @props.comment.messageHtml
      @setState lines: countMinLines(@props.comment.messageHtml)


  render: =>
    el Observer, null, () =>
      @children = uiState.getOrderedCommentsByParentId(@props.comment.id) ? []
      parent = store.comments.get(@props.comment.parentId)
      user = @userFor(@props.comment)
      meta = commentableMetaStore.get(@props.comment.commentableType, @props.comment.commentableId)
      # Only clip if there are at least CLIP_LINES + 2 lines to ensure there are enough contents
      # being clipped instead of just single lone line (or worse no more lines because of rounding up).
      longContent = @state.lines? && @state.lines.count >= CLIP_LINES + 2

      modifiers = @props.modifiers?[..] ? []
      modifiers.push 'top' if @props.depth == 0
      modifiers.push 'clip' if @state.clipped && longContent

      repliesClass = 'comment__replies'
      repliesClass += ' comment__replies--indented' if @props.depth < MAX_DEPTH
      repliesClass += ' comment__replies--hidden' if !@state.expandReplies

      div
        className: osu.classWithModifiers 'comment', modifiers
        style:
          '--line-height': if @state.lines? then "#{@state.lines.lineHeight}px" else undefined
{'fraction_non_alphanumeric': 0.1012533445993522, 'fraction_numerical': 0.003098155189409942, 'mean_word_length': 3.6387981711299804, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 25, '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': '7056187', 'n_tokens_mistral': 2135, 'n_tokens_neox': 2105, 'n_words': 565}