<commit_before>React = require 'react'
Comment = require './comment'
CommentBox = require './comment-box'
commentValidations = require './lib/comment-validations'
{getErrors} = require './lib/validations'
Router = require 'react-router'
talkClient = require '../api/talk'
Paginator = require './lib/paginator'
PromiseRenderer = require '../components/promise-renderer'
upvotedByCurrentUser = require './lib/upvoted-by-current-user'
Moderation = require './lib/moderation'
{timestamp} = require './lib/time'
{Link} = require 'react-router'
merge = require 'lodash.merge'
Avatar = require '../partials/avatar'
DisplayRoles = require './lib/display-roles'
talkConfig = require './config'

PAGE_SIZE = talkConfig.discussionPageSize

module?.exports = React.createClass
  displayName: 'TalkDiscussion'
  mixins: [Router.Navigation]

  getInitialState: ->
    comments: []
    discussion: {}
    commentsMeta: {}
    commentValidationErrors: []

  getDefaultProps: ->
    query: page: 1

  componentWillReceiveProps: (nextProps) ->
    unless nextProps.query.page is @props.query.page
      @setComments(nextProps.query.page ? 1)

  componentDidMount: ->
    @shouldScrollToBottom = true if @props.query?.scrollToLastComment

  componentWillMount: ->
    @setDiscussion()
    @setComments(@props.query.page ? 1)

  commentsRequest: (page) ->
    {board, discussion} = @props.params
    talkClient.type('comments').get({discussion_id: discussion, page_size: PAGE_SIZE, page})

  discussionsRequest: ->
    {discussion} = @props.params
    talkClient.type('discussions').get({id: discussion})

  setComments: (page = @props.query?.page) ->
    @commentsRequest(page)
      .then (comments) =>
        commentsMeta = comments[0]?.getMeta()
        @setState {comments, commentsMeta}, =>
          if @shouldScrollToBottom and comments.length
            @scrollToBottomOfDiscussion()
            @shouldScrollToBottom = false

  scrollToBottomOfDiscussion: ->
    React.findDOMNode(@)?.scrollIntoView(false)

  setDiscussion: ->
    @discussionsRequest()
      .then (discussion) =>
        @setState {discussion: discussion[0]}

  onUpdateComment: (textContent, subject, commentId) ->
    {discussion} = @props.params
    commentToUpdate = talkClient.type('comments').get(id: commentId)

    discussion_id = +discussion
    body = textContent
    focus_id = +subject?.id ? null
    focus_type = 'Subject' if !!focus_id
    comment = merge {}, {discussion_id, body}, ({focus_id, focus_type} if !!focus_id)

    commentToUpdate.update(comment).save()
      .then (comment) =>
        @setComments(@props.query.page)

  onDeleteComment: (commentId) ->
    {board, discussion} = @props.params
    if window.confirm("Are you sure that you want to delete this comment?")
      talkClient.type('comments').get(id: commentId).delete()
        .then (deleted) => @setComments(@props.query.page)

  onSubmitComment: (e, textContent, subject) ->
    {discussion} = @props.params
    user_id = @props.user.id
    discussion_id = +discussion
    body = textContent
    focus_id = +subject?.id ? null
    focus_type = 'Subject' if !!focus_id
    comment = merge {}, {user_id, discussion_id, body}, ({focus_id, focus_type} if !!focus_id)

    talkClient.type('comments').create(comment).save()
      .then (comment) =>
        @setComments(@state.commentsMeta?.page_count)

  onLikeComment: (commentId) ->
    talkClient.type('comments').get(commentId)
      .then (comment) =>
        return alert("Hey you can't upvote your own comment!") if +@props.user.id is +comment.user_id

        voteUrl = (comment.href + if upvotedByCurrentUser(@props.user, comment) then '/remove_upvote' else '/upvote')
        talkClient.request('put', voteUrl, null, {})
          .then (voted) =>
            @setComments(@props.query.page)

  onClickReply: (user, comment) ->
    # TODO: provide link to user / comment
    quotedComment = comment.body.split("\n")
      .map (line) -> "> #{line}"
      .join("\n")

    reply = "> In reply to #{user.display_name}'s comment: \n#{quotedComment}\n\n"
    @setState {reply}

  comment: (data, i) ->
    <Comment
      key={data.id}
      data={data}
      active={+data.id is +@props.query?.comment}
      user={@props.user}
      onClickReply={@onClickReply}
      onLikeComment={@onLikeComment}
      onUpdateComment={@onUpdateComment}
      onDeleteComment={@onDeleteComment}/>

  onClickDeleteDiscussion: ->
    if window.confirm("Are you sure that you want to delete this discussions? All of the comments and discussions will be lost forever.")
      @discussionsRequest().delete()
        .then (deleted) =>
          @setComments(@props.query.page)
          @transitionTo('talk')

  commentValidations: (commentBody) ->
    # TODO: return true if any additional validations fail
    commentValidationErrors = getErrors(commentBody, commentValidations)
    @setState {commentValidationErrors}
    !!commentValidationErrors.length

  onEditSubmit: (e) ->
    e.preventDefault()
    form = document.querySelector('.talk-edit-discussion-form')
    title = form.querySelector('[name="title"]').value
    sticky = form.querySelector('[name="sticky"]').checked
    locked = form.querySelector('[name="locked"]').checked<commit_msg>Transition to correct talk on delete discussion<commit_after>React = require 'react'
Comment = require './comment'
CommentBox = require './comment-box'
commentValidations = require './lib/comment-validations'
{getErrors} = require './lib/validations'
Router = require 'react-router'
talkClient = require '../api/talk'
Paginator = require './lib/paginator'
PromiseRenderer = require '../components/promise-renderer'
upvotedByCurrentUser = require './lib/upvoted-by-current-user'
Moderation = require './lib/moderation'
{timestamp} = require './lib/time'
{Link} = require 'react-router'
merge = require 'lodash.merge'
Avatar = require '../partials/avatar'
DisplayRoles = require './lib/display-roles'
talkConfig = require './config'

PAGE_SIZE = talkConfig.discussionPageSize

module?.exports = React.createClass
  displayName: 'TalkDiscussion'
  mixins: [Router.Navigation]

  getInitialState: ->
    comments: []
    discussion: {}
    commentsMeta: {}
    commentValidationErrors: []

  getDefaultProps: ->
    query: page: 1

  componentWillReceiveProps: (nextProps) ->
    unless nextProps.query.page is @props.query.page
      @setComments(nextProps.query.page ? 1)

  componentDidMount: ->
    @shouldScrollToBottom = true if @props.query?.scrollToLastComment

  componentWillMount: ->
    @setDiscussion()
    @setComments(@props.query.page ? 1)

  commentsRequest: (page) ->
    {board, discussion} = @props.params
    talkClient.type('comments').get({discussion_id: discussion, page_size: PAGE_SIZE, page})

  discussionsRequest: ->
    {discussion} = @props.params
    talkClient.type('discussions').get({id: discussion})

  setComments: (page = @props.query?.page) ->
    @commentsRequest(page)
      .then (comments) =>
        commentsMeta = comments[0]?.getMeta()
        @setState {comments, commentsMeta}, =>
          if @shouldScrollToBottom and comments.length
            @scrollToBottomOfDiscussion()
            @shouldScrollToBottom = false

  scrollToBottomOfDiscussion: ->
    React.findDOMNode(@)?.scrollIntoView(false)

  setDiscussion: ->
    @discussionsRequest()
      .then (discussion) =>
        @setState {discussion: discussion[0]}

  onUpdateComment: (textContent, subject, commentId) ->
    {discussion} = @props.params
    commentToUpdate = talkClient.type('comments').get(id: commentId)

    discussion_id = +discussion
    body = textContent
    focus_id = +subject?.id ? null
    focus_type = 'Subject' if !!focus_id
    comment = merge {}, {discussion_id, body}, ({focus_id, focus_type} if !!focus_id)

    commentToUpdate.update(comment).save()
      .then (comment) =>
        @setComments(@props.query.page)

  onDeleteComment: (commentId) ->
    {board, discussion} = @props.params
    if window.confirm("Are you sure that you want to delete this comment?")
      talkClient.type('comments').get(id: commentId).delete()
        .then (deleted) => @setComments(@props.query.page)

  onSubmitComment: (e, textContent, subject) ->
    {discussion} = @props.params
    user_id = @props.user.id
    discussion_id = +discussion
    body = textContent
    focus_id = +subject?.id ? null
    focus_type = 'Subject' if !!focus_id
    comment = merge {}, {user_id, discussion_id, body}, ({focus_id, focus_type} if !!focus_id)

    talkClient.type('comments').create(comment).save()
      .then (comment) =>
        @setComments(@state.commentsMeta?.page_count)

  onLikeComment: (commentId) ->
    talkClient.type('comments').get(commentId)
      .then (comment) =>
        return alert("Hey you can't upvote your own comment!") if +@props.user.id is +comment.user_id

        voteUrl = (comment.href + if upvotedByCurrentUser(@props.user, comment) then '/remove_upvote' else '/upvote')
        talkClient.request('put', voteUrl, null, {})
          .then (voted) =>
            @setComments(@props.query.page)

  onClickReply: (user, comment) ->
    # TODO: provide link to user / comment
    quotedComment = comment.body.split("\n")
      .map (line) -> "> #{line}"
      .join("\n")

    reply = "> In reply to #{user.display_name}'s comment: \n#{quotedComment}\n\n"
    @setState {reply}

  comment: (data, i) ->
    <Comment
      key={data.id}
      data={data}
      active={+data.id is +@props.query?.comment}
      user={@props.user}
      onClickReply={@onClickReply}
      onLikeComment={@onLikeComment}
      onUpdateComment={@onUpdateComment}
      onDeleteComment={@onDeleteComment}/>

  onClickDeleteDiscussion: ->
    if window.confirm("Are you sure that you want to delete this discussions? All of the comments and discussions will be lost forever.")
      @discussionsRequest().delete()
        .then (deleted) =>
          @setComments(@props.query.page)
          {owner, name} = @props.params
          if (owner and name) then @transitionTo('project-talk', {owner, name}) else @transitionTo('talk')

  commentValidations: (commentBody) ->
    # TODO: return true if any additional validations fail
    commentValidationErrors = getErrors(commentBody, commentValidations)
    @setState {commentValidationErrors}
    !!commentValidationErrors.length

  onEditSubmit: (e) ->
    e.preventDefault()
    form = document.querySelector('.talk-edit-discussion-form')
    title = form.querySelector('[name="title"]').value
    sticky = form.querySelector('[name="sticky"]').checked
    locked = form.querySelector('[name="locked"]').checked
{'fraction_non_alphanumeric': 0.1402089018537687, 'fraction_numerical': 0.0009409993413004611, 'mean_word_length': 3.6168549087749784, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 67, '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': '887765', 'n_tokens_mistral': 3182, 'n_tokens_neox': 3099, 'n_words': 689}