<commit_before>import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import Button from '@folio/stripes-components/lib/Button';
import TextField from '@folio/stripes-components/lib/TextField';
import { Row, Col } from '@folio/stripes-components/lib/LayoutGrid';
import { Link } from 'react-router-dom';

class ItemInfo extends React.Component {
  static propTypes = {
    stripes: PropTypes.shape({
      intl: PropTypes.object,
    }),
    onClickSelectItem: PropTypes.func,
    item: PropTypes.object,
    editable: PropTypes.bool,
  };

  constructor(props) {
    super(props);
    this.onClickSelectItem = this.onClickSelectItem.bind(this);
    this.onChangeSelectItem = this.onChangeSelectItem.bind(this);
    this.query = '0';
  }

  onClickSelectItem(e) {
    if (e) e.preventDefault();
    this.props.onClickSelectItem(this.query);
  }

  onChangeSelectItem(e) {
    if (e) e.preventDefault();
    this.query = e.target.value;
  }

  render() {
    const item = this.props.item || {};
    const location = item.location;
    const callnumber = item.callNumber;
    const status = item.itemStatus;
    const instance = item.instance;
    const barcode = item.barcode;
    const id = item.id;

    return (

<FormattedMessage id="ui-users.charge.item.title" />

        <Row>
          <Col xs={12} sm={10} md={7} lg={5}>
            <TextField placeholder={this.props.stripes.intl.formatMessage({ id: 'ui-users.charge.item.placeholder' })} onChange={this.onChangeSelectItem} />
          </Col>
          <Col xs={2}>
            <Button onClick={this.onClickSelectItem} disabled={!this.props.editable}><FormattedMessage id="ui-users.charge.item.button" /></Button>
          </Col>
        </Row>
        <Row>
          <Col xs={12} sm={10} md={7} lg={5}>
            <Row><Col xs={12}><FormattedMessage id="ui-users.charge.item.barcode" /></Col></Row>
            <Row>
              <Col xs={12}>

                  <Link to={`/items/view/${id}`}>
                    {barcode}
                  </Link>

              </Col>
            </Row>
          </Col>
        </Row>

        <Row>
          <Col xs={12} sm={10} md={7} lg={5}>
            <Row><Col xs={12}><FormattedMessage id="ui-users.charge.item.instance" /></Col></Row>
            <Row><Col xs={12}>{instance}</Col></Row>
          </Col>
        </Row>

        <Row>
          <Col xs={12} sm={10} md={7} lg={5}>
            <Row>
              <Col xs={4}>
                <Row><Col xs={12}><FormattedMessage id="ui-users.charge.item.status" /></Col></Row>
                <Row><Col xs={12}>{status}</Col></Row>
              </Col>
              <Col xs={4}>
                <Row><Col xs={12}><FormattedMessage id="ui-users.charge.item.callNumber" /></Col></Row>
                <Row><Col xs={12}>{callnumber}</Col></Row>
              </Col>
              <Col xs={4}>
                <Row><Col xs={12}><FormattedMessage id="ui-users.charge.item.location" /></Col></Row>
                <Row><Col xs={12}>{location}</Col></Row>
              </Col>
            </Row>
          </Col>
        </Row>

    );
  }
}

export default ItemInfo;
<commit_msg>Modify size box and button<commit_after>import React from 'react';
import PropTypes from 'prop-types';
import { FormattedMessage } from 'react-intl';
import Button from '@folio/stripes-components/lib/Button';
import TextField from '@folio/stripes-components/lib/TextField';
import { Row, Col } from '@folio/stripes-components/lib/LayoutGrid';
import { Link } from 'react-router-dom';

class ItemInfo extends React.Component {
  static propTypes = {
    stripes: PropTypes.shape({
      intl: PropTypes.object,
    }),
    onClickSelectItem: PropTypes.func,
    item: PropTypes.object,
    editable: PropTypes.bool,
  };

  constructor(props) {
    super(props);
    this.onClickSelectItem = this.onClickSelectItem.bind(this);
    this.onChangeSelectItem = this.onChangeSelectItem.bind(this);
    this.query = '';
  }

  onClickSelectItem(e) {
    if (e) e.preventDefault();
    this.props.onClickSelectItem(this.query);
  }

  onChangeSelectItem(e) {
    if (e) e.preventDefault();
    this.query = e.target.value;
  }

  render() {
    const item = this.props.item || {};
    const location = item.location;
    const callnumber = item.callNumber;
    const status = item.itemStatus;
    const instance = item.instance;
    const barcode = item.barcode;
    const id = item.id;

    return (

<FormattedMessage id="ui-users.charge.item.title" />

        <Row>
          <Col xs={6} sm={5} md={4} lg={3}>
            <TextField placeholder={this.props.stripes.intl.formatMessage({ id: 'ui-users.charge.item.placeholder' })} onChange={this.onChangeSelectItem} />
          </Col>
          <Col xs={2}>
            <Button buttonStyle="primary" onClick={this.onClickSelectItem} disabled={!this.props.editable}><FormattedMessage id="ui-users.charge.item.button" /></Button>
          </Col>
        </Row>
        <Row>
          <Col xs={12} sm={10} md={7} lg={5}>
            <Row><Col xs={12}><FormattedMessage id="ui-users.charge.item.barcode" /></Col></Row>
            <Row>
              <Col xs={12}>

                  <Link to={`/items/view/${id}`}>
                    {barcode}
                  </Link>

              </Col>
            </Row>
          </Col>
        </Row>

        <Row>
          <Col xs={12} sm={10} md={7} lg={5}>
            <Row><Col xs={12}><FormattedMessage id="ui-users.charge.item.instance" /></Col></Row>
            <Row><Col xs={12}>{instance}</Col></Row>
          </Col>
        </Row>

        <Row>
          <Col xs={12} sm={10} md={7} lg={5}>
            <Row>
              <Col xs={4}>
                <Row><Col xs={12}><FormattedMessage id="ui-users.charge.item.status" /></Col></Row>
                <Row><Col xs={12}>{status}</Col></Row>
              </Col>
              <Col xs={4}>
                <Row><Col xs={12}><FormattedMessage id="ui-users.charge.item.callNumber" /></Col></Row>
                <Row><Col xs={12}>{callnumber}</Col></Row>
              </Col>
              <Col xs={4}>
                <Row><Col xs={12}><FormattedMessage id="ui-users.charge.item.location" /></Col></Row>
                <Row><Col xs={12}>{location}</Col></Row>
              </Col>
            </Row>
          </Col>
        </Row>

    );
  }
}

export default ItemInfo;
<|endoftext|>


<commit_before>var Backbone = require('backbone');
var _ = require('underscore');
var CustomListView = require('../../../custom-list/custom-view');
var CustomListCollection = require('../../../custom-list/custom-list-multi-collection');
var selectedItemTemplate = require('./select-item.tpl');
var CustomListItemView = require('../../../custom-list/custom-list-multi-item-view');
var itemListTemplate = require('../../../custom-list/custom-list-item-with-checkbox.tpl');
var template = require('./select.tpl');
var ENTER_KEY_CODE = 13;

Backbone.Form.editors.MultiSelect = Backbone.Form.editors.Base.extend({

  tagName: 'div',
  className: 'u-ellipsis Editor-formSelect',

  events: {
    'click .js-button': '_onButtonClick',
    'keydown .js-button': '_onButtonKeyDown',
    'focus .js-button': function () {
      this.trigger('focus', this);
    },
    'blur': function () {
      this.trigger('blur', this);
    }
  },

  options: {
    selectedItemTemplate: selectedItemTemplate,
    itemListTemplate: itemListTemplate,
    customListItemView: CustomListItemView
  },

  initialize: function (opts) {
    this.options = _.extend(
      {},
      this.options,
      opts.schema.editorAttrs || {},
      {
        keyAttr: opts.key
      },
      opts
    );

    this.collection = new CustomListCollection(opts.schema.options);

    this._initViews();
    this.setValue(this.model.get(opts.key));
    Backbone.Form.editors.Base.prototype.initialize.call(this, opts);

    this._initBinds();
  },

  _getLabel: function () {
    var itemCount = _.compact(this.collection.pluck('selected')).length;
    return _t('components.backbone-forms.select.selected', { count: itemCount });
  },

  _initViews: function () {
    var isLoading = this.options.loading;
    var isEmpty = !this.collection.length;
    var isDisabled = !isEmpty ? this.options.disabled : true;

    this.$el.html(
      template({
        label: this._getLabel(),
        keyAttr: this.options.keyAttr,
        isDisabled: isDisabled,
        isLoading: isLoading,
        isEmpty: isEmpty
      })
    );

    if (isDisabled) {
      this.undelegateEvents();
    }

    this._listView = new CustomListView({
      collection: this.collection,
      showSearch: this.options.showSearch,
      typeLabel: this.options.keyAttr,
      itemTemplate: this.options.itemListTemplate,
      itemView: this.options.customListItemView
    });

    this._listView.bind('hidden', this._onHide, this);

    this.$el.append(this._listView.el); // No render from the beginning
  },

  _initBinds: function () {
    this.collection.bind('change:selected', this._onItemSelected, this);
    this.applyESCBind(function () {
      this._listView.hide();
    });
    this.applyClickOutsideBind(function () {
      this._listView.hide();
    });
  },

  _onItemSelected: function (mdl) {
    this._renderButton(mdl).focus();
  },

  _onButtonClick: function (ev) {
    this._listView.toggle();
  },

  _onButtonKeyDown: function (ev) {
    if (ev.which === ENTER_KEY_CODE) {
      ev.preventDefault();
      if (!this._listView.isVisible()) {
        ev.stopPropagation();
        this._listView.toggle();
      }
    }
  },

  _getSelectedValues: function () {
    return this.collection.chain().map(function (m) { return m.get('selected') ? m.get('val') : null; }).compact().value();
  },

  getValue: function () {
    var values = this._getSelectedValues();
    if (values.length > 0) {
      return values;
    }
    return;
  },

  setValue: function (value) {
    if (value) {
      var selectedModel = this.collection.setSelected(value);

      if (selectedModel) {
        this._renderButton(selectedModel);
      }
    }
  },

  _renderButton: function (mdl) {
    var button = this.$('.js-button');
    var data = _.extend({}, mdl.attributes, { label: this._getLabel() });
    var $html = this.options.selectedItemTemplate(data);

    button
      .removeClass('is-empty')
      .html($html);

    return button;
  },

  _onHide: function () {
    if (this._getSelectedValues().length > 0) {
      this.trigger('change', this);
    }
  },

  remove: function () {
    this._listView && this._listView.clean();
    Backbone.Form.editors.Base.prototype.remove.call(this);
  }
});
<commit_msg>multiselect: isnull, hotfix<commit_after>var Backbone = require('backbone');
var _ = require('underscore');
var CustomListView = require('../../../custom-list/custom-view');
var CustomListCollection = require('../../../custom-list/custom-list-multi-collection');
var selectedItemTemplate = require('./select-item.tpl');
var CustomListItemView = require('../../../custom-list/custom-list-multi-item-view');
var itemListTemplate = require('../../../custom-list/custom-list-item-with-checkbox.tpl');
var template = require('./select.tpl');
var ENTER_KEY_CODE = 13;

Backbone.Form.editors.MultiSelect = Backbone.Form.editors.Base.extend({

  tagName: 'div',
  className: 'u-ellipsis Editor-formSelect',

  events: {
    'click .js-button': '_onButtonClick',
    'keydown .js-button': '_onButtonKeyDown',
    'focus .js-button': function () {
      this.trigger('focus', this);
    },
    'blur': function () {
      this.trigger('blur', this);
    }
  },

  options: {
    selectedItemTemplate: selectedItemTemplate,
    itemListTemplate: itemListTemplate,
    customListItemView: CustomListItemView
  },

  initialize: function (opts) {
    this.options = _.extend(
      {},
      this.options,
      opts.schema.editorAttrs || {},
      {
        keyAttr: opts.key
      },
      opts
    );

    this.collection = new CustomListCollection(opts.schema.options);

    this._initViews();
    this.setValue(this.model.get(opts.key));
    Backbone.Form.editors.Base.prototype.initialize.call(this, opts);

    this._initBinds();
  },

  _getLabel: function () {
    var itemCount = _.compact(this.collection.pluck('selected')).length;
    return _t('components.backbone-forms.select.selected', { count: itemCount });
  },

  _initViews: function () {
    var isLoading = this.options.loading;
    var isEmpty = !this.collection.length;
    var isDisabled = !isEmpty ? this.options.disabled : true;
    var name = this._getLabel();
    var isNull = name === null;
    var label = isNull ? 'null' : name;

    this.$el.html(
      template({
        label: label,
        keyAttr: this.options.keyAttr,
        isDisabled: isDisabled,
        isLoading: isLoading,
        isEmpty: isEmpty,
        isNull: isNull
      })
    );

    if (isDisabled) {
      this.undelegateEvents();
    }

    this._listView = new CustomListView({
      collection: this.collection,
      showSearch: this.options.showSearch,
      typeLabel: this.options.keyAttr,
      itemTemplate: this.options.itemListTemplate,
      itemView: this.options.customListItemView
    });

    this._listView.bind('hidden', this._onHide, this);

    this.$el.append(this._listView.el); // No render from the beginning
  },

  _initBinds: function () {
    this.collection.bind('change:selected', this._onItemSelected, this);
    this.applyESCBind(function () {
      this._listView.hide();
    });
    this.applyClickOutsideBind(function () {
      this._listView.hide();
    });
  },

  _onItemSelected: function (mdl) {
    this._renderButton(mdl).focus();
  },

  _onButtonClick: function (ev) {
    this._listView.toggle();
  },

  _onButtonKeyDown: function (ev) {
    if (ev.which === ENTER_KEY_CODE) {
      ev.preventDefault();
      if (!this._listView.isVisible()) {
        ev.stopPropagation();
        this._listView.toggle();
      }
    }
  },

  _getSelectedValues: function () {
    return this.collection.chain().map(function (m) { return m.get('selected') ? m.get('val') : null; }).compact().value();
  },

  getValue: function () {
    var values = this._getSelectedValues();
    if (values.length > 0) {
      return values;
    }
    return;
  },

  setValue: function (value) {
    if (value) {
      var selectedModel = this.collection.setSelected(value);

      if (selectedModel) {
        this._renderButton(selectedModel);
      }
    }
  },

  _renderButton: function (mdl) {
    var button = this.$('.js-button');
    var data = _.extend({}, mdl.attributes, { label: this._getLabel() });
    var $html = this.options.selectedItemTemplate(data);

    button
      .removeClass('is-empty')
      .html($html);

    return button;
  },

  _onHide: function () {
    if (this._getSelectedValues().length > 0) {
      this.trigger('change', this);
    }
  },

  remove: function () {
    this._listView && this._listView.clean();
    Backbone.Form.editors.Base.prototype.remove.call(this);
  }
});
<|endoftext|>


<commit_before>const $ = require('jquery');
const _ = require('underscore');
const CoreView = require('backbone/core-view');
const ModalsServiceModel = require('builder/components/modals/modals-service-model');
const FiltersView = require('dashboard/views/dashboard/filters/filters-view');
const ListView = require('dashboard/components/list-view/list-view');
const ContentResult = require('dashboard/views/dashboard/content-controller/content-result-view');
const OnboardingView = require('dashboard/views/dashboard/onboarding/onboarding-view');
const ContentFooterView = require('dashboard/views/dashboard/content-controller/content-footer/content-footer-view');
const LoadingLibraryView = require('dashboard/views/dashboard/content-controller/loading-library-view');
const template = require('./content-controller.tpl');
const checkAndBuildOpts = require('builder/helpers/required-opts');

const REQUIRED_OPTS = [
  'configModel',
  'userModel',
  'routerModel',
  'localStorage',
  'backgroundPollingView'
];

module.exports = CoreView.extend({
  className: 'ContentController',

  initialize: function (options) {
    checkAndBuildOpts(options, REQUIRED_OPTS, this);
    this._modals = new ModalsServiceModel();
    this._initBindings();
  },

  render: function () {
    this.clearSubViews();
    this.$el.html(template());

    this._initViews();

    return this;
  },

  _initBindings: function () {
    this.listenTo(this._routerModel.model, 'change', this._onRouterChange);

    this.listenTo(this.collection, 'reset sync', this._onDataFetched);
    this.listenTo(this.collection, 'loading', this._onDataLoading);
    this.listenTo(this.collection, 'add', this._onDataChange);
    this.listenTo(this.collection, 'error', function (collection, error, options) {
      // Old requests can be stopped, so aborted requests are not
      // considered as an error
      if (!error || (error && error.statusText !== 'abort')) {
        this._onDataError();
      }
    });

    // Binding window scroll :(
    document.addEventListener('scroll', this._onWindowScroll);
  },

  _initViews: function () {
    this.controlledViews = {}; // All available views
    this.enabledViews = []; // Visible views

    const onboardingView = new OnboardingView({
      configModel: this._configModel,
      userModel: this._userModel,
      modals: this._modals
    });
    this.controlledViews['onboarding'] = onboardingView;
    this.$el.prepend(onboardingView.render().el);
    this.addView(onboardingView);

    const filtersView = new FiltersView({
      el: this.$('.Filters'),
      configModel: this._configModel,
      userModel: this._userModel,
      routerModel: this._routerModel,
      collection: this.collection,
      localStorage: this._localStorage,
      modals: this._modals,
      headerHeight: this.options.headerHeight
    });

    this.listenTo(filtersView, 'importByUploadData', this._backgroundPollingView._addDataset);

    this.controlledViews['filters'] = filtersView;
    filtersView.render();
    this.addView(filtersView);

    const noDatasetsView = new ContentResult({
      className: 'ContentResult no-datasets',
      userModel: this._userModel,
      routerModel: this._routerModel,
      collection: this.collection,
      template: require('./templates/content-no-datasets.tpl')
    });

    noDatasetsView.bind('connectDataset', function () {
      // TODO
      if (this._userModel && this._userModel.canCreateDatasets()) {
        cdb.god.trigger(
          'openCreateDialog',
          { type: 'dataset' }
        );
      }
    }, this);

    this.controlledViews['no_datasets'] = noDatasetsView;
    this.$('.NoDatasets').append(noDatasetsView.render().el);
    this.addView(noDatasetsView);

    const listView = new ListView({
      userModel: this._userModel,
      routerModel: this._routerModel,
      configModel: this._configModel,
      modals: this._modals,
      collection: this.collection
    });

    this.controlledViews['list'] = listView;
    this.$('#content-list').append(listView.render().el);
    this.addView(listView);

    const noResultsView = new ContentResult({
      userModel: this._userModel,
      routerModel: this._routerModel,
      collection: this.collection,
      template: require('./templates/content-no-results.tpl')
    });

    this.controlledViews['no_results'] = noResultsView;
    this.$el.append(noResultsView.render().el);
    this.addView(noResultsView);

    const loadingLibrary = new LoadingLibraryView();
    this.controlledViews['loading_library'] = loadingLibrary;
    this.$el.append(loadingLibrary.render().el);
    this.addView(loadingLibrary);

    const errorView = new ContentResult({
      userModel: this._userModel,
      routerModel: this._routerModel,
      collection: this.collection,
      template: require('./templates/content-error.tpl')
    });

    this.controlledViews['error'] = errorView;
    this.$el.append(errorView.render().el);
    this.addView(errorView);

    const mainLoaderView = new ContentResult({
      userModel: this._userModel,
      routerModel: this._routerModel,
      collection: this.collection,
      template: require('./templates/content-loader.tpl')
    });

    this.controlledViews['main_loader'] = mainLoaderView;
    this.$el.append(mainLoaderView.render().el);
    this.addView(mainLoaderView);

    // // No need to call render, will render itself upon initial collection fetch
    const contentFooter = new ContentFooterView({
      el: this.$('#content-footer'),
      configModel: this._configModel,
      model: this.user,
      router: this._routerModel,
      collection: this.collection
    });

    this.controlledViews['content_footer'] = contentFooter;
    // Move element to end of the parent, if not paginator will appear
    // before other elements
    this.$('#content-footer').appendTo(this.$el);
    this.addView(contentFooter);
  },

  _onRouterChange: function (model, value) {
    let blocks = [];

    if (value && value.changes && value.changes.content_type) {
      // If it changes to a different type (or tables or visualizations)
      // Show the main loader
      blocks = [ 'filters', 'main_loader' ];
    } else {
      blocks = ['filters'];

      if (this._isBlockEnabled('list') && this.collection.total_user_entries > 0) {
        // If list was enabled, keep it visible
        blocks.push('list', 'content_footer');
      } else {
        blocks.push('main_loader');
      }

      // If no_results was enabled, keep it visible
      if (this._isBlockEnabled('no_results') || this._isBlockEnabled('error')) {
        if (!_.contains(blocks, 'main_loader')) {
          blocks.push('main_loader');
        }
      }
    }

    this._hideBlocks();
    this._showBlocks(blocks);
    this._scrollToTop();
  },

  _onDataLoading: function () {
    this.$el.removeClass('on-boarding');
  },

  /**
   * Arguments may consty, depending on if it's the collection or a model that triggers the event callback.
   * @private
   */
  _onDataFetched: function () {
    let activeViews = [ 'filters', 'content_footer' ];
    const tag = this._routerModel.model.get('tag');
    const q = this._routerModel.model.get('q');
    const shared = this._routerModel.model.get('shared');
    const liked = this._routerModel.model.get('liked');
    const locked = this._routerModel.model.get('locked');
    const library = this._routerModel.model.get('library');

    if (library && this.collection.total_user_entries === 0) {
      activeViews.push('no_datasets');
    }

    if (this.collection.size() === 0) {
      if (!tag && !q && shared === 'no' && !locked && !liked) {
        if (this._routerModel.model.get('content_type') === 'maps') {
          this.$el.addClass('on-boarding');
          activeViews = ['onboarding', 'filters'];
        } else if (library) {
          // Library is loaded async on 1st visit by user, so this code path is only reached until the library has been
          // stocked up. Show an intermediate loading info, and retry fetching data until while user stays here.
          // See https://github.com/CartoDB/cartodb/pull/2741 for more details.
          activeViews.push('loading_library');
          this.controlledViews['loading_library'].retrySoonAgainOrAbortIfLeavingLibrary(this.collection, this._routerModel.model);
        } else {
          activeViews.push('no_results');
        }
      } else {
        activeViews.push('no_results');
      }
    } else {
      activeViews.push('list');
    }

    this._hideBlocks();
    this._showBlocks(activeViews);
  },

  _onDataChange: function () {
    // Fetch collection again to check if current
    // view has suffered a change
    this.collection.fetch();
  },

  _onDataError: function (e) {
    this._hideBlocks();
    this._showBlocks([ 'filters', 'error' ]);
  },

  _showBlocks: function (views) {
    if (views) {
      _.each(views, function (view) {
        this.controlledViews[view].show();
        this.enabledViews.push(view);
      }, this);
    } else {
      this.enabledViews = [];

      _.each(this.controlledViews, function (view) {
        view.show();
        this.enabledViews.push(view);
      }, this);
    }
  },

  _hideBlocks: function (views) {
    if (views) {
      _.each(views, function (view) {
        this.controlledViews[view].hide();
        this.enabledViews = _.without(this.enabledViews, view);
      }, this);
    } else {
      _.each(this.controlledViews, function (view) {
        view.hide();
      }, this);

      this.enabledViews = [];
    }
  },

  _isBlockEnabled: function (name) {
    if (name) {
      return _.contains(this.enabledViews, name);
    }

    return false;
  },

  _scrollToTop: function () {
    $('body').animate({ scrollTop: 0 }, 550);
  }
});
<commit_msg>Add create dialog to content controller view<commit_after>const $ = require('jquery');
const _ = require('underscore');
const CoreView = require('backbone/core-view');
const ModalsServiceModel = require('builder/components/modals/modals-service-model');
const FiltersView = require('dashboard/views/dashboard/filters/filters-view');
const ListView = require('dashboard/components/list-view/list-view');
const ContentResult = require('dashboard/views/dashboard/content-controller/content-result-view');
const OnboardingView = require('dashboard/views/dashboard/onboarding/onboarding-view');
const ContentFooterView = require('dashboard/views/dashboard/content-controller/content-footer/content-footer-view');
const LoadingLibraryView = require('dashboard/views/dashboard/content-controller/loading-library-view');
const CreateDialog = require('dashboard/views/dashboard/dialogs/create-dialog/sacar-fuera/dialog-view');
const template = require('./content-controller.tpl');
const checkAndBuildOpts = require('builder/helpers/required-opts');

const REQUIRED_OPTS = [
  'configModel',
  'userModel',
  'routerModel',
  'localStorage',
  'backgroundPollingView'
];

module.exports = CoreView.extend({
  className: 'ContentController',

  initialize: function (options) {
    checkAndBuildOpts(options, REQUIRED_OPTS, this);
    this._modals = new ModalsServiceModel();
    this._initBindings();
  },

  render: function () {
    this.clearSubViews();
    this.$el.html(template());

    this._initViews();

    return this;
  },

  _initBindings: function () {
    this.listenTo(this._routerModel.model, 'change', this._onRouterChange);

    this.listenTo(this.collection, 'reset sync', this._onDataFetched);
    this.listenTo(this.collection, 'loading', this._onDataLoading);
    this.listenTo(this.collection, 'add', this._onDataChange);
    this.listenTo(this.collection, 'error', function (collection, error, options) {
      // Old requests can be stopped, so aborted requests are not
      // considered as an error
      if (!error || (error && error.statusText !== 'abort')) {
        this._onDataError();
      }
    });

    // Binding window scroll :(
    document.addEventListener('scroll', this._onWindowScroll);
  },

  _initViews: function () {
    this.controlledViews = {}; // All available views
    this.enabledViews = []; // Visible views

    const onboardingView = new OnboardingView({
      configModel: this._configModel,
      userModel: this._userModel,
      modals: this._modals
    });
    this.controlledViews['onboarding'] = onboardingView;
    this.$el.prepend(onboardingView.render().el);
    this.addView(onboardingView);

    const filtersView = new FiltersView({
      el: this.$('.Filters'),
      configModel: this._configModel,
      userModel: this._userModel,
      routerModel: this._routerModel,
      collection: this.collection,
      localStorage: this._localStorage,
      modals: this._modals,
      headerHeight: this.options.headerHeight
    });

    this.listenTo(filtersView, 'importByUploadData', this._backgroundPollingView._addDataset);

    this.controlledViews['filters'] = filtersView;
    filtersView.render();
    this.addView(filtersView);

    const noDatasetsView = new ContentResult({
      className: 'ContentResult no-datasets',
      userModel: this._userModel,
      routerModel: this._routerModel,
      collection: this.collection,
      template: require('./templates/content-no-datasets.tpl')
    });

    noDatasetsView.bind('connectDataset', function () {
      if (this._userModel && this._userModel.canCreateDatasets()) {
        this._modals.create(modalModel => {
          return CreateDialog.openDialog({ modalModel }, {
            type: 'dataset',
            selectedItems: [],
            modalModel
          });
        });
      }
    }, this);

    this.controlledViews['no_datasets'] = noDatasetsView;
    this.$('.NoDatasets').append(noDatasetsView.render().el);
    this.addView(noDatasetsView);

    const listView = new ListView({
      userModel: this._userModel,
      routerModel: this._routerModel,
      configModel: this._configModel,
      modals: this._modals,
      collection: this.collection
    });

    this.controlledViews['list'] = listView;
    this.$('#content-list').append(listView.render().el);
    this.addView(listView);

    const noResultsView = new ContentResult({
      userModel: this._userModel,
      routerModel: this._routerModel,
      collection: this.collection,
      template: require('./templates/content-no-results.tpl')
    });

    this.controlledViews['no_results'] = noResultsView;
    this.$el.append(noResultsView.render().el);
    this.addView(noResultsView);

    const loadingLibrary = new LoadingLibraryView();
    this.controlledViews['loading_library'] = loadingLibrary;
    this.$el.append(loadingLibrary.render().el);
    this.addView(loadingLibrary);

    const errorView = new ContentResult({
      userModel: this._userModel,
      routerModel: this._routerModel,
      collection: this.collection,
      template: require('./templates/content-error.tpl')
    });

    this.controlledViews['error'] = errorView;
    this.$el.append(errorView.render().el);
    this.addView(errorView);

    const mainLoaderView = new ContentResult({
      userModel: this._userModel,
      routerModel: this._routerModel,
      collection: this.collection,
      template: require('./templates/content-loader.tpl')
    });

    this.controlledViews['main_loader'] = mainLoaderView;
    this.$el.append(mainLoaderView.render().el);
    this.addView(mainLoaderView);

    // // No need to call render, will render itself upon initial collection fetch
    const contentFooter = new ContentFooterView({
      el: this.$('#content-footer'),
      configModel: this._configModel,
      model: this.user,
      router: this._routerModel,
      collection: this.collection
    });

    this.controlledViews['content_footer'] = contentFooter;
    // Move element to end of the parent, if not paginator will appear
    // before other elements
    this.$('#content-footer').appendTo(this.$el);
    this.addView(contentFooter);
  },

  _onRouterChange: function (model, value) {
    let blocks = [];

    if (value && value.changes && value.changes.content_type) {
      // If it changes to a different type (or tables or visualizations)
      // Show the main loader
      blocks = [ 'filters', 'main_loader' ];
    } else {
      blocks = ['filters'];

      if (this._isBlockEnabled('list') && this.collection.total_user_entries > 0) {
        // If list was enabled, keep it visible
        blocks.push('list', 'content_footer');
      } else {
        blocks.push('main_loader');
      }

      // If no_results was enabled, keep it visible
      if (this._isBlockEnabled('no_results') || this._isBlockEnabled('error')) {
        if (!_.contains(blocks, 'main_loader')) {
          blocks.push('main_loader');
        }
      }
    }

    this._hideBlocks();
    this._showBlocks(blocks);
    this._scrollToTop();
  },

  _onDataLoading: function () {
    this.$el.removeClass('on-boarding');
  },

  /**
   * Arguments may consty, depending on if it's the collection or a model that triggers the event callback.
   * @private
   */
  _onDataFetched: function () {
    let activeViews = [ 'filters', 'content_footer' ];
    const tag = this._routerModel.model.get('tag');
    const q = this._routerModel.model.get('q');
    const shared = this._routerModel.model.get('shared');
    const liked = this._routerModel.model.get('liked');
    const locked = this._routerModel.model.get('locked');
    const library = this._routerModel.model.get('library');

    if (library && this.collection.total_user_entries === 0) {
      activeViews.push('no_datasets');
    }

    if (this.collection.size() === 0) {
      if (!tag && !q && shared === 'no' && !locked && !liked) {
        if (this._routerModel.model.get('content_type') === 'maps') {
          this.$el.addClass('on-boarding');
          activeViews = ['onboarding', 'filters'];
        } else if (library) {
          // Library is loaded async on 1st visit by user, so this code path is only reached until the library has been
          // stocked up. Show an intermediate loading info, and retry fetching data until while user stays here.
          // See https://github.com/CartoDB/cartodb/pull/2741 for more details.
          activeViews.push('loading_library');
          this.controlledViews['loading_library'].retrySoonAgainOrAbortIfLeavingLibrary(this.collection, this._routerModel.model);
        } else {
          activeViews.push('no_results');
        }
      } else {
        activeViews.push('no_results');
      }
    } else {
      activeViews.push('list');
    }

    this._hideBlocks();
    this._showBlocks(activeViews);
  },

  _onDataChange: function () {
    // Fetch collection again to check if current
    // view has suffered a change
    this.collection.fetch();
  },

  _onDataError: function (e) {
    this._hideBlocks();
    this._showBlocks([ 'filters', 'error' ]);
  },

  _showBlocks: function (views) {
    if (views) {
      _.each(views, function (view) {
        this.controlledViews[view].show();
        this.enabledViews.push(view);
      }, this);
    } else {
      this.enabledViews = [];

      _.each(this.controlledViews, function (view) {
        view.show();
        this.enabledViews.push(view);
      }, this);
    }
  },

  _hideBlocks: function (views) {
    if (views) {
      _.each(views, function (view) {
        this.controlledViews[view].hide();
        this.enabledViews = _.without(this.enabledViews, view);
      }, this);
    } else {
      _.each(this.controlledViews, function (view) {
        view.hide();
      }, this);

      this.enabledViews = [];
    }
  },

  _isBlockEnabled: function (name) {
    if (name) {
      return _.contains(this.enabledViews, name);
    }

    return false;
  },

  _scrollToTop: function () {
    $('body').animate({ scrollTop: 0 }, 550);
  }
});
<|endoftext|>


<commit_before>"use strict";

var LmdbQueue = require('../'),
    Producer = LmdbQueue.Producer;

var producer = new Producer({ path: __dirname + '/test-data', topic: 'test', dataType: LmdbQueue.STRING_TYPE, chunkSize: 1024 * 1024 * 1024, keepHours: 24 * 2 }),
    start = Date.now();

console.log('Begin write to queue.');

var step = 1024;
for (var i = 0; i < 10 * 1024 * 1024; i += step) {
    //producer.push('msg' + i);
    var msg = [];
    for (var j = 0; j < step; j++) msg.push('msg' + (i + j));
    producer.push(msg);
}

console.log('Pushed 1M messages in %d ms', Date.now() - start);<commit_msg>update example.<commit_after>"use strict";

var LmdbQueue = require('../'),
    Producer = LmdbQueue.Producer;

var producer = new Producer({ path: __dirname + '/test-data', topic: 'test', dataType: LmdbQueue.STRING_TYPE, chunkSize: 64 * 1024 * 1024, chunksToKeep: 8 }),
    start = Date.now();

console.log('Begin write to queue.');

var step = 1024;
for (var i = 0; i < 10 * 1024 * 1024; i += step) {
    //producer.push('msg' + i);
    var msg = [];
    for (var j = 0; j < step; j++) msg.push('msg' + (i + j));
    producer.push(msg);
}

console.log('Pushed 10M messages in %d ms', Date.now() - start);<|endoftext|>


<commit_before>import LiveEvents from './LiveEvents';
import LiveError from './LiveError';
import * as calls from './calls';
import * as stateful from './stateful';

const MockWebSocket = () => {};
let WebSocket = typeof window !== 'undefined' ? window.WebSocket : MockWebSocket;

const shouldIgnoreError = error =>
    error.message.includes('You are already subscribed to') ||
        error.message.includes('Input validation failed: forget');

export default class LiveApi {

    static Status = {
        Unknown: 'unknown',
        Connected: 'connected',
    };

    constructor({ apiUrl = 'wss://ws.binaryws.com/websockets/v3', language = 'en', websocket } = {}) {
        this.apiUrl = apiUrl;
        this.language = language;

        if (websocket) {
            WebSocket = websocket;
        }

        this.status = LiveApi.Status.Unknown;

        this.bufferedSends = [];
        this.bufferedExecutes = [];
        this.unresolvedPromises = {};

        this.events = new LiveEvents();

        this.bindCallsAndStateMutators();

        this.connect();
    }

    bindCallsAndStateMutators() {
        Object.keys(calls).forEach(callName => {
            this[callName] = (...params) => {
                if (stateful[callName]) {
                    stateful[callName](...params);
                }
                return this.send(calls[callName](...params));
            };
        });
    }

    connect() {
        this.socket = new WebSocket(`${this.apiUrl}?l=${this.language}`);
        this.socket.onopen = ::this.onOpen;
        this.socket.onclose = ::this.onClose;
        this.socket.onerror = ::this.onError;
        this.socket.onmessage = ::this.onMessage;

        this.resubscribe();
    }

    disconnect() {
        this.token = '';
        this.socket.onclose = undefined;
        this.socket.close();
    }

    resubscribe() {
        const { token, balance, portfolio, transactions, ticks, proposals } = stateful.getState();

        if (token) {
            this.authorize(token);
        }

        ticks.forEach(tick =>
            this.subscribeToTick(tick)
        );

        proposals.forEach(proposal =>
            this.subscribeToPriceForContractProposal(proposal)
        );

        const delayedCallAfterAuthSuccess = () => {
            if (balance) {
                this.subscribeToBalance();
            }

            if (transactions) {
                this.subscribeToTransactions();
            }

            if (portfolio) {
                this.subscribeToAllOpenContracts();
            }

            this.onAuth = undefined;
        };
        this.onAuth = delayedCallAfterAuthSuccess;
    }

    changeLanguage(ln) {
        if (ln === this.language) {
            return;
        }
        this.socket.onclose = undefined;
        this.socket.close();
        this.language = ln;
        this.connect();
    }

    isReady() {
        return this.socket && this.socket.readyState === 1;
    }

    sendBufferedSends() {
        while (this.bufferedSends.length > 0) {
            this.socket.send(JSON.stringify(this.bufferedSends.shift()));
        }
    }

    executeBufferedExecutes() {
        while (this.bufferedExecutes.length > 0) {
            this.bufferedExecutes.shift()();
        }
    }

    onOpen() {
        this.sendBufferedSends();
        this.executeBufferedExecutes();
    }

    onClose() {
        setTimeout(() => {
            this.connect();
        }, 1000);
    }

    onError(error) {
        // for process manager like pm2.
        // It's necessary to print error with console.error.
        // It will make error readable on error.log
        window.console.error(error);

        // And also make process exiting to respawn.
        if (typeof process === 'function') {
            process.exit();
        }
    }

    resolvePromiseForResponse(json) {
        if (!json.req_id) {
            return Promise.resolve();
        }

        const reqId = json.req_id.toString();
        const promise = this.unresolvedPromises[reqId];

        if (!promise) {
            return Promise.resolve();
        }

        delete this.unresolvedPromises[reqId];
        if (!json.error) {
            return promise.resolve(json);
        }

        if (!shouldIgnoreError(json.error)) {
            return promise.reject(new LiveError(json.error));
        }

        return Promise.resolve();
    }

    onMessage(message) {
        const json = JSON.parse(message.data);

        if (!json.error) {
            if (json.msg_type === 'authorize' && this.onAuth) {
                this.onAuth();
            }
            this.events.emit(json.msg_type, json);
        } else {
            this.events.emit('error', json);
        }

        return this.resolvePromiseForResponse(json);
    }

    generatePromiseForRequest(json) {
        const reqId = json.req_id.toString();

        return new Promise((resolve, reject) => {
            this.unresolvedPromises[reqId] = { resolve, reject };
        });
    }

    sendRaw(json) {
        if (this.isReady()) {
            this.socket.send(JSON.stringify(json));
        } else {
            this.bufferedSends.push(json);
        }

        if (json.req_id) {
            return this.generatePromiseForRequest(json);
        }
    }

    send(json) {
        const reqId = Math.floor((Math.random() * 1e15));
        return this.sendRaw({
            req_id: reqId,
            ...json,
        });
    }

    execute(func) {
        if (this.isReady()) {
            func();
        } else {
            this.bufferedExecutes.push(func);
        }
    }
}
<commit_msg>Do not delay<commit_after>import LiveEvents from './LiveEvents';
import LiveError from './LiveError';
import * as calls from './calls';
import * as stateful from './stateful';

const MockWebSocket = () => {};
let WebSocket = typeof window !== 'undefined' ? window.WebSocket : MockWebSocket;

const shouldIgnoreError = error =>
    error.message.includes('You are already subscribed to') ||
        error.message.includes('Input validation failed: forget');

export default class LiveApi {

    static Status = {
        Unknown: 'unknown',
        Connected: 'connected',
    };

    constructor({ apiUrl = 'wss://ws.binaryws.com/websockets/v3', language = 'en', websocket } = {}) {
        this.apiUrl = apiUrl;
        this.language = language;

        if (websocket) {
            WebSocket = websocket;
        }

        this.status = LiveApi.Status.Unknown;

        this.bufferedSends = [];
        this.bufferedExecutes = [];
        this.unresolvedPromises = {};

        this.events = new LiveEvents();

        this.bindCallsAndStateMutators();

        this.connect();
    }

    bindCallsAndStateMutators() {
        Object.keys(calls).forEach(callName => {
            this[callName] = (...params) => {
                if (stateful[callName]) {
                    stateful[callName](...params);
                }
                return this.send(calls[callName](...params));
            };
        });
    }

    connect() {
        this.socket = new WebSocket(`${this.apiUrl}?l=${this.language}`);
        this.socket.onopen = ::this.onOpen;
        this.socket.onclose = ::this.onClose;
        this.socket.onerror = ::this.onError;
        this.socket.onmessage = ::this.onMessage;

        this.resubscribe();
    }

    disconnect() {
        this.token = '';
        this.socket.onclose = undefined;
        this.socket.close();
    }

    resubscribe() {
        const { token, balance, portfolio, transactions, ticks, proposals } = stateful.getState();

        if (token) {
            this.authorize(token);
        }

        ticks.forEach(tick =>
            this.subscribeToTick(tick)
        );

        proposals.forEach(proposal =>
            this.subscribeToPriceForContractProposal(proposal)
        );

        const delayedCallAfterAuthSuccess = () => {
            if (balance) {
                this.subscribeToBalance();
            }

            if (transactions) {
                this.subscribeToTransactions();
            }

            if (portfolio) {
                this.subscribeToAllOpenContracts();
            }

            this.onAuth = undefined;
        };
        this.onAuth = delayedCallAfterAuthSuccess;
    }

    changeLanguage(ln) {
        if (ln === this.language) {
            return;
        }
        this.socket.onclose = undefined;
        this.socket.close();
        this.language = ln;
        this.connect();
    }

    isReady() {
        return this.socket && this.socket.readyState === 1;
    }

    sendBufferedSends() {
        while (this.bufferedSends.length > 0) {
            this.socket.send(JSON.stringify(this.bufferedSends.shift()));
        }
    }

    executeBufferedExecutes() {
        while (this.bufferedExecutes.length > 0) {
            this.bufferedExecutes.shift()();
        }
    }

    onOpen() {
        this.sendBufferedSends();
        this.executeBufferedExecutes();
    }

    onClose() {
        this.connect();
    }

    onError(error) {
        // for process manager like pm2.
        // It's necessary to print error with console.error.
        // It will make error readable on error.log
        window.console.error(error);

        // And also make process exiting to respawn.
        if (typeof process === 'function') {
            process.exit();
        }
    }

    resolvePromiseForResponse(json) {
        if (!json.req_id) {
            return Promise.resolve();
        }

        const reqId = json.req_id.toString();
        const promise = this.unresolvedPromises[reqId];

        if (!promise) {
            return Promise.resolve();
        }

        delete this.unresolvedPromises[reqId];
        if (!json.error) {
            return promise.resolve(json);
        }

        if (!shouldIgnoreError(json.error)) {
            return promise.reject(new LiveError(json.error));
        }

        return Promise.resolve();
    }

    onMessage(message) {
        const json = JSON.parse(message.data);

        if (!json.error) {
            if (json.msg_type === 'authorize' && this.onAuth) {
                this.onAuth();
            }
            this.events.emit(json.msg_type, json);
        } else {
            this.events.emit('error', json);
        }

        return this.resolvePromiseForResponse(json);
    }

    generatePromiseForRequest(json) {
        const reqId = json.req_id.toString();

        return new Promise((resolve, reject) => {
            this.unresolvedPromises[reqId] = { resolve, reject };
        });
    }

    sendRaw(json) {
        if (this.isReady()) {
            this.socket.send(JSON.stringify(json));
        } else {
            this.bufferedSends.push(json);
        }

        if (json.req_id) {
            return this.generatePromiseForRequest(json);
        }
    }

    send(json) {
        const reqId = Math.floor((Math.random() * 1e15));
        return this.sendRaw({
            req_id: reqId,
            ...json,
        });
    }

    execute(func) {
        if (this.isReady()) {
            func();
        } else {
            this.bufferedExecutes.push(func);
        }
    }
}
<|endoftext|>


<commit_before>/*
Copyright 2016 Brazil Ltd.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
(function () {
  'use strict';

  angular.module('app')
    .component('commentGrid', {
      templateUrl: 'templates/commentGrid.html',
      controller: CommentGridCtrl
    });

  function CommentGridCtrl(
    $scope,
    $filter,
    CommonService,
    CommentService,
    PlayerService
  ) {
    var $ctrl = this;
    var autoScrolling = false;

    $ctrl.autoScroll = true;
    $ctrl.gridOptions = {
      rowSelection: 'single',
      enableColResize: true,
      enableSorting: true,
      suppressCellSelection: true,
      suppressLoadingOverlay: true,
      suppressNoRowsOverlay: true,
      columnDefs: [{
        colId: 'playTime',
        field: 'playTime',
        headerName: '時間',
        width: 70,
        cellStyle: {
          textAlign: 'right'
        },
        cellRenderer: function (params) {
          var time = CommonService.formatTime(params.value);

          return ['
', time, '
'].join('');
        }
      }, {
        colId: 'time',
        field: 'time',
        headerName: '時刻',
        width: 70,
        cellStyle: {
          textAlign: 'right'
        },
        cellRenderer: function (params) {
          var time = $filter('date')(params.value, 'HH:mm:ss');

          return ['
', time, '
'].join('');
        }
      }, {
        colId: 'text',
        field: 'text',
        tooltipField: 'text',
        headerName: 'コメント',
        width: 428
      }, {
        colId: 'name',
        field: 'name',
        tooltipField: 'name',
        headerName: '名前',
        width: 180
      }, {
        colId: 'id',
        field: 'id',
        tooltipField: 'id',
        headerName: 'ID',
        width: 180
      }, {
        colId: 'email',
        field: 'email',
        tooltipField: 'email',
        headerName: 'メール',
        width: 240
      }, {
        colId: 'title',
        field: 'title',
        tooltipField: 'title',
        headerName: 'スレッド',
        width: 240
      }],
      onSortChanged: function () {
        var sortModel = this.api.getSortModel();

        if (
          sortModel.length > 1 ||
          sortModel[0].colId !== 'playTime' ||
          sortModel[0].sort !== 'asc'
        ) {
          $ctrl.autoScroll = false;
        }
      },
      onViewportChanged: function () {
        if (autoScrolling) {
          autoScrolling = false;
        } else {
          $ctrl.autoScroll = false;
        }
      },
      onRowDoubleClicked: function () {
        var selectedtRows = this.api.getSelectedRows();

        if (selectedtRows.length > 0) {
          PlayerService.time(selectedtRows[0].playTime);
        }
      }
    };

    $ctrl.updateFilter = function () {
      var checkedThreads = [];

      $ctrl.threads.forEach(function (a) {
        if (a.checked) {
          checkedThreads.push(a.title);
        }
      });
      if (checkedThreads.length > 0) {
        CommentService.filter(function (comment) {
          if (checkedThreads.indexOf(comment.title) < 0) {
            return false;
          }
          return true;
        });
      } else {
        CommentService.filter(null);
      }
      $ctrl.gridOptions.api.setRowData(CommentService.filteredComments());
      checkedThreads = null;
    };

    $ctrl.autoScrollChanged = function () {
      if ($ctrl.autoScroll) {
        $ctrl.gridOptions.api.setSortModel([{
          colId: 'playTime',
          sort: 'asc'
        }]);
      }
    };

    $scope.$watch(function () {
      return CommentService.comments();
    }, function (value) {
      var titles = [];
      var threads = [];

      value.forEach(function (a) {
        if (titles.indexOf(a.title) < 0) {
          titles.push(a.title);
          threads.push({
            title: a.title
          });
        }
      });
      $ctrl.threads = threads;
      $ctrl.gridOptions.api.setRowData(CommentService.filteredComments());
      titles = null;
      threads = null;
    });

    $scope.$watch(function () {
      return PlayerService.time();
    }, function (newValue, oldValue) {
      if ($ctrl.autoScroll) {
        $ctrl.gridOptions.api.ensureNodeVisible(function (a) {
          return a.data.playTime >= oldValue;
        });
        autoScrolling = true;
      }
    });
  }
}());
<commit_msg>miyoutv: コメント取得時にコメント一覧の自動スクロールを有効化<commit_after>/*
Copyright 2016 Brazil Ltd.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
(function () {
  'use strict';

  angular.module('app')
    .component('commentGrid', {
      templateUrl: 'templates/commentGrid.html',
      controller: CommentGridCtrl
    });

  function CommentGridCtrl(
    $scope,
    $filter,
    CommonService,
    CommentService,
    PlayerService
  ) {
    var $ctrl = this;
    var autoScrolling = false;

    $ctrl.autoScroll = true;
    $ctrl.gridOptions = {
      rowSelection: 'single',
      enableColResize: true,
      enableSorting: true,
      suppressCellSelection: true,
      suppressLoadingOverlay: true,
      suppressNoRowsOverlay: true,
      columnDefs: [{
        colId: 'playTime',
        field: 'playTime',
        headerName: '時間',
        width: 70,
        cellStyle: {
          textAlign: 'right'
        },
        cellRenderer: function (params) {
          var time = CommonService.formatTime(params.value);

          return ['
', time, '
'].join('');
        }
      }, {
        colId: 'time',
        field: 'time',
        headerName: '時刻',
        width: 70,
        cellStyle: {
          textAlign: 'right'
        },
        cellRenderer: function (params) {
          var time = $filter('date')(params.value, 'HH:mm:ss');

          return ['
', time, '
'].join('');
        }
      }, {
        colId: 'text',
        field: 'text',
        tooltipField: 'text',
        headerName: 'コメント',
        width: 428
      }, {
        colId: 'name',
        field: 'name',
        tooltipField: 'name',
        headerName: '名前',
        width: 180
      }, {
        colId: 'id',
        field: 'id',
        tooltipField: 'id',
        headerName: 'ID',
        width: 180
      }, {
        colId: 'email',
        field: 'email',
        tooltipField: 'email',
        headerName: 'メール',
        width: 240
      }, {
        colId: 'title',
        field: 'title',
        tooltipField: 'title',
        headerName: 'スレッド',
        width: 240
      }],
      onSortChanged: function () {
        var sortModel = this.api.getSortModel();

        if (
          sortModel.length > 1 ||
          sortModel[0].colId !== 'playTime' ||
          sortModel[0].sort !== 'asc'
        ) {
          $ctrl.autoScroll = false;
        }
      },
      onViewportChanged: function () {
        if (autoScrolling) {
          autoScrolling = false;
        } else {
          $ctrl.autoScroll = false;
        }
      },
      onRowDoubleClicked: function () {
        var selectedtRows = this.api.getSelectedRows();

        if (selectedtRows.length > 0) {
          PlayerService.time(selectedtRows[0].playTime);
        }
      }
    };

    $ctrl.updateFilter = function () {
      var checkedThreads = [];

      $ctrl.threads.forEach(function (a) {
        if (a.checked) {
          checkedThreads.push(a.title);
        }
      });
      if (checkedThreads.length > 0) {
        CommentService.filter(function (comment) {
          if (checkedThreads.indexOf(comment.title) < 0) {
            return false;
          }
          return true;
        });
      } else {
        CommentService.filter(null);
      }
      $ctrl.gridOptions.api.setRowData(CommentService.filteredComments());
      checkedThreads = null;
    };

    $ctrl.autoScrollChanged = function () {
      if ($ctrl.autoScroll) {
        $ctrl.gridOptions.api.setSortModel([{
          colId: 'playTime',
          sort: 'asc'
        }]);
      }
    };

    $scope.$watch(function () {
      return CommentService.comments();
    }, function (value) {
      var titles = [];
      var threads = [];

      value.forEach(function (a) {
        if (titles.indexOf(a.title) < 0) {
          titles.push(a.title);
          threads.push({
            title: a.title
          });
        }
      });
      $ctrl.threads = threads;
      $ctrl.gridOptions.api.setRowData(CommentService.filteredComments());
      $ctrl.autoScroll = true;
      titles = null;
      threads = null;
    });

    $scope.$watch(function () {
      return PlayerService.time();
    }, function (newValue, oldValue) {
      if ($ctrl.autoScroll) {
        $ctrl.gridOptions.api.ensureNodeVisible(function (a) {
          return a.data.playTime >= oldValue;
        });
        autoScrolling = true;
      }
    });
  }
}());
<|endoftext|>


<commit_before>import MeshBVHNode from './MeshBVHNode.js';
import { CENTER } from './Constants.js';
import { buildTree } from './buildFunctions.js';
import {
	raycast,
	raycastFirst,
	shapecast,
	intersectsGeometry,
	intersectsBox,
	intersectsSphere,
	closestPointToPoint,
	closestPointToGeometry,
} from './castFunctions.js';

// boundingData  				: 6 float32
// right / offset 				: 1 uint32
// splitAxis / isLeaf + count 	: 1 uint32 / 2 uint16
const BYTES_PER_NODE = 6 * 4 + 4 + 4;
const IS_LEAFNODE_FLAG = 0xFFFF;
const SKIP_GENERATION = Symbol( 'skip tree generation' );

export default class MeshBVH {

	static serialize( bvh, geometry, copyIndexBuffer = true ) {

		function finishTree( node ) {

			if ( node.continueGeneration ) {

				node.continueGeneration();

			}

			if ( ! node.count ) {

				finishTree( node.left );
				finishTree( node.right );

			}

		}

		function countNodes( node ) {

			if ( node.count ) {

				return 1;

			} else {

				return 1 + countNodes( node.left ) + countNodes( node.right );

			}

		}

		function populateBuffer( byteOffset, node ) {

			const stride4Offset = byteOffset / 4;
			const stride2Offset = byteOffset / 2;
			const isLeaf = ! ! node.count;
			const boundingData = node.boundingData;
			for ( let i = 0; i < 6; i ++ ) {

				float32Array[ stride4Offset + i ] = boundingData[ i ];

			}

			if ( isLeaf ) {

				const offset = node.offset;
				const count = node.count;
				uint32Array[ stride4Offset + 6 ] = offset;
				uint16Array[ stride2Offset + 14 ] = count;
				uint16Array[ stride2Offset + 15 ] = IS_LEAFNODE_FLAG;
				return byteOffset + BYTES_PER_NODE;

			} else {

				const left = node.left;
				const right = node.right;
				const splitAxis = node.splitAxis;

				let nextUnusedPointer;

				// uint32Array[ stride4Offset + 6 ] = stride4Offset + BYTES_PER_NODE / 4;
				nextUnusedPointer = populateBuffer( byteOffset + BYTES_PER_NODE, left );

				uint32Array[ stride4Offset + 6 ] = nextUnusedPointer / 4;
				nextUnusedPointer = populateBuffer( nextUnusedPointer, right );

				uint32Array[ stride4Offset + 7 ] = splitAxis;
				return nextUnusedPointer;

			}

		}

		let float32Array;
		let uint32Array;
		let uint16Array;

		const roots = bvh._roots;
		const rootData = [];
		for ( let i = 0; i < roots.length; i ++ ) {

			const root = roots[ i ];
			finishTree( root );
			let nodeCount = countNodes( root );

			const buffer = new ArrayBuffer( BYTES_PER_NODE * nodeCount );
			float32Array = new Float32Array( buffer );
			uint32Array = new Uint32Array( buffer );
			uint16Array = new Uint16Array( buffer );
			populateBuffer( 0, root );
			rootData.push( buffer );

		}

		const indexAttribute = geometry.getIndex();
		const result = {
			roots: rootData,
			index: copyIndexBuffer ? indexAttribute.array.slice() : indexAttribute.array,
		};

		return result;

	}

	static deserialize( data, geometry, setIndex = true ) {

		function setData( byteOffset, node ) {

			const stride4Offset = byteOffset / 4;
			const stride2Offset = byteOffset / 2;
			const boundingData = new Float32Array( 6 );
			for ( let i = 0; i < 6; i ++ ) {

				boundingData[ i ] = float32Array[ stride4Offset + i ];

			}
			node.boundingData = boundingData;

			const isLeaf = uint16Array[ stride2Offset + 15 ] === IS_LEAFNODE_FLAG;
			if ( isLeaf ) {

				node.offset = uint32Array[ stride4Offset + 6 ];
				node.count = uint16Array[ stride2Offset + 14 ];

			} else {

				const left = new MeshBVHNode();
				const right = new MeshBVHNode();
				const leftOffset = stride4Offset + BYTES_PER_NODE / 4;
				const rightOffset = uint32Array[ stride4Offset + 6 ];

				setData( leftOffset * 4, left );
				setData( rightOffset * 4, right );

				node.left = left;
				node.right = right;
				node.splitAxis = uint32Array[ stride4Offset + 7 ];

			}

		}

		let float32Array;
		let uint32Array;
		let uint16Array;

		const { index, roots } = data;
		const bvh = new MeshBVH( geometry, { [ SKIP_GENERATION ]: true } );
		bvh._roots = [];
		for ( let i = 0; i < roots.length; i ++ ) {

			const buffer = roots[ i ];
			float32Array = new Float32Array( buffer );
			uint32Array = new Uint32Array( buffer );
			uint16Array = new Uint16Array( buffer );

			const root = new MeshBVHNode();
			setData( 0, root );
			bvh._roots.push( root );

		}

		if ( setIndex ) {

			const indexAttribute = geometry.getIndex();
			if ( indexAttribute.array !== index ) {

				indexAttribute.array.set( index );
				indexAttribute.needsUpdate = true;

			}

		}

		return bvh;

	}

	constructor( geo, options = {} ) {

		if ( ! geo.isBufferGeometry ) {

			throw new Error( 'MeshBVH: Only BufferGeometries are supported.' );

		} else if ( geo.attributes.position.isInterleavedBufferAttribute ) {

			throw new Error( 'MeshBVH: InterleavedBufferAttribute is not supported for the position attribute.' );

		} else if ( geo.index && geo.index.isInterleavedBufferAttribute ) {

			throw new Error( 'MeshBVH: InterleavedBufferAttribute is not supported for the index attribute.' );

		}

		// default options
		options = Object.assign( {

			strategy: CENTER,
			maxDepth: 40,
			maxLeafTris: 10,
			verbose: true,
			lazyGeneration: false,
			[ SKIP_GENERATION ]: false

		}, options );
		options.strategy = Math.max( 0, Math.min( 2, options.strategy ) );

		if ( options[ SKIP_GENERATION ] ) {

			this._roots = null;

		} else {

			this._roots = buildTree( geo, options );

		}

	}

	/* Public Functions */
	raycast( mesh, raycaster, ray, intersects ) {

		for ( const root of this._roots ) {

			raycast( root, mesh, raycaster, ray, intersects );

		}

	}

	raycastFirst( mesh, raycaster, ray ) {

		let closestResult = null;
		for ( const root of this._roots ) {

			const result = raycastFirst( root, mesh, raycaster, ray );
			if ( result != null && ( closestResult == null || result.distance < closestResult.distance ) ) {

				closestResult = result;

			}

		}

		return closestResult;

	}

	intersectsGeometry( mesh, geometry, geomToMesh ) {

		for ( const root of this._roots ) {

			if ( intersectsGeometry( root, mesh, geometry, geomToMesh ) ) return true;

		}

		return false;

	}

	shapecast( mesh, intersectsBoundsFunc, intersectsTriangleFunc = null, orderNodesFunc = null ) {

		for ( const root of this._roots ) {

			if ( shapecast( root, mesh, intersectsBoundsFunc, intersectsTriangleFunc, orderNodesFunc ) ) return true;

		}

		return false;

	}

	intersectsBox( mesh, box, boxToMesh ) {

		for ( const root of this._roots ) {

			if ( intersectsBox( root, mesh, box, boxToMesh ) ) return true;

		}

		return false;

	}

	intersectsSphere( mesh, sphere ) {

		for ( const root of this._roots ) {

			if ( intersectsSphere( root, mesh, sphere ) ) return true;

		}

		return false;

	}

	closestPointToGeometry( mesh, geom, matrix, target1, target2, minThreshold, maxThreshold ) {

		let closestDistance = Infinity;
		for ( const root of this._roots ) {

			const dist = closestPointToGeometry( root, mesh, geom, matrix, target1, target2, minThreshold, maxThreshold );
			if ( dist < closestDistance ) closestDistance = dist;
			if ( dist < minThreshold ) return dist;

		}

		return closestDistance;

	}

	distanceToGeometry( mesh, geom, matrix, minThreshold, maxThreshold ) {

		return this.closestPointToGeometry( mesh, geom, matrix, null, null, minThreshold, maxThreshold );

	}

	closestPointToPoint( mesh, point, target, minThreshold, maxThreshold ) {

		let closestDistance = Infinity;
		for ( const root of this._roots ) {

			const dist = closestPointToPoint( root, mesh, point, target, minThreshold, maxThreshold );
			if ( dist < closestDistance ) closestDistance = dist;
			if ( dist < minThreshold ) return dist;

		}

		return closestDistance;

	}

	distanceToPoint( mesh, point, minThreshold, maxThreshold ) {

		return this.closestPointToPoint( mesh, point, null, minThreshold, maxThreshold );

	}

}
<commit_msg>add packed buffers<commit_after>import MeshBVHNode from './MeshBVHNode.js';
import { CENTER } from './Constants.js';
import { buildTree } from './buildFunctions.js';
import {
	raycast,
	raycastFirst,
	shapecast,
	intersectsGeometry,
	intersectsBox,
	intersectsSphere,
	closestPointToPoint,
	closestPointToGeometry,
} from './castFunctions.js';

// boundingData  				: 6 float32
// right / offset 				: 1 uint32
// splitAxis / isLeaf + count 	: 1 uint32 / 2 uint16
const BYTES_PER_NODE = 6 * 4 + 4 + 4;
const IS_LEAFNODE_FLAG = 0xFFFF;
const SKIP_GENERATION = Symbol( 'skip tree generation' );

export default class MeshBVH {

	static serialize( bvh, geometry, copyIndexBuffer = true ) {

		function finishTree( node ) {

			if ( node.continueGeneration ) {

				node.continueGeneration();

			}

			if ( ! node.count ) {

				finishTree( node.left );
				finishTree( node.right );

			}

		}

		function countNodes( node ) {

			if ( node.count ) {

				return 1;

			} else {

				return 1 + countNodes( node.left ) + countNodes( node.right );

			}

		}

		function populateBuffer( byteOffset, node ) {

			const stride4Offset = byteOffset / 4;
			const stride2Offset = byteOffset / 2;
			const isLeaf = ! ! node.count;
			const boundingData = node.boundingData;
			for ( let i = 0; i < 6; i ++ ) {

				float32Array[ stride4Offset + i ] = boundingData[ i ];

			}

			if ( isLeaf ) {

				const offset = node.offset;
				const count = node.count;
				uint32Array[ stride4Offset + 6 ] = offset;
				uint16Array[ stride2Offset + 14 ] = count;
				uint16Array[ stride2Offset + 15 ] = IS_LEAFNODE_FLAG;
				return byteOffset + BYTES_PER_NODE;

			} else {

				const left = node.left;
				const right = node.right;
				const splitAxis = node.splitAxis;

				let nextUnusedPointer;

				// uint32Array[ stride4Offset + 6 ] = stride4Offset + BYTES_PER_NODE / 4;
				nextUnusedPointer = populateBuffer( byteOffset + BYTES_PER_NODE, left );

				uint32Array[ stride4Offset + 6 ] = nextUnusedPointer / 4;
				nextUnusedPointer = populateBuffer( nextUnusedPointer, right );

				uint32Array[ stride4Offset + 7 ] = splitAxis;
				return nextUnusedPointer;

			}

		}

		let float32Array;
		let uint32Array;
		let uint16Array;

		const roots = bvh._roots;
		const rootData = [];
		for ( let i = 0; i < roots.length; i ++ ) {

			const root = roots[ i ];
			finishTree( root );
			let nodeCount = countNodes( root );

			const buffer = new ArrayBuffer( BYTES_PER_NODE * nodeCount );
			float32Array = new Float32Array( buffer );
			uint32Array = new Uint32Array( buffer );
			uint16Array = new Uint16Array( buffer );
			populateBuffer( 0, root );
			rootData.push( buffer );

		}

		const indexAttribute = geometry.getIndex();
		const result = {
			roots: rootData,
			index: copyIndexBuffer ? indexAttribute.array.slice() : indexAttribute.array,
		};

		return result;

	}

	static deserialize( data, geometry, setIndex = true ) {

		function setData( byteOffset, node ) {

			const stride4Offset = byteOffset / 4;
			const stride2Offset = byteOffset / 2;
			const boundingData = new Float32Array( 6 );
			for ( let i = 0; i < 6; i ++ ) {

				boundingData[ i ] = float32Array[ stride4Offset + i ];

			}
			node.boundingData = boundingData;

			const isLeaf = uint16Array[ stride2Offset + 15 ] === IS_LEAFNODE_FLAG;
			if ( isLeaf ) {

				node.offset = uint32Array[ stride4Offset + 6 ];
				node.count = uint16Array[ stride2Offset + 14 ];

			} else {

				const left = new MeshBVHNode();
				const right = new MeshBVHNode();
				const leftOffset = stride4Offset + BYTES_PER_NODE / 4;
				const rightOffset = uint32Array[ stride4Offset + 6 ];

				setData( leftOffset * 4, left );
				setData( rightOffset * 4, right );

				node.left = left;
				node.right = right;
				node.splitAxis = uint32Array[ stride4Offset + 7 ];

			}

		}

		let float32Array;
		let uint32Array;
		let uint16Array;

		const { index, roots } = data;
		const bvh = new MeshBVH( geometry, { [ SKIP_GENERATION ]: true } );
		bvh._roots = [];
		for ( let i = 0; i < roots.length; i ++ ) {

			const buffer = roots[ i ];
			float32Array = new Float32Array( buffer );
			uint32Array = new Uint32Array( buffer );
			uint16Array = new Uint16Array( buffer );

			const root = new MeshBVHNode();
			setData( 0, root );
			bvh._roots.push( root );

		}

		if ( setIndex ) {

			const indexAttribute = geometry.getIndex();
			if ( indexAttribute.array !== index ) {

				indexAttribute.array.set( index );
				indexAttribute.needsUpdate = true;

			}

		}

		return bvh;

	}

	constructor( geo, options = {} ) {

		if ( ! geo.isBufferGeometry ) {

			throw new Error( 'MeshBVH: Only BufferGeometries are supported.' );

		} else if ( geo.attributes.position.isInterleavedBufferAttribute ) {

			throw new Error( 'MeshBVH: InterleavedBufferAttribute is not supported for the position attribute.' );

		} else if ( geo.index && geo.index.isInterleavedBufferAttribute ) {

			throw new Error( 'MeshBVH: InterleavedBufferAttribute is not supported for the index attribute.' );

		}

		// default options
		options = Object.assign( {

			strategy: CENTER,
			maxDepth: 40,
			maxLeafTris: 10,
			verbose: true,
			lazyGeneration: false,
			packData: false,
			[ SKIP_GENERATION ]: false

		}, options );
		options.strategy = Math.max( 0, Math.min( 2, options.strategy ) );

		this._isPacked = false;
		this._roots = null;
		if ( ! options[ SKIP_GENERATION ] ) {

			this._roots = buildTree( geo, options );
			if ( options.packData ) {

				this._roots = MeshBVH.serialize( this, geo, false ).roots;
				this._isPacked = true;

			}

		}

	}

	/* Public Functions */
	raycast( mesh, raycaster, ray, intersects ) {

		for ( const root of this._roots ) {

			raycast( root, mesh, raycaster, ray, intersects );

		}

	}

	raycastFirst( mesh, raycaster, ray ) {

		let closestResult = null;
		for ( const root of this._roots ) {

			const result = raycastFirst( root, mesh, raycaster, ray );
			if ( result != null && ( closestResult == null || result.distance < closestResult.distance ) ) {

				closestResult = result;

			}

		}

		return closestResult;

	}

	intersectsGeometry( mesh, geometry, geomToMesh ) {

		for ( const root of this._roots ) {

			if ( intersectsGeometry( root, mesh, geometry, geomToMesh ) ) return true;

		}

		return false;

	}

	shapecast( mesh, intersectsBoundsFunc, intersectsTriangleFunc = null, orderNodesFunc = null ) {

		for ( const root of this._roots ) {

			if ( shapecast( root, mesh, intersectsBoundsFunc, intersectsTriangleFunc, orderNodesFunc ) ) return true;

		}

		return false;

	}

	intersectsBox( mesh, box, boxToMesh ) {

		for ( const root of this._roots ) {

			if ( intersectsBox( root, mesh, box, boxToMesh ) ) return true;

		}

		return false;

	}

	intersectsSphere( mesh, sphere ) {

		for ( const root of this._roots ) {

			if ( intersectsSphere( root, mesh, sphere ) ) return true;

		}

		return false;

	}

	closestPointToGeometry( mesh, geom, matrix, target1, target2, minThreshold, maxThreshold ) {

		let closestDistance = Infinity;
		for ( const root of this._roots ) {

			const dist = closestPointToGeometry( root, mesh, geom, matrix, target1, target2, minThreshold, maxThreshold );
			if ( dist < closestDistance ) closestDistance = dist;
			if ( dist < minThreshold ) return dist;

		}

		return closestDistance;

	}

	distanceToGeometry( mesh, geom, matrix, minThreshold, maxThreshold ) {

		return this.closestPointToGeometry( mesh, geom, matrix, null, null, minThreshold, maxThreshold );

	}

	closestPointToPoint( mesh, point, target, minThreshold, maxThreshold ) {

		let closestDistance = Infinity;
		for ( const root of this._roots ) {

			const dist = closestPointToPoint( root, mesh, point, target, minThreshold, maxThreshold );
			if ( dist < closestDistance ) closestDistance = dist;
			if ( dist < minThreshold ) return dist;

		}

		return closestDistance;

	}

	distanceToPoint( mesh, point, minThreshold, maxThreshold ) {

		return this.closestPointToPoint( mesh, point, null, minThreshold, maxThreshold );

	}

}
<|endoftext|>


<commit_before>// Copyright (C) 2016 Goom Inc. All rights reserved.

import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import _ from 'lodash';

import { constants } from 'commons/utils/constants';
import i18n from 'commons/utils/i18n';
import numberUtil from 'commons/utils/numberUtil';
import uploadUtil from 'commons/utils/uploadUtil';

export default React.createClass({
  propTypes: {
    handleSubmit: PropTypes.func,
    signupUser: PropTypes.object,
    updateSignupUser: PropTypes.func,
  },
  getInitialState() {
    if (this.props.signupUser) {
      return this.props.signupUser;
    }
    return { activeAreaCodeIndex: 0 };
  },
  componentWillUnmount() {
    this.props.updateSignupUser(this.state);
  },
  render() {
    const { handleSubmit } = this.props;
    const { areaCodes } = constants;
    const activeAreaCodeIndex = this.state.activeAreaCodeIndex || 0;
    const t = (key) => i18n.get(`pcMain.signup.${key}`);

    const onChange = (e, key) => {
      const nextState = {};
      _.set(nextState, key, e.target.value);
      this.setState(_.merge(this.state, nextState));
    };
    const onlyNumberFieldOnChange = (e, key, maxLen) => {
      if (numberUtil.validateNumberInput(e.target.value, maxLen)) {
        onChange(e, key);
      }
    };
    const renderField = (field) =>
      <input
        key={field.name}
        className={field.className || 'signin-input'}
        value={_.get(this.state, field.key) || ''}
        type={field.type || 'text'}
        placeholder={field.name}
        onChange={(e) => (
          field.onChange ? field.onChange(e) : onChange(e, field.key)
        )}
      />;
    const renderBizInfo = () => {
      const onSelectFile = (e) => {
        const r = new FileReader();
        const bizImageName = e.target.files[0].name;
        r.onload = (event) => {
          this.setState({ bizImageUrl: event.target.result, bizImageName });
        };
        r.readAsDataURL(e.target.files[0]);
      };
      const fields1 = [
        { name: t('bizName'), placeholder: t('bizNamePlaceHolder'), key: 'data.bizName', isRequired: true },
        { name: t('bizNumber'), placeholder: t('bizNumberPlaceHolder'), key: 'data.bizNumber', isRequired: true,
          onChange: (e) => onlyNumberFieldOnChange(e, 'data.bizNumber', 15) },
      ];
      const fields2 = [
        { name: t('returnAccountNumber'), placeholder: '123-456-123456', key: 'data.returnAccountNumber' }, // eslint-disable-line
        { name: t('returnAccountBank'), placeholder: t('returnAccountBankPlaceHolder'), key: 'data.returnAccountBank' }, // eslint-disable-line
        { name: t('returnAccountOwner'), placeholder: t('returnAccountOwnerPlaceHolder'), key: 'data.returnAccountOwner' }, // eslint-disable-line
      ];
      const openBizImagePopup = () => {
        $('#biz-image-button').click();
      };
      const bizImageField = (

          <input id="biz-image-button" type="file" accept="image/*" onChange={onSelectFile} style={({ display: 'none' })} />
          <input type="button" value="사업자 등록증 선택" onClick={openBizImagePopup} />

      );
      return fields1.map(renderField).concat([bizImageField]).concat(fields2.map(renderField));
    };
    const onSubmit = (e) => {
      e.preventDefault();
      const requiredFields = [
        { key: 'email', errorMsg: '이메일을 입력해 주세요' },
        { key: 'password', errorMsg: '비밀번호를 입력해 주세요' },
        { key: 'data.lastName', errorMsg: '성을 입력해 주세요' },
        { key: 'data.firstName', errorMsg: '이름을 입력해 주세요' },
        { key: 'data.tel', errorMsg: '전화번호를 입력해 주세요' },
        { key: 'data.bizName', errorMsg: '사업자명을 입력해 주세요' },
        { key: 'data.bizNumber', errorMsg: '사업자 번호를 입력해 주세요' },
      ];
      const user = _.pick(this.state, ['email', 'password', 'passwordConfirm', 'data']);
      for (let i = 0; i < requiredFields.length; i++) {
        const field = requiredFields[i];
        if (!_.get(user, field.key)) {
          window.alert(field.errorMsg);
          $(`#${field.key.split('.').splice(-1)[0]}`).focus();
          return;
        }
      }
      if (this.state.password !== this.state.passwordConfirm) {
        window.alert('비밀번호가 일치하지 않습니다');
        return;
      }
      if (!this.state.bizImageUrl) {
        window.alert('사업자 등록증을 선택해 주세요');
        return;
      }
      if (!$('#terms_title').is(':checked')) {
        window.alert('이용약관에 동의해 주세요');
        return;
      }
      if (!$('#policies_title').is(':checked')) {
        window.alert('개인정보 수집방침에 동의해 주세요');
        return;
      }
      user.data.areaCode = '+82'; // TODO
      const cb = (result) => {
        user.data.bizImage = result;
        if (user.data.firstName && user.data.lastName) {
          user.name = `${user.data.lastName} ${user.data.firstName}`;
        }
        handleSubmit(user);
      };
      uploadUtil.uploadFile(this.state.bizImageUrl, cb);
    };
    const toggleNumberDropdown = () => {
      const target = $('.form-tel .dropdown-box');
      const display = target.css('display');
      if (display === 'none') {
        target.css('display', 'block');
      } else {
        target.css('display', 'none');
      }
    };
    const renderAreaCodeDropdown = (ac, index) => {
      if (index === activeAreaCodeIndex) {
        return null;
      }
      const onClick = () => {
        toggleNumberDropdown();
        this.setState({ activeAreaCodeIndex: index, data: _.merge(this.state.data || {}, { areaCode: areaCodes[index].number }) });
      };
      return (

           {ac.name} {ac.number}

      );
    };
    return (
      <form onSubmit={onSubmit}>
        <Link to="/" className="signin-title">
          <img className="logo-img" src={`${constants.resourceRoot}/mobile/main/mobile_linkshops_logo.png`} />
        </Link>

          {renderField({ name: '아이디(이메일)', type: 'email', key: 'email' })}
          {renderField({ name: '비밀번호', type: 'password', key: 'password' })}
          {renderField({ name: '비밀번호 확인', type: 'password', key: 'passwordConfirm' })}

            {renderField({ name: '성', className: 'signup-input-lastName', key: 'data.lastName' })}
            {renderField({ name: '이름', className: 'signup-input-firstName', key: 'data.firstName' })}

               {areaCodes[activeAreaCodeIndex].number}

            <input
              id="tel"
              onChange={(e) => (
                onlyNumberFieldOnChange ? onlyNumberFieldOnChange(e, 'data.tel', 12) : onChange(e, 'data.tel')
              )}
              value={_.get(this.state, 'data.tel') || ''}
              type="text" placeholder="전화번호('-' 제외)"
            />

              {areaCodes.map(renderAreaCodeDropdown)}

          {renderBizInfo()}

            <input id="terms_title" type="checkbox" />
             $('#terms_title').click()}>
            이용약관 동의 *
            <Link to="/user/terms" className="show-detail">내용보기</Link>

            <input id="policies_title" type="checkbox" />
             $('#policies_title').click()}>
            개인정보 수집방침 동의 *
            <Link to="/user/policies" className="show-detail">내용보기</Link>

          <button type="submit" className="signin-button">회원가입하기</button>

      </form>
    );
  },
});
<commit_msg>m - update bizNumber placeholder<commit_after>// Copyright (C) 2016 Goom Inc. All rights reserved.

import React, { PropTypes } from 'react';
import { Link } from 'react-router';
import _ from 'lodash';

import { constants } from 'commons/utils/constants';
import i18n from 'commons/utils/i18n';
import numberUtil from 'commons/utils/numberUtil';
import uploadUtil from 'commons/utils/uploadUtil';

export default React.createClass({
  propTypes: {
    handleSubmit: PropTypes.func,
    signupUser: PropTypes.object,
    updateSignupUser: PropTypes.func,
  },
  getInitialState() {
    if (this.props.signupUser) {
      return this.props.signupUser;
    }
    return { activeAreaCodeIndex: 0 };
  },
  componentWillUnmount() {
    this.props.updateSignupUser(this.state);
  },
  render() {
    const { handleSubmit } = this.props;
    const { areaCodes } = constants;
    const activeAreaCodeIndex = this.state.activeAreaCodeIndex || 0;
    const t = (key) => i18n.get(`pcMain.signup.${key}`);

    const onChange = (e, key) => {
      const nextState = {};
      _.set(nextState, key, e.target.value);
      this.setState(_.merge(this.state, nextState));
    };
    const onlyNumberFieldOnChange = (e, key, maxLen) => {
      if (numberUtil.validateNumberInput(e.target.value, maxLen)) {
        onChange(e, key);
      }
    };
    const renderField = (field) =>
      <input
        key={field.name}
        className={field.className || 'signin-input'}
        value={_.get(this.state, field.key) || ''}
        type={field.type || 'text'}
        placeholder={field.name}
        onChange={(e) => (
          field.onChange ? field.onChange(e) : onChange(e, field.key)
        )}
      />;
    const renderBizInfo = () => {
      const onSelectFile = (e) => {
        const r = new FileReader();
        const bizImageName = e.target.files[0].name;
        r.onload = (event) => {
          this.setState({ bizImageUrl: event.target.result, bizImageName });
        };
        r.readAsDataURL(e.target.files[0]);
      };
      const fields1 = [
        { name: t('bizName'), placeholder: t('bizNamePlaceHolder'), key: 'data.bizName', isRequired: true },
        { name: `${t('bizNumber')}('-' 제외)`, placeholder: t('bizNumberPlaceHolder'), key: 'data.bizNumber', isRequired: true,
          onChange: (e) => onlyNumberFieldOnChange(e, 'data.bizNumber', 15) },
      ];
      const fields2 = [
        { name: t('returnAccountNumber'), placeholder: '123-456-123456', key: 'data.returnAccountNumber' }, // eslint-disable-line
        { name: t('returnAccountBank'), placeholder: t('returnAccountBankPlaceHolder'), key: 'data.returnAccountBank' }, // eslint-disable-line
        { name: t('returnAccountOwner'), placeholder: t('returnAccountOwnerPlaceHolder'), key: 'data.returnAccountOwner' }, // eslint-disable-line
      ];
      const openBizImagePopup = () => {
        $('#biz-image-button').click();
      };
      const bizImageField = (

          <input id="biz-image-button" type="file" accept="image/*" onChange={onSelectFile} style={({ display: 'none' })} />
          <input type="button" value="사업자 등록증 선택" onClick={openBizImagePopup} />

      );
      return fields1.map(renderField).concat([bizImageField]).concat(fields2.map(renderField));
    };
    const onSubmit = (e) => {
      e.preventDefault();
      const requiredFields = [
        { key: 'email', errorMsg: '이메일을 입력해 주세요' },
        { key: 'password', errorMsg: '비밀번호를 입력해 주세요' },
        { key: 'data.lastName', errorMsg: '성을 입력해 주세요' },
        { key: 'data.firstName', errorMsg: '이름을 입력해 주세요' },
        { key: 'data.tel', errorMsg: '전화번호를 입력해 주세요' },
        { key: 'data.bizName', errorMsg: '사업자명을 입력해 주세요' },
        { key: 'data.bizNumber', errorMsg: '사업자 번호를 입력해 주세요' },
      ];
      const user = _.pick(this.state, ['email', 'password', 'passwordConfirm', 'data']);
      for (let i = 0; i < requiredFields.length; i++) {
        const field = requiredFields[i];
        if (!_.get(user, field.key)) {
          window.alert(field.errorMsg);
          $(`#${field.key.split('.').splice(-1)[0]}`).focus();
          return;
        }
      }
      if (this.state.password !== this.state.passwordConfirm) {
        window.alert('비밀번호가 일치하지 않습니다');
        return;
      }
      if (!this.state.bizImageUrl) {
        window.alert('사업자 등록증을 선택해 주세요');
        return;
      }
      if (!$('#terms_title').is(':checked')) {
        window.alert('이용약관에 동의해 주세요');
        return;
      }
      if (!$('#policies_title').is(':checked')) {
        window.alert('개인정보 수집방침에 동의해 주세요');
        return;
      }
      user.data.areaCode = '+82'; // TODO
      const cb = (result) => {
        user.data.bizImage = result;
        if (user.data.firstName && user.data.lastName) {
          user.name = `${user.data.lastName} ${user.data.firstName}`;
        }
        handleSubmit(user);
      };
      uploadUtil.uploadFile(this.state.bizImageUrl, cb);
    };
    const toggleNumberDropdown = () => {
      const target = $('.form-tel .dropdown-box');
      const display = target.css('display');
      if (display === 'none') {
        target.css('display', 'block');
      } else {
        target.css('display', 'none');
      }
    };
    const renderAreaCodeDropdown = (ac, index) => {
      if (index === activeAreaCodeIndex) {
        return null;
      }
      const onClick = () => {
        toggleNumberDropdown();
        this.setState({ activeAreaCodeIndex: index, data: _.merge(this.state.data || {}, { areaCode: areaCodes[index].number }) });
      };
      return (

           {ac.name} {ac.number}

      );
    };
    return (
      <form onSubmit={onSubmit}>
        <Link to="/" className="signin-title">
          <img className="logo-img" src={`${constants.resourceRoot}/mobile/main/mobile_linkshops_logo.png`} />
        </Link>

          {renderField({ name: '아이디(이메일)', type: 'email', key: 'email' })}
          {renderField({ name: '비밀번호', type: 'password', key: 'password' })}
          {renderField({ name: '비밀번호 확인', type: 'password', key: 'passwordConfirm' })}

            {renderField({ name: '성', className: 'signup-input-lastName', key: 'data.lastName' })}
            {renderField({ name: '이름', className: 'signup-input-firstName', key: 'data.firstName' })}

               {areaCodes[activeAreaCodeIndex].number}

            <input
              id="tel"
              onChange={(e) => (
                onlyNumberFieldOnChange ? onlyNumberFieldOnChange(e, 'data.tel', 12) : onChange(e, 'data.tel')
              )}
              value={_.get(this.state, 'data.tel') || ''}
              type="text" placeholder="전화번호('-' 제외)"
            />

              {areaCodes.map(renderAreaCodeDropdown)}

          {renderBizInfo()}

            <input id="terms_title" type="checkbox" />
             $('#terms_title').click()}>
            이용약관 동의 *
            <Link to="/user/terms" className="show-detail">내용보기</Link>

            <input id="policies_title" type="checkbox" />
             $('#policies_title').click()}>
            개인정보 수집방침 동의 *
            <Link to="/user/policies" className="show-detail">내용보기</Link>

          <button type="submit" className="signin-button">회원가입하기</button>

      </form>
    );
  },
});
<|endoftext|>


<commit_before>'use babel';

import { CompositeDisposable } from 'atom';

export default {
    subscriptions: null,

    activate(state) {
        // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable
        this.subscriptions = new CompositeDisposable();

        // Register command that toggles this view
        this.subscriptions.add(
            atom.commands.add('atom-workspace', {
                'atom-spanish-valencian-translator:spanish-valencian': () =>
                    this.translate('spa', 'cat_valencia'),
                'atom-spanish-valencian-translator:valencian-spanish': () =>
                    this.translate('cat_valencia', 'spa'),
            }),
        );
    },

    deactivate() {
        this.subscriptions.dispose();
    },

    config: {
        markUnknown: {
            title: 'Mark unknown',
            description: 'If active will mark with a star(*) the words that could not be translated',
            type: 'boolean',
            default: false,
        },
    },

    translate(fromLanguage, toLanguage) {
        const editor = atom.workspace.getActiveTextEditor();
        const markUnknown =
            atom.config.get('atom-spanish-valencian-translator.markUnknown') ||
            false;

        if (!editor) {
            return atom.notifications.addWarning(
                'Must select a text to translate',
            );
        }

        const selectedText = editor.getSelectedText();

        if (selectedText.trim() === '') {
            return atom.notifications.addWarning(
                'Must select a text to translate',
            );
        }

        const url =
            'https://www.apertium.org/apy/translate' +
            `?langpair=${fromLanguage}|${toLanguage}` +
            `&markUnknown=${markUnknown ? 'yes' : 'no'}` +
            `&q=${encodeURIComponent(selectedText)}`;

        fetch(url, {
            method: 'GET',
            headers: {
                Accept: 'application/json',
            },
        })
            .then(response => response.json())
            .then(data => {
                const translatedText =
                    data.responseData && data.responseData.translatedText;

                if (!translatedText) {
                    return atom.notifications.addError(
                        'Unable to get translated text',
                    );
                }

                editor.insertText(translatedText);
            })
            .catch(err =>
                atom.notifications.addError(
                    err || 'Oops.. thats an error for sure',
                ),
            );
    },
};
<commit_msg>Fix valencian to spanish query language on request to the one valid & Update setting mark unknown title to be more descriptive<commit_after>'use babel';

import { CompositeDisposable } from 'atom';

export default {
    subscriptions: null,

    activate(state) {
        // Events subscribed to in atom's system can be easily cleaned up with a CompositeDisposable
        this.subscriptions = new CompositeDisposable();

        // Register command that toggles this view
        this.subscriptions.add(
            atom.commands.add('atom-workspace', {
                'atom-spanish-valencian-translator:spanish-valencian': () =>
                    this.translate('spa', 'cat_valencia'),
                'atom-spanish-valencian-translator:valencian-spanish': () =>
                    this.translate('cat', 'spa'),
            }),
        );
    },

    deactivate() {
        this.subscriptions.dispose();
    },

    config: {
        markUnknown: {
            title: 'Mark unknown words',
            description: 'If active will mark with a star(*) the words that could not be translated',
            type: 'boolean',
            default: false,
        },
    },

    translate(fromLanguage, toLanguage) {
        const editor = atom.workspace.getActiveTextEditor();
        const markUnknown =
            atom.config.get('atom-spanish-valencian-translator.markUnknown') ||
            false;

        if (!editor) {
            return atom.notifications.addWarning(
                'Must select a text to translate',
            );
        }

        const selectedText = editor.getSelectedText();

        if (selectedText.trim() === '') {
            return atom.notifications.addWarning(
                'Must select a text to translate',
            );
        }

        const url =
            'https://www.apertium.org/apy/translate' +
            `?langpair=${fromLanguage}|${toLanguage}` +
            `&markUnknown=${markUnknown ? 'yes' : 'no'}` +
            `&q=${encodeURIComponent(selectedText)}`;

        fetch(url, {
            method: 'GET',
            headers: {
                Accept: 'application/json',
            },
        })
            .then(response => response.json())
            .then(data => {
                const translatedText =
                    data.responseData && data.responseData.translatedText;

                if (!translatedText) {
                    return atom.notifications.addError(
                        'Unable to get translated text',
                    );
                }

                editor.insertText(translatedText);
            })
            .catch(err =>
                atom.notifications.addError(
                    err || 'Oops.. thats an error for sure',
                ),
            );
    },
};
<|endoftext|>