<commit_before>###
# Copyright 2015 ppy Pty. Ltd.
#
# This file is part of osu!web. osu!web is distributed with the hope of
# attracting more community contributions to the core ecosystem of osu!.
#
# osu!web is free software: you can redistribute it and/or modify
# it under the terms of the Affero GNU General Public License version 3
# as published by the Free Software Foundation.
#
# osu!web is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with osu!web.  If not, see <http://www.gnu.org/licenses/>.
###
{a, div, h1, p} = React.DOM
el = React.createElement

modeSwitcher = document.getElementsByClassName('js-mode-switcher')

BeatmapDiscussions.Main = React.createClass
  mixins: [React.addons.PureRenderMixin]


  getInitialState: ->
    beatmaps = BeatmapHelper.group @props.initial.beatmapset.beatmaps

    beatmapset: @props.initial.beatmapset
    beatmaps: beatmaps
    beatmapsetDiscussion: @props.initial.beatmapsetDiscussion
    currentBeatmap: BeatmapHelper.default(group: beatmaps)
    currentUser: currentUser
    userPermissions: @props.initial.userPermissions
    mode: 'timeline'
    readPostIds: _.chain(@props.initial.beatmapsetDiscussion.beatmap_discussions)
      .map (d) =>
        d.beatmap_discussion_posts.map (r) =>
          r.id
      .flatten()
      .value()
    currentFilter: 'total'


  componentWillMount: ->
    @checkNewTimeoutDefault = 10000
    @checkNewTimeoutMax = 60000
    @cache = {}


  componentDidMount: ->
    $.subscribe 'beatmap:select.beatmapDiscussions', @setCurrentBeatmapId
    $.subscribe 'beatmapset:mode:set.beatmapDiscussions', @setCurrentPlaymode
    $.subscribe 'beatmapsetDiscussion:update.beatmapDiscussions', @setBeatmapsetDiscussion
    $.subscribe 'beatmapset:update.beatmapDiscussions', @setBeatmapset
    $.subscribe 'beatmapDiscussion:jump.beatmapDiscussions', @jumpTo
    $.subscribe 'beatmapDiscussion:setMode.beatmapDiscussions', @setMode
    $.subscribe 'beatmapDiscussionPost:markRead.beatmapDiscussions', @markPostRead
    $.subscribe 'beatmapDiscussion:filter.beatmapDiscussions', @setFilter

    @jumpByHash()
    @checkNewTimeout = Timeout.set @checkNewTimeoutDefault, @checkNew


  componentWillUpdate: ->
    @cache = {}


  componentWillUnmount: ->
    $.unsubscribe '.beatmapDiscussions'

    Timeout.clear @checkNewTimeout
    @checkNewAjax?.abort()


  render: ->
    div null,
      el BeatmapDiscussions.Header,
        beatmapset: @state.beatmapset
        beatmaps: @state.beatmaps
        currentBeatmap: @state.currentBeatmap
        currentDiscussions: @currentDiscussions()
        currentUser: @state.currentUser
        currentFilter: @state.currentFilter
        beatmapsetDiscussion: @state.beatmapsetDiscussion
        users: @users()

      el BeatmapDiscussions.ModeSwitcher,
        mode: @state.mode

      div
        className: 'osu-layout__section osu-layout__section--extra'
        el BeatmapDiscussions.NewDiscussion,
          currentUser: @state.currentUser
          currentBeatmap: @state.currentBeatmap
          mode: @state.mode

        el BeatmapDiscussions.Discussions,
          beatmapset: @state.beatmapset
          beatmapsetDiscussion: @state.beatmapsetDiscussion
          currentBeatmap: @state.currentBeatmap
          currentDiscussions: @currentDiscussions()
          currentFilter: @state.currentFilter
          currentUser: @state.currentUser
          mode: @state.mode
          readPostIds: @state.readPostIds
          userPermissions: @state.userPermissions
          users: @users()


  checkNew: ->
    @nextTimeout ?= @checkNewTimeoutDefault

    Timeout.clear @checkNewTimeout

    @checkNewAjax = $.ajax document.location.pathname,
      data:
        format: 'json'
        last_updated: moment(@state.beatmapsetDiscussion.updated_at).unix()

    .done (data) =>
      if data.updated? && !data.updated
        @nextTimeout *= 2
        return

      @nextTimeout = @checkNewTimeoutDefault

      @setBeatmapsetDiscussion null, beatmapsetDiscussion: data.beatmapsetDiscussion

    .always =>
      @nextTimeout = Math.min @nextTimeout, @checkNewTimeoutMax

      @checkNewTimeout = Timeout.set @nextTimeout, @checkNew


  currentDiscussions: ->
    if !@cache.currentDiscussions?
      general = []
      timeline = []
      timelineByFilter =
        total: {}
        resolved: {}
        pending: {}
        praises: {}
        mine: {}

      for d in @state.beatmapsetDiscussion.beatmap_discussions
        if d.timestamp?
          continue if d.beatmap_id != @state.currentBeatmap.id

          timeline.push d
          timelineByFilter.total[d.id] = d

          if d.message_type == 'praise'
            timelineByFilter.praises[d.id] = d
          else if d.timestamp?
            if d.resolved
              timelineByFilter.resolved[d.id] = d
            else
              timelineByFilter.pending[d.id] = d

          if d.user_id == @state.currentUser.id
            timelineByFilter.mine[d.id] = d

        else
          general.push d

      _.orderBy timeline, ['timestamp', 'id']
      _.orderBy general, 'id'

      @cache.currentDiscussions =
        general: general
        timeline: timeline
        timelineByFilter: timelineByFilter

    @cache.currentDiscussions


  jumpByHash: ->
    jumpId = document.location.hash.match(/\/(\d+)/)?[1]

    if jumpId?
      return $.publish 'beatmapDiscussion:jump', id: parseInt(jumpId, 10)

    beatmapId = document.location.hash.match(/:(\d+)/)?[1]
    beatmapId ?= @state.currentBeatmap.id
    $.publish 'beatmap:select', id: parseInt(beatmapId, 10)


  jumpTo: (_e, {id}) ->
    discussion = @state.beatmapsetDiscussion.beatmap_discussions.find (d) => d.id == id

    return if !discussion?

    mode = if discussion.timestamp? then 'timeline' else 'general'
<commit_msg>Forgot to actually store the sorted array<commit_after>###
# Copyright 2015 ppy Pty. Ltd.
#
# This file is part of osu!web. osu!web is distributed with the hope of
# attracting more community contributions to the core ecosystem of osu!.
#
# osu!web is free software: you can redistribute it and/or modify
# it under the terms of the Affero GNU General Public License version 3
# as published by the Free Software Foundation.
#
# osu!web is distributed WITHOUT ANY WARRANTY; without even the implied
# warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with osu!web.  If not, see <http://www.gnu.org/licenses/>.
###
{a, div, h1, p} = React.DOM
el = React.createElement

modeSwitcher = document.getElementsByClassName('js-mode-switcher')

BeatmapDiscussions.Main = React.createClass
  mixins: [React.addons.PureRenderMixin]


  getInitialState: ->
    beatmaps = BeatmapHelper.group @props.initial.beatmapset.beatmaps

    beatmapset: @props.initial.beatmapset
    beatmaps: beatmaps
    beatmapsetDiscussion: @props.initial.beatmapsetDiscussion
    currentBeatmap: BeatmapHelper.default(group: beatmaps)
    currentUser: currentUser
    userPermissions: @props.initial.userPermissions
    mode: 'timeline'
    readPostIds: _.chain(@props.initial.beatmapsetDiscussion.beatmap_discussions)
      .map (d) =>
        d.beatmap_discussion_posts.map (r) =>
          r.id
      .flatten()
      .value()
    currentFilter: 'total'


  componentWillMount: ->
    @checkNewTimeoutDefault = 10000
    @checkNewTimeoutMax = 60000
    @cache = {}


  componentDidMount: ->
    $.subscribe 'beatmap:select.beatmapDiscussions', @setCurrentBeatmapId
    $.subscribe 'beatmapset:mode:set.beatmapDiscussions', @setCurrentPlaymode
    $.subscribe 'beatmapsetDiscussion:update.beatmapDiscussions', @setBeatmapsetDiscussion
    $.subscribe 'beatmapset:update.beatmapDiscussions', @setBeatmapset
    $.subscribe 'beatmapDiscussion:jump.beatmapDiscussions', @jumpTo
    $.subscribe 'beatmapDiscussion:setMode.beatmapDiscussions', @setMode
    $.subscribe 'beatmapDiscussionPost:markRead.beatmapDiscussions', @markPostRead
    $.subscribe 'beatmapDiscussion:filter.beatmapDiscussions', @setFilter

    @jumpByHash()
    @checkNewTimeout = Timeout.set @checkNewTimeoutDefault, @checkNew


  componentWillUpdate: ->
    @cache = {}


  componentWillUnmount: ->
    $.unsubscribe '.beatmapDiscussions'

    Timeout.clear @checkNewTimeout
    @checkNewAjax?.abort()


  render: ->
    div null,
      el BeatmapDiscussions.Header,
        beatmapset: @state.beatmapset
        beatmaps: @state.beatmaps
        currentBeatmap: @state.currentBeatmap
        currentDiscussions: @currentDiscussions()
        currentUser: @state.currentUser
        currentFilter: @state.currentFilter
        beatmapsetDiscussion: @state.beatmapsetDiscussion
        users: @users()

      el BeatmapDiscussions.ModeSwitcher,
        mode: @state.mode

      div
        className: 'osu-layout__section osu-layout__section--extra'
        el BeatmapDiscussions.NewDiscussion,
          currentUser: @state.currentUser
          currentBeatmap: @state.currentBeatmap
          mode: @state.mode

        el BeatmapDiscussions.Discussions,
          beatmapset: @state.beatmapset
          beatmapsetDiscussion: @state.beatmapsetDiscussion
          currentBeatmap: @state.currentBeatmap
          currentDiscussions: @currentDiscussions()
          currentFilter: @state.currentFilter
          currentUser: @state.currentUser
          mode: @state.mode
          readPostIds: @state.readPostIds
          userPermissions: @state.userPermissions
          users: @users()


  checkNew: ->
    @nextTimeout ?= @checkNewTimeoutDefault

    Timeout.clear @checkNewTimeout

    @checkNewAjax = $.ajax document.location.pathname,
      data:
        format: 'json'
        last_updated: moment(@state.beatmapsetDiscussion.updated_at).unix()

    .done (data) =>
      if data.updated? && !data.updated
        @nextTimeout *= 2
        return

      @nextTimeout = @checkNewTimeoutDefault

      @setBeatmapsetDiscussion null, beatmapsetDiscussion: data.beatmapsetDiscussion

    .always =>
      @nextTimeout = Math.min @nextTimeout, @checkNewTimeoutMax

      @checkNewTimeout = Timeout.set @nextTimeout, @checkNew


  currentDiscussions: ->
    if !@cache.currentDiscussions?
      general = []
      timeline = []
      timelineByFilter =
        total: {}
        resolved: {}
        pending: {}
        praises: {}
        mine: {}

      for d in @state.beatmapsetDiscussion.beatmap_discussions
        if d.timestamp?
          continue if d.beatmap_id != @state.currentBeatmap.id

          timeline.push d
          timelineByFilter.total[d.id] = d

          if d.message_type == 'praise'
            timelineByFilter.praises[d.id] = d
          else if d.timestamp?
            if d.resolved
              timelineByFilter.resolved[d.id] = d
            else
              timelineByFilter.pending[d.id] = d

          if d.user_id == @state.currentUser.id
            timelineByFilter.mine[d.id] = d

        else
          general.push d

      timeline = _.orderBy timeline, ['timestamp', 'id']
      general = _.orderBy general, 'id'

      @cache.currentDiscussions =
        general: general
        timeline: timeline
        timelineByFilter: timelineByFilter

    @cache.currentDiscussions


  jumpByHash: ->
    jumpId = document.location.hash.match(/\/(\d+)/)?[1]

    if jumpId?
      return $.publish 'beatmapDiscussion:jump', id: parseInt(jumpId, 10)

    beatmapId = document.location.hash.match(/:(\d+)/)?[1]
    beatmapId ?= @state.currentBeatmap.id
    $.publish 'beatmap:select', id: parseInt(beatmapId, 10)


  jumpTo: (_e, {id}) ->
    discussion = @state.beatmapsetDiscussion.beatmap_discussions.find (d) => d.id == id

    return if !discussion?

    mode = if discussion.timestamp? then 'timeline' else 'general'

{'fraction_non_alphanumeric': 0.09855072463768116, 'fraction_numerical': 0.0038095238095238095, 'mean_word_length': 3.01329345297441, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 35, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, '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': '13950', 'n_tokens_mistral': 3702, 'n_tokens_neox': 3490, 'n_words': 790}