<commit_before>###*

  UI entry point

  @jsx React.DOM

  Under MIT license, see LICENSE file for details
  <NAME> (c) 2013

###

url                           = require 'url'
{extend, result, isFunction}  = require 'underscore'
Backbone                      = require 'backbone'
Record                        = require 'backbone.record'
Backbone.$                    = require 'jqueryify'
React                         = require 'react-tools/build/modules/react'
Timestamp                     = require 'react-time'
DOMEvents                     = require 'react-dom-events'
Textarea                      = require 'react-textarea-autosize'
_BootstrapModal               = require './bootstrap-modal'

AppEvents = extend {}, Backbone.Events,
  componentWillUnmount: ->
    this.stopListening()

LocationAware =
  componentDidMount: ->
    this.router = new Backbone.Router(routes: this.routes)

UserAware =
  getUser: ->
    try
      JSON.parse localStorage.getItem('wall.user')
    catch e
      null

  _handleStorageEvent: (e) ->
    this.forceUpdate() if e.key == 'wall.user'

  componentDidMount: ->
    Backbone.$(window).on "storage", this._handleStorageEvent

  componentWillUnmount: ->
    Backbone.$(window).off "storage", this._handleStorageEvent

HasModal =
  renderModal: ->
    if this.state?.modal
      `<Modal ref="modal"
        onHide={this.onModalHide}
        onClick={this.hideModal}>{this.state.modal}</Modal>` 

  onModalHide: ->
    this.setState(modal: undefined)

  showModal: (screen) ->
    this.setState(modal: screen)

  hideModal: ->
    this.refs.modal.hide()

Screen =
  url: -> result this.props.model, 'screenURL'

class User extends Record

class Item extends Record
  @define 'title', 'uri', 'description', 'created', 'creator'

  url: -> if this.id? then "/api/items/#{this.id}" else "/api/items"
  screenURL: -> if this.id? then "/items/#{this.id}"

class ItemCollection extends Backbone.Collection
  model: Item

class Items extends Record
  @define
    items: ItemCollection

  url: -> '/api/items'
  screenURL: -> '/'

Control = React.createClass
  render: ->
    iconClass = "icon icon-#{this.props.icon}"
    selfClass = "Control #{this.props.class or ''}"
    label = if this.props.label
      `<span class="label">{this.props.label}</span>`
    `<a onClick={this.props.onClick} class={selfClass} href={this.props.href}>
      <i class={iconClass}></i>{label}
     </a>`

ItemsScreen = React.createClass
  mixins: [Screen]
  propTypes:
    model: React.PropTypes.instanceOf(Items).isRequired
  render: ->
    items = this.props.model.items.map (item) => ItemView {item}
    `<div class="ItemsScreen">{items}</div>`

ItemView = React.createClass
  propTypes:
    item: React.PropTypes.instanceOf(Item).isRequired
    externalLink: React.PropTypes.boolean

  renderIcon: ->
    if this.props.item.uri
      `<i class="icon icon-globe"></i>`
    else
      `<i class="icon icon-comments"></i>`

  render: ->
    item = this.props.item
    mainLink = if this.props.externalLink then item.uri else item.screenURL()
    `<div class="ItemView">
      {this.renderIcon()}
      <h4 class="title"><a href={mainLink}>{item.title}</a></h4>
      <a class="uri" href={item.uri}>{url.parse(item.uri).hostname}</a>
      <Timestamp class="created" relative value={item.created} />
     </div>`

FullItemView = React.createClass
  propTypes:
    item: React.PropTypes.instanceOf(Item).isRequired

  render: ->
    item = this.props.item
    `<div class="FullItemView">
      <ItemView externalLink item={item} />
      {item.description && <div class="description">{item.description}</div>}
     </div>`

CommentEditor = React.createClass
  focus: ->
    Backbone.$(this.refs.description.getDOMNode()).focus()

  componentDidMount: ->
    this.focus() if this.props.autofocus

  render: ->
    `<div class="CommentEditor">
      <i class="icon icon-comment"></i>
      <Textarea autosize ref="description" class="description" placeholder="Add comment"></Textarea>
      <div class="Controls">
        <Control onClick={this.props.onSubmit} icon="ok" label="Submit" />
        <Control onClick={this.props.onCancel} icon="remove" label="Cancel" />
      </div>
     </div>`

ItemScreen = React.createClass
  mixins: [Screen]
  propTypes:
    model: React.PropTypes.instanceOf(Item).isRequired

  onAddComment: ->
    this.setState(commentEditorShown: true)

  onCommentCancel: ->
    this.setState(commentEditorShown: false)

  renderCommentEditor: ->
    if this.state?.commentEditorShown
      `<CommentEditor autofocus onCancel={this.onCommentCancel} />`
    else
      `<div class="Controls">
        <Control onClick={this.onAddComment} icon="comment" label="Add comment" />
       </div>`

  render: ->
    `<div class="ItemScreen">
      <FullItemView item={this.props.model} />
      {this.renderCommentEditor()}
     </div>`

SubmitDialog = React.createClass
  mixins: [Screen]

  getInitialState: ->
    {model: new Item}

  onSubmit: (e) ->
    e.preventDefault()
    data =
      title: this.refs.title.getDOMNode().value
      uri: this.refs.uri.getDOMNode().value
      description: this.refs.description.getDOMNode().value
    this.state.model.save(data).then =>
      Wall.show(new ItemScreen(model: this.state.model), trigger: true)
      Wall.hideModal()

  onCancel: ->
    Wall.hideModal()

  render: ->
    item = this.state.model
    `<div class="SubmitDialog">
      <div class="form">
        <input type="text" class="title" ref="title" value={item.title} placeholder="Title" />
        <input type="text" class="uri" ref="uri" value={item.uri} placeholder="URL" />
        <Textarea autosize class="description" ref="description" placeholder="Description">
          {item.description}
        </Textarea>
      </div>
      <div class="Controls">
        <Control onClick={this.onSubmit} icon="ok" label="Submit" />
        <Control onClick={this.onCancel} icon="remove" label="Cancel" />
      </div>
     </div>`

UserView = React.createClass
  render: ->
    `<div class="User"></div>`

Modal = React.createClass
  $getDOMNode: ->
    $ this.getDOMNode()

  componentDidMount: ->
    $node = this.$getDOMNode()
    $node.modal(backdrop: 'static', show: not this.props.hide)
    $node.on 'shown.bs.modal',  this.props.onShow if this.props.onShow?
    $node.on 'hidden.bs.modal', this.props.onHide if this.props.onHide?

  componentWillUnmount: ->
    this.hide()

  hide: ->
    this.$getDOMNode().modal 'hide'

  show: ->
    this.$getDOMNode().modal 'show'

  onBodyClick: (e) ->
    e.stopPropagation() unless e.target == this.refs.modalBody.getDOMNode()

  render: ->
    `<div onClick={this.props.onClick} class="modal fade">
      <div class="modal-dialog">
        <div class="modal-body" ref="modalBody" onClick={this.onBodyClick}>
          {this.props.children}
        </div>
      </div>
     </div>`

LoginDialog = React.createClass
  render: ->
    buttons = for provider in Wall.settings.authProviders
      Control(icon: provider, href: "/auth/#{provider}", label: "Sign in with #{provider}")
    `<div class="LoginDialog">
      <div class="caption">
        Sign in with one of the authentication providers below
      </div>
      <div onClick={Wall.hideModal} class="Controls">{buttons}</div><commit_msg>ui: autofocus on modal dialogs<commit_after>###*

  UI entry point

  @jsx React.DOM

  Under MIT license, see LICENSE file for details
  <NAME> (c) 2013

###

url                           = require 'url'
{extend, result, isArray}     = require 'underscore'
Backbone                      = require 'backbone'
Record                        = require 'backbone.record'
Backbone.$                    = require 'jqueryify'
React                         = require 'react-tools/build/modules/react'
Timestamp                     = require 'react-time'
DOMEvents                     = require 'react-dom-events'
Textarea                      = require 'react-textarea-autosize'
_BootstrapModal               = require './bootstrap-modal'

AppEvents = extend {}, Backbone.Events,
  componentWillUnmount: ->
    this.stopListening()

LocationAware =
  componentDidMount: ->
    this.router = new Backbone.Router(routes: this.routes)

UserAware =
  getUser: ->
    try
      JSON.parse localStorage.getItem('wall.user')
    catch e
      null

  _handleStorageEvent: (e) ->
    this.forceUpdate() if e.key == 'wall.user'

  componentDidMount: ->
    Backbone.$(window).on "storage", this._handleStorageEvent

  componentWillUnmount: ->
    Backbone.$(window).off "storage", this._handleStorageEvent

HasModal =
  renderModal: ->
    if this.state?.modal
      `<Modal ref="modal"
        onShow={this.onModalShow}
        onHide={this.onModalHide}
        onClick={this.hideModal}>{this.state.modal}</Modal>` 

  onModalShow: ->
    this.refs.modal.focus()

  onModalHide: ->
    this.setState(modal: undefined)

  showModal: (screen) ->
    this.setState(modal: screen)

  hideModal: ->
    this.refs.modal.hide()

Screen =
  url: -> result this.props.model, 'screenURL'

class User extends Record

class Item extends Record
  @define 'title', 'uri', 'description', 'created', 'creator'

  url: -> if this.id? then "/api/items/#{this.id}" else "/api/items"
  screenURL: -> if this.id? then "/items/#{this.id}"

class ItemCollection extends Backbone.Collection
  model: Item

class Items extends Record
  @define
    items: ItemCollection

  url: -> '/api/items'
  screenURL: -> '/'

Control = React.createClass
  render: ->
    iconClass = "icon icon-#{this.props.icon}"
    selfClass = "Control #{this.props.class or ''}"
    label = if this.props.label
      `<span class="label">{this.props.label}</span>`
    `<a onClick={this.props.onClick} class={selfClass} href={this.props.href}>
      <i class={iconClass}></i>{label}
     </a>`

ItemsScreen = React.createClass
  mixins: [Screen]
  propTypes:
    model: React.PropTypes.instanceOf(Items).isRequired
  render: ->
    items = this.props.model.items.map (item) => ItemView {item}
    `<div class="ItemsScreen">{items}</div>`

ItemView = React.createClass
  propTypes:
    item: React.PropTypes.instanceOf(Item).isRequired
    externalLink: React.PropTypes.boolean

  renderIcon: ->
    if this.props.item.uri
      `<i class="icon icon-globe"></i>`
    else
      `<i class="icon icon-comments"></i>`

  render: ->
    item = this.props.item
    mainLink = if this.props.externalLink then item.uri else item.screenURL()
    `<div class="ItemView">
      {this.renderIcon()}
      <h4 class="title"><a href={mainLink}>{item.title}</a></h4>
      <a class="uri" href={item.uri}>{url.parse(item.uri).hostname}</a>
      <Timestamp class="created" relative value={item.created} />
     </div>`

FullItemView = React.createClass
  propTypes:
    item: React.PropTypes.instanceOf(Item).isRequired

  render: ->
    item = this.props.item
    `<div class="FullItemView">
      <ItemView externalLink item={item} />
      {item.description && <div class="description">{item.description}</div>}
     </div>`

CommentEditor = React.createClass
  focus: ->
    Backbone.$(this.refs.description.getDOMNode()).focus()

  componentDidMount: ->
    this.focus() if this.props.autofocus

  render: ->
    `<div class="CommentEditor">
      <i class="icon icon-comment"></i>
      <Textarea autosize ref="description" class="description" placeholder="Add comment"></Textarea>
      <div class="Controls">
        <Control onClick={this.props.onSubmit} icon="ok" label="Submit" />
        <Control onClick={this.props.onCancel} icon="remove" label="Cancel" />
      </div>
     </div>`

ItemScreen = React.createClass
  mixins: [Screen]
  propTypes:
    model: React.PropTypes.instanceOf(Item).isRequired

  onAddComment: ->
    this.setState(commentEditorShown: true)

  onCommentCancel: ->
    this.setState(commentEditorShown: false)

  renderCommentEditor: ->
    if this.state?.commentEditorShown
      `<CommentEditor autofocus onCancel={this.onCommentCancel} />`
    else
      `<div class="Controls">
        <Control onClick={this.onAddComment} icon="comment" label="Add comment" />
       </div>`

  render: ->
    `<div class="ItemScreen">
      <FullItemView item={this.props.model} />
      {this.renderCommentEditor()}
     </div>`

SubmitDialog = React.createClass
  mixins: [Screen]

  getInitialState: ->
    {model: new Item}

  focus: ->
    Backbone.$(this.refs.uri.getDOMNode()).focus()

  onSubmit: (e) ->
    e.preventDefault()
    data =
      title: this.refs.title.getDOMNode().value
      uri: this.refs.uri.getDOMNode().value
      description: this.refs.description.getDOMNode().value
    this.state.model.save(data).then =>
      Wall.show(new ItemScreen(model: this.state.model), trigger: true)
      Wall.hideModal()

  onCancel: ->
    Wall.hideModal()

  render: ->
    item = this.state.model
    `<div class="SubmitDialog">
      <div class="form">
        <input type="text" class="title" ref="title" value={item.title} placeholder="Title" />
        <input type="text" class="uri" ref="uri" value={item.uri} placeholder="URL" />
        <Textarea autosize class="description" ref="description" placeholder="Description">
          {item.description}
        </Textarea>
      </div>
      <div class="Controls">
        <Control onClick={this.onSubmit} icon="ok" label="Submit" />
        <Control onClick={this.onCancel} icon="remove" label="Cancel" />
      </div>
     </div>`

UserView = React.createClass
  render: ->
    `<div class="User"></div>`

Modal = React.createClass
  $getDOMNode: ->
    $ this.getDOMNode()

  componentDidMount: ->
    $node = this.$getDOMNode()
    $node.modal(backdrop: 'static', show: not this.props.hide)
    $node.on 'shown.bs.modal',  this.props.onShow if this.props.onShow?
    $node.on 'hidden.bs.modal', this.props.onHide if this.props.onHide?

  componentWillUnmount: ->
    this.hide()

  focus: ->
    children = this.props.children
    children = [children] unless isArray children
    for child in children when child.focus?
      child.focus()

  hide: ->
    this.$getDOMNode().modal 'hide'

  show: ->
    this.$getDOMNode().modal 'show'

  onBodyClick: (e) ->
    e.stopPropagation() unless e.target == this.refs.modalBody.getDOMNode()

  render: ->
    `<div onClick={this.props.onClick} class="modal fade">
      <div class="modal-dialog">
        <div class="modal-body" ref="modalBody" onClick={this.onBodyClick}>
          {this.props.children}
        </div>
      </div>
     </div>`

LoginDialog = React.createClass
  render: ->
    buttons = for provider in Wall.settings.authProviders
      Control(icon: provider, href: "/auth/#{provider}", label: "Sign in with #{provider}")
    `<div class="LoginDialog">
      <div class="caption">
        Sign in with one of the authentication providers below
      </div>
      <div onClick={Wall.hideModal} class="Controls">{buttons}</div>
{'fraction_non_alphanumeric': 0.15265843179377014, 'fraction_numerical': 0.0008055853920515575, 'mean_word_length': 2.9746531483457845, 'pattern_counts': {'":': 0, '<': 145, '<?xml version=': 0, '>': 232, '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': '3549695', 'n_tokens_mistral': 4690, 'n_tokens_neox': 4580, 'n_words': 951}