<commit_before>/*jshint multistr:true */

this.recline = this.recline || {};
this.recline.View = this.recline.View || {};

(function($, my) {
// ## SlickGrid Dataset View
//
// Provides a tabular view on a Dataset, based on SlickGrid.
//
// https://github.com/mleibman/SlickGrid
//
// Initialize it with a `recline.Model.Dataset`.
//
// Additional options to drive SlickGrid grid can be given through state.
// The following keys allow for customization:
// * gridOptions: to add options at grid level
// * columnsEditor: to add editor for editable columns
//
// For example:
//    var grid = new recline.View.SlickGrid({
//         model: dataset,
//         el: $el,
//         state: {
//          gridOptions: {editable: true},
//          columnsEditor: [
//            {column: 'date', editor: Slick.Editor.Date },
//            {column: 'title', editor: Slick.Editor.Text}
//          ]
//        }
//      });
//// NB: you need an explicit height on the element for slickgrid to work
my.SlickGrid = Backbone.View.extend({
  initialize: function(modelEtc) {
    var self = this;
    this.el = $(this.el);
    this.el.addClass('recline-slickgrid');
    _.bindAll(this, 'render');
    this.model.records.bind('add', this.render);
    this.model.records.bind('reset', this.render);
    this.model.records.bind('remove', this.render);

    var state = _.extend({
        hiddenColumns: [],
        columnsOrder: [],
        columnsSort: {},
        columnsWidth: [],
        columnsEditor: [],
        options: {},
        fitColumns: false
      }, modelEtc.state

    );
//      this.grid_options = modelEtc.options;
    this.state = new recline.Model.ObjectState(state);
  },

  events: {
  },

  render: function() {
    var self = this;

    var options = _.extend({
      enableCellNavigation: true,
      enableColumnReorder: true,
      explicitInitialization: true,
      syncColumnCellResize: true,
      forceFitColumns: this.state.get('fitColumns')
    }, self.state.get('gridOptions'));

    // We need all columns, even the hidden ones, to show on the column picker
    var columns = [];
    // custom formatter as default one escapes html
    // plus this way we distinguish between rendering/formatting and computed value (so e.g. sort still works ...)
    // row = row index, cell = cell index, value = value, columnDef = column definition, dataContext = full row values
    var formatter = function(row, cell, value, columnDef, dataContext) {
      var field = self.model.fields.get(columnDef.id);
      if (field.renderer) {
        return field.renderer(value, field, dataContext);
      } else {
        return value;
      }
    }
    _.each(this.model.fields.toJSON(),function(field){
      var column = {
        id:field['id'],
        name:field['label'],
        field:field['id'],
        sortable: true,
        minWidth: 80,
        formatter: formatter
      };

      var widthInfo = _.find(self.state.get('columnsWidth'),function(c){return c.column == field.id});
      if (widthInfo){
        column['width'] = widthInfo.width;
      }

      var editInfo = _.find(self.state.get('columnsEditor'),function(c){return c.column == field.id});
      if (editInfo){
        column['editor'] = editInfo.editor;
      }
      columns.push(column);
    });

    // Restrict the visible columns
    var visibleColumns = columns.filter(function(column) {
      return _.indexOf(self.state.get('hiddenColumns'), column.id) == -1;
    });

    // Order them if there is ordering info on the state
    if (this.state.get('columnsOrder') && this.state.get('columnsOrder').length > 0) {
      visibleColumns = visibleColumns.sort(function(a,b){
        return _.indexOf(self.state.get('columnsOrder'),a.id) > _.indexOf(self.state.get('columnsOrder'),b.id) ? 1 : -1;
      });
      columns = columns.sort(function(a,b){
        return _.indexOf(self.state.get('columnsOrder'),a.id) > _.indexOf(self.state.get('columnsOrder'),b.id) ? 1 : -1;
      });
    }

    // Move hidden columns to the end, so they appear at the bottom of the
    // column picker
    var tempHiddenColumns = [];
    for (var i = columns.length -1; i >= 0; i--){
      if (_.indexOf(_.pluck(visibleColumns,'id'),columns[i].id) == -1){
        tempHiddenColumns.push(columns.splice(i,1)[0]);
      }
    }
    columns = columns.concat(tempHiddenColumns);

    function RowSet() {
      var models = [];
      var rows = [];

      this.push = function(model, row) {
        models.push(model);
        rows.push(row);
      }

      this.getLength = function() { return rows.length; }
      this.getItem = function(index) { return rows[index];}
      this.getItemMetadata= function(index) { return {};}
      this.getModel= function(index) { return models[index]; }
    };

    var data = new RowSet();

    this.model.records.each(function(doc){
      var row = {};
      self.model.fields.each(function(field){
        row[field.id] = doc.getFieldValueUnrendered(field);
      });
      data.push(doc, row);
    });

    this.grid = new Slick.Grid(this.el, data, visibleColumns, options);

    // Column sorting
    var sortInfo = this.model.queryState.get('sort');
    if (sortInfo){
      var column = sortInfo[0].field;
      var sortAsc = !(sortInfo[0].order == 'desc');
      this.grid.setSortColumn(column, sortAsc);
    }

    this.grid.onSort.subscribe(function(e, args){
      var order = (args.sortAsc) ? 'asc':'desc';
      var sort = [{
        field: args.sortCol.field,
        order: order
      }];
      self.model.query({sort: sort});
    });

    this.grid.onColumnsReordered.subscribe(function(e, args){
      self.state.set({columnsOrder: _.pluck(self.grid.getColumns(),'id')});
    });

    this.grid.onColumnsResized.subscribe(function(e, args){
        var columns = args.grid.getColumns();
        var defaultColumnWidth = args.grid.getOptions().defaultColumnWidth;
        var columnsWidth = [];
        _.each(columns,function(column){
          if (column.width != defaultColumnWidth){
            columnsWidth.push({column:column.id,width:column.width});
          }
        });
        self.state.set({columnsWidth:columnsWidth});
    });

    this.grid.onCellChange.subscribe(function (e, args) {
      // We need to change the model associated value
      //
      var grid = args.grid;
      var model = data.getModel(args.row);
      var field = grid.getColumns()[args.cell]['id'];
      var v = {};
      v[field] = args.item[field];
      model.set(v);
    });

    var columnpicker = new Slick.Controls.ColumnPicker(columns, this.grid,
                                                       _.extend(options,{state:this.state}));

    if (self.visible){
      self.grid.init();
      self.rendered = true;
    } else {
      // Defer rendering until the view is visible
      self.rendered = false;
    }

    return this;
 },

  show: function() {
    // If the div is hidden, SlickGrid will calculate wrongly some
    // sizes so we must render it explicitly when the view is visible
    if (!this.rendered){
      if (!this.grid){
        this.render();
      }
      this.grid.init();
      this.rendered = true;
    }
    this.visible = true;
  },

  hide: function() {
    this.visible = false;
  }
});

})(jQuery, recline.View);

/*
* Context menu for the column picker, adapted from
* http://mleibman.github.com/SlickGrid/examples/example-grouping
*
*/
(function ($) {
  function SlickColumnPicker(columns, grid, options) {
    var $menu;
    var columnCheckboxes;

    var defaults = {
      fadeSpeed:250
    };

    function init() {
      grid.onHeaderContextMenu.subscribe(handleHeaderContextMenu);
      options = $.extend({}, defaults, options);

      $menu = $('
').appendTo(document.body);

      $menu.bind('mouseleave', function (e) {
        $(this).fadeOut(options.fadeSpeed)
      });
      $menu.bind('click', updateColumn);

    }

    function handleHeaderContextMenu(e, args) {
      e.preventDefault();
      $menu.empty();
      columnCheckboxes = [];

      var $li, $input;
      for (var i = 0; i < columns.length; i++) {
        $li = $('
').appendTo($menu);
        $input = $('<input type="checkbox" />').data('column-id', columns[i].id).attr('id','slick-column-vis-'+columns[i].id);
        columnCheckboxes.push($input);

        if (grid.getColumnIndex(columns[i].id) != null) {
          $input.attr('checked', 'checked');
        }
        $input.appendTo($li);
        $('')
            .text(columns[i].name)
            .attr('for','slick-column-vis-'+columns[i].id)
            .appendTo($li);
      }
      $('
').addClass('divider').appendTo($menu);
      $li = $('
').data('option', 'autoresize').appendTo($menu);
      $input = $('<input type="checkbox" />').data('option', 'autoresize').attr('id','slick-option-autoresize');
      $input.appendTo($li);
      $('')
          .text('Force fit columns')
          .attr('for','slick-option-autoresize')
          .appendTo($li);
      if (grid.getOptions().forceFitColumns) {
        $input.attr('checked', 'checked');
      }

      $menu.css('top', e.pageY - 10)
          .css('left', e.pageX - 10)
          .fadeIn(options.fadeSpeed);
    }

    function updateColumn(e) {
      if ($(e.target).data('option') == 'autoresize') {
        var checked;
        if ($(e.target).is('li')){
            var checkbox = $(e.target).find('input').first();
            checked = !checkbox.is(':checked');
            checkbox.attr('checked',checked);
        } else {
          checked = e.target.checked;
        }

        if (checked) {
          grid.setOptions({forceFitColumns:true});
          grid.autosizeColumns();
        } else {
          grid.setOptions({forceFitColumns:false});
        }
        options.state.set({fitColumns:checked});
        return;
      }

      if (($(e.target).is('li') && !$(e.target).hasClass('divider')) ||
            $(e.target).is('input')) {
        if ($(e.target).is('li')){
            var checkbox = $(e.target).find('input').first();
            checkbox.attr('checked',!checkbox.is(':checked'));
        }
        var visibleColumns = [];
        var hiddenColumnsIds = [];
        $.each(columnCheckboxes, function (i, e) {
          if ($(this).is(':checked')) {
            visibleColumns.push(columns[i]);
          } else {
            hiddenColumnsIds.push(columns[i].id);
          }
        });

        if (!visibleColumns.length) {
          $(e.target).attr('checked', 'checked');
          return;
        }

        grid.setColumns(visibleColumns);
        options.state.set({hiddenColumns:hiddenColumnsIds});
      }
    }
    init();
  }

  // Slick.Controls.ColumnPicker
  $.extend(true, window, { Slick:{ Controls:{ ColumnPicker:SlickColumnPicker }}});
})(jQuery);
<commit_msg>Fixed typo in comments<commit_after>/*jshint multistr:true */

this.recline = this.recline || {};
this.recline.View = this.recline.View || {};

(function($, my) {
// ## SlickGrid Dataset View
//
// Provides a tabular view on a Dataset, based on SlickGrid.
//
// https://github.com/mleibman/SlickGrid
//
// Initialize it with a `recline.Model.Dataset`.
//
// Additional options to drive SlickGrid grid can be given through state.
// The following keys allow for customization:
// * gridOptions: to add options at grid level
// * columnsEditor: to add editor for editable columns
//
// For example:
//    var grid = new recline.View.SlickGrid({
//         model: dataset,
//         el: $el,
//         state: {
//          gridOptions: {editable: true},
//          columnsEditor: [
//            {column: 'date', editor: Slick.Editors.Date },
//            {column: 'title', editor: Slick.Editors.Text}
//          ]
//        }
//      });
//// NB: you need an explicit height on the element for slickgrid to work
my.SlickGrid = Backbone.View.extend({
  initialize: function(modelEtc) {
    var self = this;
    this.el = $(this.el);
    this.el.addClass('recline-slickgrid');
    _.bindAll(this, 'render');
    this.model.records.bind('add', this.render);
    this.model.records.bind('reset', this.render);
    this.model.records.bind('remove', this.render);

    var state = _.extend({
        hiddenColumns: [],
        columnsOrder: [],
        columnsSort: {},
        columnsWidth: [],
        columnsEditor: [],
        options: {},
        fitColumns: false
      }, modelEtc.state

    );
//      this.grid_options = modelEtc.options;
    this.state = new recline.Model.ObjectState(state);
  },

  events: {
  },

  render: function() {
    var self = this;

    var options = _.extend({
      enableCellNavigation: true,
      enableColumnReorder: true,
      explicitInitialization: true,
      syncColumnCellResize: true,
      forceFitColumns: this.state.get('fitColumns')
    }, self.state.get('gridOptions'));

    // We need all columns, even the hidden ones, to show on the column picker
    var columns = [];
    // custom formatter as default one escapes html
    // plus this way we distinguish between rendering/formatting and computed value (so e.g. sort still works ...)
    // row = row index, cell = cell index, value = value, columnDef = column definition, dataContext = full row values
    var formatter = function(row, cell, value, columnDef, dataContext) {
      var field = self.model.fields.get(columnDef.id);
      if (field.renderer) {
        return field.renderer(value, field, dataContext);
      } else {
        return value;
      }
    }
    _.each(this.model.fields.toJSON(),function(field){
      var column = {
        id:field['id'],
        name:field['label'],
        field:field['id'],
        sortable: true,
        minWidth: 80,
        formatter: formatter
      };

      var widthInfo = _.find(self.state.get('columnsWidth'),function(c){return c.column == field.id});
      if (widthInfo){
        column['width'] = widthInfo.width;
      }

      var editInfo = _.find(self.state.get('columnsEditor'),function(c){return c.column == field.id});
      if (editInfo){
        column['editor'] = editInfo.editor;
      }
      columns.push(column);
    });

    // Restrict the visible columns
    var visibleColumns = columns.filter(function(column) {
      return _.indexOf(self.state.get('hiddenColumns'), column.id) == -1;
    });

    // Order them if there is ordering info on the state
    if (this.state.get('columnsOrder') && this.state.get('columnsOrder').length > 0) {
      visibleColumns = visibleColumns.sort(function(a,b){
        return _.indexOf(self.state.get('columnsOrder'),a.id) > _.indexOf(self.state.get('columnsOrder'),b.id) ? 1 : -1;
      });
      columns = columns.sort(function(a,b){
        return _.indexOf(self.state.get('columnsOrder'),a.id) > _.indexOf(self.state.get('columnsOrder'),b.id) ? 1 : -1;
      });
    }

    // Move hidden columns to the end, so they appear at the bottom of the
    // column picker
    var tempHiddenColumns = [];
    for (var i = columns.length -1; i >= 0; i--){
      if (_.indexOf(_.pluck(visibleColumns,'id'),columns[i].id) == -1){
        tempHiddenColumns.push(columns.splice(i,1)[0]);
      }
    }
    columns = columns.concat(tempHiddenColumns);

    function RowSet() {
      var models = [];
      var rows = [];

      this.push = function(model, row) {
        models.push(model);
        rows.push(row);
      }

      this.getLength = function() { return rows.length; }
      this.getItem = function(index) { return rows[index];}
      this.getItemMetadata= function(index) { return {};}
      this.getModel= function(index) { return models[index]; }
    };

    var data = new RowSet();

    this.model.records.each(function(doc){
      var row = {};
      self.model.fields.each(function(field){
        row[field.id] = doc.getFieldValueUnrendered(field);
      });
      data.push(doc, row);
    });

    this.grid = new Slick.Grid(this.el, data, visibleColumns, options);

    // Column sorting
    var sortInfo = this.model.queryState.get('sort');
    if (sortInfo){
      var column = sortInfo[0].field;
      var sortAsc = !(sortInfo[0].order == 'desc');
      this.grid.setSortColumn(column, sortAsc);
    }

    this.grid.onSort.subscribe(function(e, args){
      var order = (args.sortAsc) ? 'asc':'desc';
      var sort = [{
        field: args.sortCol.field,
        order: order
      }];
      self.model.query({sort: sort});
    });

    this.grid.onColumnsReordered.subscribe(function(e, args){
      self.state.set({columnsOrder: _.pluck(self.grid.getColumns(),'id')});
    });

    this.grid.onColumnsResized.subscribe(function(e, args){
        var columns = args.grid.getColumns();
        var defaultColumnWidth = args.grid.getOptions().defaultColumnWidth;
        var columnsWidth = [];
        _.each(columns,function(column){
          if (column.width != defaultColumnWidth){
            columnsWidth.push({column:column.id,width:column.width});
          }
        });
        self.state.set({columnsWidth:columnsWidth});
    });

    this.grid.onCellChange.subscribe(function (e, args) {
      // We need to change the model associated value
      //
      var grid = args.grid;
      var model = data.getModel(args.row);
      var field = grid.getColumns()[args.cell]['id'];
      var v = {};
      v[field] = args.item[field];
      model.set(v);
    });

    var columnpicker = new Slick.Controls.ColumnPicker(columns, this.grid,
                                                       _.extend(options,{state:this.state}));

    if (self.visible){
      self.grid.init();
      self.rendered = true;
    } else {
      // Defer rendering until the view is visible
      self.rendered = false;
    }

    return this;
 },

  show: function() {
    // If the div is hidden, SlickGrid will calculate wrongly some
    // sizes so we must render it explicitly when the view is visible
    if (!this.rendered){
      if (!this.grid){
        this.render();
      }
      this.grid.init();
      this.rendered = true;
    }
    this.visible = true;
  },

  hide: function() {
    this.visible = false;
  }
});

})(jQuery, recline.View);

/*
* Context menu for the column picker, adapted from
* http://mleibman.github.com/SlickGrid/examples/example-grouping
*
*/
(function ($) {
  function SlickColumnPicker(columns, grid, options) {
    var $menu;
    var columnCheckboxes;

    var defaults = {
      fadeSpeed:250
    };

    function init() {
      grid.onHeaderContextMenu.subscribe(handleHeaderContextMenu);
      options = $.extend({}, defaults, options);

      $menu = $('
').appendTo(document.body);

      $menu.bind('mouseleave', function (e) {
        $(this).fadeOut(options.fadeSpeed)
      });
      $menu.bind('click', updateColumn);

    }

    function handleHeaderContextMenu(e, args) {
      e.preventDefault();
      $menu.empty();
      columnCheckboxes = [];

      var $li, $input;
      for (var i = 0; i < columns.length; i++) {
        $li = $('
').appendTo($menu);
        $input = $('<input type="checkbox" />').data('column-id', columns[i].id).attr('id','slick-column-vis-'+columns[i].id);
        columnCheckboxes.push($input);

        if (grid.getColumnIndex(columns[i].id) != null) {
          $input.attr('checked', 'checked');
        }
        $input.appendTo($li);
        $('')
            .text(columns[i].name)
            .attr('for','slick-column-vis-'+columns[i].id)
            .appendTo($li);
      }
      $('
').addClass('divider').appendTo($menu);
      $li = $('
').data('option', 'autoresize').appendTo($menu);
      $input = $('<input type="checkbox" />').data('option', 'autoresize').attr('id','slick-option-autoresize');
      $input.appendTo($li);
      $('')
          .text('Force fit columns')
          .attr('for','slick-option-autoresize')
          .appendTo($li);
      if (grid.getOptions().forceFitColumns) {
        $input.attr('checked', 'checked');
      }

      $menu.css('top', e.pageY - 10)
          .css('left', e.pageX - 10)
          .fadeIn(options.fadeSpeed);
    }

    function updateColumn(e) {
      if ($(e.target).data('option') == 'autoresize') {
        var checked;
        if ($(e.target).is('li')){
            var checkbox = $(e.target).find('input').first();
            checked = !checkbox.is(':checked');
            checkbox.attr('checked',checked);
        } else {
          checked = e.target.checked;
        }

        if (checked) {
          grid.setOptions({forceFitColumns:true});
          grid.autosizeColumns();
        } else {
          grid.setOptions({forceFitColumns:false});
        }
        options.state.set({fitColumns:checked});
        return;
      }

      if (($(e.target).is('li') && !$(e.target).hasClass('divider')) ||
            $(e.target).is('input')) {
        if ($(e.target).is('li')){
            var checkbox = $(e.target).find('input').first();
            checkbox.attr('checked',!checkbox.is(':checked'));
        }
        var visibleColumns = [];
        var hiddenColumnsIds = [];
        $.each(columnCheckboxes, function (i, e) {
          if ($(this).is(':checked')) {
            visibleColumns.push(columns[i]);
          } else {
            hiddenColumnsIds.push(columns[i].id);
          }
        });

        if (!visibleColumns.length) {
          $(e.target).attr('checked', 'checked');
          return;
        }

        grid.setColumns(visibleColumns);
        options.state.set({hiddenColumns:hiddenColumnsIds});
      }
    }
    init();
  }

  // Slick.Controls.ColumnPicker
  $.extend(true, window, { Slick:{ Controls:{ ColumnPicker:SlickColumnPicker }}});
})(jQuery);
<|endoftext|>


<commit_before>/**
 * @license
 * Copyright The Closure Library Authors.
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Generated Protocol Buffer code for file
 * closure/goog/proto2/package_test.proto.
 */

goog.provide('someprotopackage.TestPackageTypes');
goog.setTestOnly('someprotopackage.TestPackageTypes');

goog.require('goog.proto2.Message');
goog.require('proto2.TestAllTypes');

/**
 * Message TestPackageTypes.
 * @constructor
 * @extends {goog.proto2.Message}
 * @final
 */
someprotopackage.TestPackageTypes = function() {
  goog.proto2.Message.call(this);
};
goog.inherits(someprotopackage.TestPackageTypes, goog.proto2.Message);

/**
 * Descriptor for this message, deserialized lazily in getDescriptor().
 * @private {?goog.proto2.Descriptor}
 */
someprotopackage.TestPackageTypes.descriptor_ = null;

/**
 * Overrides {@link goog.proto2.Message#clone} to specify its exact return type.
 * @return {!someprotopackage.TestPackageTypes} The cloned message.
 * @override
 */
someprotopackage.TestPackageTypes.prototype.clone;

/**
 * Gets the value of the optional_int32 field.
 * @return {?number} The value.
 */
someprotopackage.TestPackageTypes.prototype.getOptionalInt32 = function() {
  return /** @type {?number} */ (this.get$Value(1));
};

/**
 * Gets the value of the optional_int32 field or the default value if not set.
 * @return {number} The value.
 */
someprotopackage.TestPackageTypes.prototype.getOptionalInt32OrDefault = function() {
  return /** @type {number} */ (this.get$ValueOrDefault(1));
};

/**
 * Sets the value of the optional_int32 field.
 * @param {number} value The value.
 */
someprotopackage.TestPackageTypes.prototype.setOptionalInt32 = function(value) {
  this.set$Value(1, value);
};

/**
 * @return {boolean} Whether the optional_int32 field has a value.
 */
someprotopackage.TestPackageTypes.prototype.hasOptionalInt32 = function() {
  return this.has$Value(1);
};

/**
 * @return {number} The number of values in the optional_int32 field.
 */
someprotopackage.TestPackageTypes.prototype.optionalInt32Count = function() {
  return this.count$Values(1);
};

/**
 * Clears the values in the optional_int32 field.
 */
someprotopackage.TestPackageTypes.prototype.clearOptionalInt32 = function() {
  this.clear$Field(1);
};

/**
 * Gets the value of the other_all field.
 * @return {?proto2.TestAllTypes} The value.
 */
someprotopackage.TestPackageTypes.prototype.getOtherAll = function() {
  return /** @type {?proto2.TestAllTypes} */ (this.get$Value(2));
};

/**
 * Gets the value of the other_all field or the default value if not set.
 * @return {!proto2.TestAllTypes} The value.
 */
someprotopackage.TestPackageTypes.prototype.getOtherAllOrDefault = function() {
  return /** @type {!proto2.TestAllTypes} */ (this.get$ValueOrDefault(2));
};

/**
 * Sets the value of the other_all field.
 * @param {!proto2.TestAllTypes} value The value.
 */
someprotopackage.TestPackageTypes.prototype.setOtherAll = function(value) {
  this.set$Value(2, value);
};

/**
 * @return {boolean} Whether the other_all field has a value.
 */
someprotopackage.TestPackageTypes.prototype.hasOtherAll = function() {
  return this.has$Value(2);
};

/**
 * @return {number} The number of values in the other_all field.
 */
someprotopackage.TestPackageTypes.prototype.otherAllCount = function() {
  return this.count$Values(2);
};

/**
 * Clears the values in the other_all field.
 */
someprotopackage.TestPackageTypes.prototype.clearOtherAll = function() {
  this.clear$Field(2);
};

/** @override */
someprotopackage.TestPackageTypes.prototype.getDescriptor = function() {
  let descriptor = someprotopackage.TestPackageTypes.descriptor_;
  if (!descriptor) {
    // The descriptor is created lazily when we instantiate a new instance.
    const descriptorObj = {
      0: {
        name: 'TestPackageTypes',
        fullName: 'someprotopackage.TestPackageTypes'
      },
      1: {
        name: 'optional_int32',
        fieldType: goog.proto2.Message.FieldType.INT32,
        type: Number
      },
      2: {
        name: 'other_all',
        fieldType: goog.proto2.Message.FieldType.MESSAGE,
        type: proto2.TestAllTypes
      }
    };
    someprotopackage.TestPackageTypes.descriptor_ = descriptor =
        goog.proto2.Message.createDescriptor(
             someprotopackage.TestPackageTypes, descriptorObj);
  }
  return descriptor;
};

/** @nocollapse */
someprotopackage.TestPackageTypes.getDescriptor =
    someprotopackage.TestPackageTypes.prototype.getDescriptor;
<commit_msg>Internal change<commit_after>/**
 * @license
 * Copyright The Closure Library Authors.
 * SPDX-License-Identifier: Apache-2.0
 */

/**
 * @fileoverview Generated Protocol Buffer code for file
 * closure/goog/proto2/package_test.proto.
 */

goog.provide('someprotopackage.TestPackageTypes');
goog.setTestOnly('someprotopackage.TestPackageTypes');

goog.require('goog.proto2.Message');
goog.require('proto2.TestAllTypes');
goog.requireType('goog.proto2.Descriptor');

/**
 * Message TestPackageTypes.
 * @constructor
 * @extends {goog.proto2.Message}
 * @final
 */
someprotopackage.TestPackageTypes = function() {
  goog.proto2.Message.call(this);
};
goog.inherits(someprotopackage.TestPackageTypes, goog.proto2.Message);

/**
 * Descriptor for this message, deserialized lazily in getDescriptor().
 * @private {?goog.proto2.Descriptor}
 */
someprotopackage.TestPackageTypes.descriptor_ = null;

/**
 * Overrides {@link goog.proto2.Message#clone} to specify its exact return type.
 * @return {!someprotopackage.TestPackageTypes} The cloned message.
 * @override
 */
someprotopackage.TestPackageTypes.prototype.clone;

/**
 * Gets the value of the optional_int32 field.
 * @return {?number} The value.
 */
someprotopackage.TestPackageTypes.prototype.getOptionalInt32 = function() {
  return /** @type {?number} */ (this.get$Value(1));
};

/**
 * Gets the value of the optional_int32 field or the default value if not set.
 * @return {number} The value.
 */
someprotopackage.TestPackageTypes.prototype.getOptionalInt32OrDefault = function() {
  return /** @type {number} */ (this.get$ValueOrDefault(1));
};

/**
 * Sets the value of the optional_int32 field.
 * @param {number} value The value.
 */
someprotopackage.TestPackageTypes.prototype.setOptionalInt32 = function(value) {
  this.set$Value(1, value);
};

/**
 * @return {boolean} Whether the optional_int32 field has a value.
 */
someprotopackage.TestPackageTypes.prototype.hasOptionalInt32 = function() {
  return this.has$Value(1);
};

/**
 * @return {number} The number of values in the optional_int32 field.
 */
someprotopackage.TestPackageTypes.prototype.optionalInt32Count = function() {
  return this.count$Values(1);
};

/**
 * Clears the values in the optional_int32 field.
 */
someprotopackage.TestPackageTypes.prototype.clearOptionalInt32 = function() {
  this.clear$Field(1);
};

/**
 * Gets the value of the other_all field.
 * @return {?proto2.TestAllTypes} The value.
 */
someprotopackage.TestPackageTypes.prototype.getOtherAll = function() {
  return /** @type {?proto2.TestAllTypes} */ (this.get$Value(2));
};

/**
 * Gets the value of the other_all field or the default value if not set.
 * @return {!proto2.TestAllTypes} The value.
 */
someprotopackage.TestPackageTypes.prototype.getOtherAllOrDefault = function() {
  return /** @type {!proto2.TestAllTypes} */ (this.get$ValueOrDefault(2));
};

/**
 * Sets the value of the other_all field.
 * @param {!proto2.TestAllTypes} value The value.
 */
someprotopackage.TestPackageTypes.prototype.setOtherAll = function(value) {
  this.set$Value(2, value);
};

/**
 * @return {boolean} Whether the other_all field has a value.
 */
someprotopackage.TestPackageTypes.prototype.hasOtherAll = function() {
  return this.has$Value(2);
};

/**
 * @return {number} The number of values in the other_all field.
 */
someprotopackage.TestPackageTypes.prototype.otherAllCount = function() {
  return this.count$Values(2);
};

/**
 * Clears the values in the other_all field.
 */
someprotopackage.TestPackageTypes.prototype.clearOtherAll = function() {
  this.clear$Field(2);
};

/** @override */
someprotopackage.TestPackageTypes.prototype.getDescriptor = function() {
  let descriptor = someprotopackage.TestPackageTypes.descriptor_;
  if (!descriptor) {
    // The descriptor is created lazily when we instantiate a new instance.
    const descriptorObj = {
      0: {
        name: 'TestPackageTypes',
        fullName: 'someprotopackage.TestPackageTypes'
      },
      1: {
        name: 'optional_int32',
        fieldType: goog.proto2.Message.FieldType.INT32,
        type: Number
      },
      2: {
        name: 'other_all',
        fieldType: goog.proto2.Message.FieldType.MESSAGE,
        type: proto2.TestAllTypes
      }
    };
    someprotopackage.TestPackageTypes.descriptor_ = descriptor =
        goog.proto2.Message.createDescriptor(
             someprotopackage.TestPackageTypes, descriptorObj);
  }
  return descriptor;
};

/** @nocollapse */
someprotopackage.TestPackageTypes.getDescriptor =
    someprotopackage.TestPackageTypes.prototype.getDescriptor;
<|endoftext|>


<commit_before>import postgrest from 'mithril-postgrest';
import moment from 'moment';
import I18n from 'i18n-js';
import h from '../h';
import usersVM from './user-vm';
import models from '../models';
const I18nScope = _.partial(h.i18nScope, 'projects.contributions.edit.errors');

const paymentVM = (mode = 'aon') => {
    const pagarme = m.prop({}),
        submissionError = m.prop(false),
        isLoading = m.prop(false);

    const setCsrfToken = (xhr) => {
        if (h.authenticityToken()) {
            xhr.setRequestHeader('X-CSRF-Token', h.authenticityToken());
        }
        return;
    };

    const fields = {
        completeName: m.prop(''),
        email: m.prop(''),
        anonymous: m.prop(),
        countries: m.prop(),
        userCountryId: m.prop(),
        zipCode: m.prop(''),
        street: m.prop(''),
        number: m.prop(''),
        addressComplement: m.prop(''),
        neighbourhood: m.prop(''),
        city: m.prop(''),
        states: m.prop([]),
        userState: m.prop(),
        ownerDocument: m.prop(''),
        phone: m.prop(''),
        errors: m.prop([])
    };

    const creditCardFields = {
        name: m.prop(''),
        number: m.prop(''),
        expMonth: m.prop(''),
        expYear: m.prop(''),
        save: m.prop(false),
        cvv: m.prop(''),
        errors: m.prop([])
    };

    const faq = I18n.translations[I18n.currentLocale()].projects.faq[mode],
        currentUser = h.getUser(),
        countriesLoader = postgrest.loader(models.country.getPageOptions()),
        statesLoader = postgrest.loader(models.state.getPageOptions());

    const populateForm = (fetchedData) => {
        const data = _.first(fetchedData);

        fields.completeName(data.name);
        fields.email(data.email);
        fields.city(data.address.city);
        fields.zipCode(data.address.zipcode);
        fields.street(data.address.street);
        fields.number(data.address.number);
        fields.addressComplement(data.address.complement);
        fields.userState(data.address.state);
        fields.userCountryId(data.address.country_id);
        fields.ownerDocument(data.owner_document);
        fields.phone(data.address.phonenumber);
        fields.neighbourhood(data.address.neighbourhood);
    };

    const expMonthOptions = () => {
        return [
            [1, '01 - Janeiro'],
            [2, '02 - Fevereiro'],
            [3, '03 - Março'],
            [4, '04 - Abril'],
            [5, '05 - Maio'],
            [6, '06 - Junho'],
            [7, '07 - Julho'],
            [8, '08 - Agosto'],
            [9, '09 - Setembro'],
            [10, '10 - Outubro'],
            [11, '11 - Novembro'],
            [12, '12 - Dezembro']
        ];
    };

    const expYearOptions = () => {
        const currentYear = moment().year();
        let yearsOptions = [];
        for (let i = currentYear; i <= currentYear + 25; i++) {
            yearsOptions.push(i);
        }
        return yearsOptions;
    };

    const isInternational = () => {
        return !_.isEmpty(fields.countries()) ? fields.userCountryId() != _.findWhere(fields.countries(), {name: 'Brasil'}).id : false;
    };

    const checkEmptyFields = (checkedFields) => {
        return _.map(checkedFields, (field) => {
            if (_.isEmpty(String(fields[field]()).trim())) {
                fields.errors().push({field: field, message: 'O campo não pode ser vazio.'});
            }
        });
    };

    const checkEmail = () => {
        const isValid = h.validateEmail(fields.email());

        if (!isValid){
            fields.errors().push({field: 'email', message: 'E-mail inválido.'});
        }
    };

    const checkDocument = () => {
        //TODO: also validate Cnpj
        const isValid = h.validateCpf(fields.ownerDocument().replace(/[\.|\-]*/g,''));

        if (!isValid){
            fields.errors().push({field: 'ownerDocument', message: 'CPF inválido.'});
        }
    };

    const validate = () => {
        fields.errors([]);

        checkEmptyFields(['completeName', 'street', 'number', 'city']);

        checkEmail();

        if (!isInternational()){
            checkEmptyFields(['phone', 'neighbourhood']);
            checkDocument();
        }

        return _.isEmpty(fields.errors());
    };

    const getSlipPaymentDate = (contribution_id) => {
        const paymentDate = m.prop();

        m.request({
            method: 'GET',
            config: setCsrfToken,
            url: `/payment/pagarme/${contribution_id}/slip_data`
        }).then(paymentDate);

        return paymentDate;
    };

    const savedCreditCards = m.prop([]);

    const getSavedCreditCards = (user_id) => {
        const otherSample = {
            id: -1
        };

        return m.request({
            method: 'GET',
            config: setCsrfToken,
            url: `/users/${user_id}/credit_cards`
        }).then((creditCards) => {
            if (_.isArray(creditCards)){
                creditCards.push(otherSample);
            } else {
                creditCards = [];
            }

            return savedCreditCards(creditCards);
        });
    };

    const requestPayment = (data, contribution_id) => {
        return m.request({
            method: 'POST',
            url: `/payment/pagarme/${contribution_id}/pay_credit_card`,
            data: data,
            config: setCsrfToken
        });
    };

    const payWithSavedCard = (creditCard, installment, contribution_id) => {
        const data = {
            card_id: creditCard.card_key,
            payment_card_installments: installment
        };
        return requestPayment(data, contribution_id);
    };

    const setNewCreditCard = () => {
        let creditCard = new window.PagarMe.creditCard();
        creditCard.cardHolderName = creditCardFields.name();
        creditCard.cardExpirationMonth = creditCardFields.expMonth();
        creditCard.cardExpirationYear = creditCardFields.expYear();
        creditCard.cardNumber = creditCardFields.number();
        creditCard.cardCVV = creditCardFields.cvv();
        return creditCard;
    };

    const payWithNewCard = (contribution_id, installment) => {
        const deferred = m.deferred();
        m.request({
            method: 'GET',
            url: `/payment/pagarme/${contribution_id}/get_encryption_key`,
            config: setCsrfToken
        }).then((data) => {
            window.PagarMe.encryption_key = data.key;
            const card = setNewCreditCard();
            const errors = card.fieldErrors();
            if (_.keys(errors).length > 0) {
                deferred.reject({message: I18n.t('submission.card_invalid', I18nScope())});
            } else {
                card.generateHash((cardHash) => {
                    const data = {
                        card_hash: cardHash,
                        save_card: creditCardFields.save().toString(),
                        payment_card_installments: installment
                    };
                    requestPayment(data, contribution_id).then(deferred.resolve).catch(deferred.reject);
                });

            }
        }).catch((error) => {
            if(!_.isEmpty(error.message)){
                deferred.reject(error);
            } else {
                deferred.reject({message: I18n.t('submission.encryption_error', I18nScope())});
            }
        });

        return deferred.promise;
    };

    const updateContributionData = (contribution_id, project_id) => {
        const contributionData = {
            anonymous: fields.anonymous(),
            country_id: fields.userCountryId(),
            payer_name: fields.completeName(),
            payer_email: fields.email(),
            payer_document: fields.ownerDocument(),
            address_street: fields.street(),
            address_number: fields.number(),
            address_complement: fields.addressComplement(),
            address_neighbourhood: fields.neighbourhood(),
            address_zip_code: fields.zipCode(),
            address_city: fields.city(),
            address_state: fields.userState(),
            address_phone_number: fields.phone()
        };

        return m.request({
            method: 'PUT',
            url: `/projects/${project_id}/contributions/${contribution_id}.json`,
            data: {contribution: contributionData},
            config: setCsrfToken
        });
    };

    const creditCardPaymentSuccess = (deferred, project_id, contribution_id) => (data) => {
        if (data.payment_status === 'failed') {
            const errorMsg = data.message || I18n.t('submission.payment_failed', I18nScope());

            isLoading(false);
            submissionError(I18n.t('submission.error', I18nScope({message: errorMsg})));
            m.redraw();
            deferred.reject();
        } else {
            window.location.href = `/projects/${project_id}/contributions/${contribution_id}`;
        }
    };

    const creditCardPaymentFail = (deferred) => (data) => {
        isLoading(false);
        submissionError(I18n.t('submission.error', I18nScope({message: data.message})));
        m.redraw();
        deferred.reject();
    };

    const checkAndPayCreditCard = (deferred, selectedCreditCard, contribution_id, project_id, selectedInstallment) => () => {
        if (selectedCreditCard().id && selectedCreditCard().id !== -1) {
            return payWithSavedCard(selectedCreditCard(), selectedInstallment(), contribution_id)
                .then(creditCardPaymentSuccess(deferred, project_id, contribution_id))
                .catch(creditCardPaymentFail(deferred));
        } else {
            if (selectedCreditCard().id === -1) {
                return payWithNewCard(contribution_id, selectedInstallment)
                    .then(creditCardPaymentSuccess(deferred, project_id, contribution_id))
                    .catch(creditCardPaymentFail(deferred));
            } else {
                submissionError(I18n.t('submission.error', I18nScope({message: `Nenhum cartão escolhido.`})));
                m.redraw();
            }

        }
    };

    const sendPayment = (selectedCreditCard, selectedInstallment, contribution_id, project_id) => {
        const deferred = m.deferred();
        if (validate()) {
            isLoading(true);
            submissionError(false);
            m.redraw();
            updateContributionData(contribution_id, project_id)
                .then(checkAndPayCreditCard(deferred, selectedCreditCard, contribution_id, project_id, selectedInstallment))
                .catch(() => {
                    isLoading(false);
                    deferred.reject();
                });

        } else {
            isLoading(false);
            deferred.reject();
        }
        return deferred.promise;
    };

    const resetFieldError = (fieldName) => () => {
        const errors = fields.errors(),
            errorField = _.findWhere(fields.errors(), {field: fieldName}),
            newErrors = _.compose(fields.errors, _.without);

        return newErrors(fields.errors(), errorField);
    };

    const resetCreditCardFieldError = (fieldName) => () => {
        const errors = fields.errors(),
            errorField = _.findWhere(creditCardFields.errors(), {field: fieldName}),
            newErrors = _.compose(creditCardFields.errors, _.without);

        return newErrors(creditCardFields.errors(), errorField);
    };

    const installments = m.prop([{value: 10, number: 1}]);

    const getInstallments = (contribution_id) => {
        return m.request({
            method: 'GET',
            url: `/payment/pagarme/${contribution_id}/get_installment`,
            config: h.setCsrfToken
        }).then(installments);
    };

    const creditCardMask = _.partial(h.mask, '9999 9999 9999 9999');

    const applyCreditCardMask = _.compose(creditCardFields.number, creditCardMask);

    countriesLoader.load().then(fields.countries);
    statesLoader.load().then(fields.states);
    usersVM.fetchUser(currentUser.user_id, false).then(populateForm);

    return {
        fields: fields,
        validate: validate,
        isInternational: isInternational,
        resetFieldError: resetFieldError,
        getSlipPaymentDate: getSlipPaymentDate,
        installments: installments,
        getInstallments: getInstallments,
        savedCreditCards: savedCreditCards,
        getSavedCreditCards: getSavedCreditCards,
        applyCreditCardMask: applyCreditCardMask,
        creditCardFields: creditCardFields,
        resetCreditCardFieldError: resetCreditCardFieldError,
        expMonthOptions: expMonthOptions,
        expYearOptions: expYearOptions,
        sendPayment: sendPayment,
        submissionError: submissionError,
        isLoading: isLoading,
        pagarme: pagarme,
        faq: faq
    };
};

export default paymentVM;
<commit_msg>Removes unecessary id check. Considers new credit card if id is not set<commit_after>import postgrest from 'mithril-postgrest';
import moment from 'moment';
import I18n from 'i18n-js';
import h from '../h';
import usersVM from './user-vm';
import models from '../models';
const I18nScope = _.partial(h.i18nScope, 'projects.contributions.edit.errors');

const paymentVM = (mode = 'aon') => {
    const pagarme = m.prop({}),
        submissionError = m.prop(false),
        isLoading = m.prop(false);

    const setCsrfToken = (xhr) => {
        if (h.authenticityToken()) {
            xhr.setRequestHeader('X-CSRF-Token', h.authenticityToken());
        }
        return;
    };

    const fields = {
        completeName: m.prop(''),
        email: m.prop(''),
        anonymous: m.prop(),
        countries: m.prop(),
        userCountryId: m.prop(),
        zipCode: m.prop(''),
        street: m.prop(''),
        number: m.prop(''),
        addressComplement: m.prop(''),
        neighbourhood: m.prop(''),
        city: m.prop(''),
        states: m.prop([]),
        userState: m.prop(),
        ownerDocument: m.prop(''),
        phone: m.prop(''),
        errors: m.prop([])
    };

    const creditCardFields = {
        name: m.prop(''),
        number: m.prop(''),
        expMonth: m.prop(''),
        expYear: m.prop(''),
        save: m.prop(false),
        cvv: m.prop(''),
        errors: m.prop([])
    };

    const faq = I18n.translations[I18n.currentLocale()].projects.faq[mode],
        currentUser = h.getUser(),
        countriesLoader = postgrest.loader(models.country.getPageOptions()),
        statesLoader = postgrest.loader(models.state.getPageOptions());

    const populateForm = (fetchedData) => {
        const data = _.first(fetchedData);

        fields.completeName(data.name);
        fields.email(data.email);
        fields.city(data.address.city);
        fields.zipCode(data.address.zipcode);
        fields.street(data.address.street);
        fields.number(data.address.number);
        fields.addressComplement(data.address.complement);
        fields.userState(data.address.state);
        fields.userCountryId(data.address.country_id);
        fields.ownerDocument(data.owner_document);
        fields.phone(data.address.phonenumber);
        fields.neighbourhood(data.address.neighbourhood);
    };

    const expMonthOptions = () => {
        return [
            [1, '01 - Janeiro'],
            [2, '02 - Fevereiro'],
            [3, '03 - Março'],
            [4, '04 - Abril'],
            [5, '05 - Maio'],
            [6, '06 - Junho'],
            [7, '07 - Julho'],
            [8, '08 - Agosto'],
            [9, '09 - Setembro'],
            [10, '10 - Outubro'],
            [11, '11 - Novembro'],
            [12, '12 - Dezembro']
        ];
    };

    const expYearOptions = () => {
        const currentYear = moment().year();
        let yearsOptions = [];
        for (let i = currentYear; i <= currentYear + 25; i++) {
            yearsOptions.push(i);
        }
        return yearsOptions;
    };

    const isInternational = () => {
        return !_.isEmpty(fields.countries()) ? fields.userCountryId() != _.findWhere(fields.countries(), {name: 'Brasil'}).id : false;
    };

    const checkEmptyFields = (checkedFields) => {
        return _.map(checkedFields, (field) => {
            if (_.isEmpty(String(fields[field]()).trim())) {
                fields.errors().push({field: field, message: 'O campo não pode ser vazio.'});
            }
        });
    };

    const checkEmail = () => {
        const isValid = h.validateEmail(fields.email());

        if (!isValid){
            fields.errors().push({field: 'email', message: 'E-mail inválido.'});
        }
    };

    const checkDocument = () => {
        //TODO: also validate Cnpj
        const isValid = h.validateCpf(fields.ownerDocument().replace(/[\.|\-]*/g,''));

        if (!isValid){
            fields.errors().push({field: 'ownerDocument', message: 'CPF inválido.'});
        }
    };

    const validate = () => {
        fields.errors([]);

        checkEmptyFields(['completeName', 'street', 'number', 'city']);

        checkEmail();

        if (!isInternational()){
            checkEmptyFields(['phone', 'neighbourhood']);
            checkDocument();
        }

        return _.isEmpty(fields.errors());
    };

    const getSlipPaymentDate = (contribution_id) => {
        const paymentDate = m.prop();

        m.request({
            method: 'GET',
            config: setCsrfToken,
            url: `/payment/pagarme/${contribution_id}/slip_data`
        }).then(paymentDate);

        return paymentDate;
    };

    const savedCreditCards = m.prop([]);

    const getSavedCreditCards = (user_id) => {
        const otherSample = {
            id: -1
        };

        return m.request({
            method: 'GET',
            config: setCsrfToken,
            url: `/users/${user_id}/credit_cards`
        }).then((creditCards) => {
            if (_.isArray(creditCards)){
                creditCards.push(otherSample);
            } else {
                creditCards = [];
            }

            return savedCreditCards(creditCards);
        });
    };

    const requestPayment = (data, contribution_id) => {
        return m.request({
            method: 'POST',
            url: `/payment/pagarme/${contribution_id}/pay_credit_card`,
            data: data,
            config: setCsrfToken
        });
    };

    const payWithSavedCard = (creditCard, installment, contribution_id) => {
        const data = {
            card_id: creditCard.card_key,
            payment_card_installments: installment
        };
        return requestPayment(data, contribution_id);
    };

    const setNewCreditCard = () => {
        let creditCard = new window.PagarMe.creditCard();
        creditCard.cardHolderName = creditCardFields.name();
        creditCard.cardExpirationMonth = creditCardFields.expMonth();
        creditCard.cardExpirationYear = creditCardFields.expYear();
        creditCard.cardNumber = creditCardFields.number();
        creditCard.cardCVV = creditCardFields.cvv();
        return creditCard;
    };

    const payWithNewCard = (contribution_id, installment) => {
        const deferred = m.deferred();
        m.request({
            method: 'GET',
            url: `/payment/pagarme/${contribution_id}/get_encryption_key`,
            config: setCsrfToken
        }).then((data) => {
            window.PagarMe.encryption_key = data.key;
            const card = setNewCreditCard();
            const errors = card.fieldErrors();
            if (_.keys(errors).length > 0) {
                deferred.reject({message: I18n.t('submission.card_invalid', I18nScope())});
            } else {
                card.generateHash((cardHash) => {
                    const data = {
                        card_hash: cardHash,
                        save_card: creditCardFields.save().toString(),
                        payment_card_installments: installment
                    };
                    requestPayment(data, contribution_id).then(deferred.resolve).catch(deferred.reject);
                });

            }
        }).catch((error) => {
            if(!_.isEmpty(error.message)){
                deferred.reject(error);
            } else {
                deferred.reject({message: I18n.t('submission.encryption_error', I18nScope())});
            }
        });

        return deferred.promise;
    };

    const updateContributionData = (contribution_id, project_id) => {
        const contributionData = {
            anonymous: fields.anonymous(),
            country_id: fields.userCountryId(),
            payer_name: fields.completeName(),
            payer_email: fields.email(),
            payer_document: fields.ownerDocument(),
            address_street: fields.street(),
            address_number: fields.number(),
            address_complement: fields.addressComplement(),
            address_neighbourhood: fields.neighbourhood(),
            address_zip_code: fields.zipCode(),
            address_city: fields.city(),
            address_state: fields.userState(),
            address_phone_number: fields.phone()
        };

        return m.request({
            method: 'PUT',
            url: `/projects/${project_id}/contributions/${contribution_id}.json`,
            data: {contribution: contributionData},
            config: setCsrfToken
        });
    };

    const creditCardPaymentSuccess = (deferred, project_id, contribution_id) => (data) => {
        if (data.payment_status === 'failed') {
            const errorMsg = data.message || I18n.t('submission.payment_failed', I18nScope());

            isLoading(false);
            submissionError(I18n.t('submission.error', I18nScope({message: errorMsg})));
            m.redraw();
            deferred.reject();
        } else {
            window.location.href = `/projects/${project_id}/contributions/${contribution_id}`;
        }
    };

    const creditCardPaymentFail = (deferred) => (data) => {
        isLoading(false);
        submissionError(I18n.t('submission.error', I18nScope({message: data.message})));
        m.redraw();
        deferred.reject();
    };

    const checkAndPayCreditCard = (deferred, selectedCreditCard, contribution_id, project_id, selectedInstallment) => () => {
        if (selectedCreditCard().id && selectedCreditCard().id !== -1) {
            return payWithSavedCard(selectedCreditCard(), selectedInstallment(), contribution_id)
                .then(creditCardPaymentSuccess(deferred, project_id, contribution_id))
                .catch(creditCardPaymentFail(deferred));
        } else {
            return payWithNewCard(contribution_id, selectedInstallment)
                .then(creditCardPaymentSuccess(deferred, project_id, contribution_id))
                .catch(creditCardPaymentFail(deferred));
        }
    };

    const sendPayment = (selectedCreditCard, selectedInstallment, contribution_id, project_id) => {
        const deferred = m.deferred();
        if (validate()) {
            isLoading(true);
            submissionError(false);
            m.redraw();
            updateContributionData(contribution_id, project_id)
                .then(checkAndPayCreditCard(deferred, selectedCreditCard, contribution_id, project_id, selectedInstallment))
                .catch(() => {
                    isLoading(false);
                    deferred.reject();
                });

        } else {
            isLoading(false);
            deferred.reject();
        }
        return deferred.promise;
    };

    const resetFieldError = (fieldName) => () => {
        const errors = fields.errors(),
            errorField = _.findWhere(fields.errors(), {field: fieldName}),
            newErrors = _.compose(fields.errors, _.without);

        return newErrors(fields.errors(), errorField);
    };

    const resetCreditCardFieldError = (fieldName) => () => {
        const errors = fields.errors(),
            errorField = _.findWhere(creditCardFields.errors(), {field: fieldName}),
            newErrors = _.compose(creditCardFields.errors, _.without);

        return newErrors(creditCardFields.errors(), errorField);
    };

    const installments = m.prop([{value: 10, number: 1}]);

    const getInstallments = (contribution_id) => {
        return m.request({
            method: 'GET',
            url: `/payment/pagarme/${contribution_id}/get_installment`,
            config: h.setCsrfToken
        }).then(installments);
    };

    const creditCardMask = _.partial(h.mask, '9999 9999 9999 9999');

    const applyCreditCardMask = _.compose(creditCardFields.number, creditCardMask);

    countriesLoader.load().then(fields.countries);
    statesLoader.load().then(fields.states);
    usersVM.fetchUser(currentUser.user_id, false).then(populateForm);

    return {
        fields: fields,
        validate: validate,
        isInternational: isInternational,
        resetFieldError: resetFieldError,
        getSlipPaymentDate: getSlipPaymentDate,
        installments: installments,
        getInstallments: getInstallments,
        savedCreditCards: savedCreditCards,
        getSavedCreditCards: getSavedCreditCards,
        applyCreditCardMask: applyCreditCardMask,
        creditCardFields: creditCardFields,
        resetCreditCardFieldError: resetCreditCardFieldError,
        expMonthOptions: expMonthOptions,
        expYearOptions: expYearOptions,
        sendPayment: sendPayment,
        submissionError: submissionError,
        isLoading: isLoading,
        pagarme: pagarme,
        faq: faq
    };
};

export default paymentVM;
<|endoftext|>


<commit_before>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

// @ts-check

const perf = require('../base/common/performance');
const performance = require('perf_hooks').performance;
const product = require('../../../product.json');
const readline = require('readline');
const http = require('http');

perf.mark('code/server/start');
// @ts-ignore
global.vscodeServerStartTime = performance.now();

async function start() {
	if (process.argv[2] === '--exec') {
		console.warn('--exec is deprecated and will be removed.');
		process.argv.splice(1, 2);
		require(process.argv[1]);
		return;
	}

	const minimist = require('minimist');

	// Do a quick parse to determine if a server or the cli needs to be started
	const parsedArgs = minimist(process.argv.slice(2), {
		boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms'],
		string: ['install-extension', 'install-builtin-extension', 'uninstall-extension', 'locate-extension', 'socket-path', 'host', 'port', 'pick-port']
	});

	const extensionCliArgs = ['list-extensions', 'install-extension', 'install-builtin-extension', 'uninstall-extension', 'locate-extension'];

	const shouldSpawnCli = parsedArgs.help || parsedArgs.version || !parsedArgs['start-server'] && extensionCliArgs.some(a => !!parsedArgs[a]);

	if (shouldSpawnCli) {
		loadCode().then((mod) => {
			mod.spawnCli();
		});
		return;
	}

	/**
	 * @typedef { import('./remoteExtensionHostAgentServer').IServerAPI } IServerAPI
	 */
	/** @type {IServerAPI | null} */
	let _remoteExtensionHostAgentServer = null;
	/** @type {Promise<IServerAPI> | null} */
	let _remoteExtensionHostAgentServerPromise = null;
	/** @returns {Promise<IServerAPI>} */
	const getRemoteExtensionHostAgentServer = () => {
		if (!_remoteExtensionHostAgentServerPromise) {
			_remoteExtensionHostAgentServerPromise = loadCode().then((mod) => mod.createServer(address));
		}
		return _remoteExtensionHostAgentServerPromise;
	};

	const http = require('http');
	const os = require('os');

	if (Array.isArray(product.serverLicense) && product.serverLicense.length) {
		console.log(product.serverLicense.join('\n'));
		if (product.serverLicensePrompt && parsedArgs['accept-server-license-terms'] !== true) {
			try {
				const accept = await prompt(product.serverLicensePrompt);
				if (!accept) {
					process.exit();
				}
			} catch (e) {
				console.log(e);
				process.exit();
			}
		}
	}

	let firstRequest = true;
	let firstWebSocket = true;

	/** @type {string | import('net').AddressInfo | null} */
	let address = null;
	const server = http.createServer(async (req, res) => {
		if (firstRequest) {
			firstRequest = false;
			perf.mark('code/server/firstRequest');
		}
		const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer();
		return remoteExtensionHostAgentServer.handleRequest(req, res);
	});
	server.on('upgrade', async (req, socket) => {
		if (firstWebSocket) {
			firstWebSocket = false;
			perf.mark('code/server/firstWebSocket');
		}
		const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer();
		// @ts-ignore
		return remoteExtensionHostAgentServer.handleUpgrade(req, socket);
	});
	server.on('error', async (err) => {
		const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer();
		return remoteExtensionHostAgentServer.handleServerError(err);
	});
	const nodeListenOptions = (
		parsedArgs['socket-path']
			? { path: parsedArgs['socket-path'] }
			: { host: parsedArgs['host'], port: await parsePort(parsedArgs['port'], parsedArgs['pick-port']) }
	);
	server.listen(nodeListenOptions, async () => {
		const serverGreeting = product.serverGreeting.join('\n');
		let output = serverGreeting ? `\n\n${serverGreeting}\n\n` : ``;

		if (typeof nodeListenOptions.port === 'number' && parsedArgs['print-ip-address']) {
			const ifaces = os.networkInterfaces();
			Object.keys(ifaces).forEach(function (ifname) {
				ifaces[ifname].forEach(function (iface) {
					if (!iface.internal && iface.family === 'IPv4') {
						output += `IP Address: ${iface.address}\n`;
					}
				});
			});
		}

		address = server.address();
		if (address === null) {
			throw new Error('Unexpected server address');
		}

		// Do not change this line. VS Code looks for this in the output.
		output += `Extension host agent listening on ${typeof address === 'string' ? address : address.port}\n`;
		console.log(output);

		perf.mark('code/server/started');
		// @ts-ignore
		global.vscodeServerListenTime = performance.now();

		await getRemoteExtensionHostAgentServer();
	});

	process.on('exit', () => {
		server.close();
		if (_remoteExtensionHostAgentServer) {
			_remoteExtensionHostAgentServer.dispose();
		}
	});
}

/**
 * If `--pick-port` and `--port` is specified, connect to that port.
 *
 * If not and a port range is specified through `--pick-port`
 * then find a free port in that range. Throw error if no
 * free port available in range.
 *
 * If only `--port` is provided then connect to that port.
 *
 * In absence of specified ports, connect to port 8000.
 * @param {string | undefined} strPort
 * @param {string | undefined} strPickPort
 * @returns {Promise<number>}
 * @throws
 */
async function parsePort(strPort, strPickPort) {
	let specificPort;
	if (strPort) {
		let range;
		if (strPort.match(/^\d+$/)) {
			specificPort = parseInt(strPort, 10);
			if (specificPort === 0 || !strPickPort) {
				return specificPort;
			}
		} else if (range = parseRange(strPort)) {
			const port = await findFreePort(range.start, range.end);
			if (port !== undefined) {
				return port;
			}
			console.warn(`--port: Could not find free port in range: ${range.start}-${range.end}.`);
			process.exit(1);

		} else {
			console.warn('--port "${strPort}" is not a valid number or range.');
			process.exit(1);
		}
	}
	if (strPickPort) {
		const range = parseRange(strPickPort);
		if (range) {
			if (range.start <= specificPort && specificPort <= range.end) {
				return specificPort;
			} else {
				const port = await findFreePort(range.start, range.end);
				if (port !== undefined) {
					return port;
				}
				console.log(`--pick-port: Could not find free port in range: ${range.start}-${range.end}.`);
				process.exit(1);
			}
		} else {
			console.log(`--pick-port "${strPickPort}" is not properly formatted.`);
			process.exit(1);
		}
	}
	return 8000;
}

/**
 * @param {string} strRange
 * @returns {{ start: number; end: number } | undefined}
 */
function parseRange(strRange) {
	const match = strRange.match(/^(\d+)-(\d+)$/);
	if (match) {
		return { start: parseInt(match[1], 10), end: parseInt(match[2], 10) };
	}
	return undefined;
}

/**
 * Starting at the `start` port, look for a free port incrementing
 * by 1 until `end` inclusive. If no free port is found, undefined is returned.
 *
 * @param {number} start
 * @param {number} end
 * @returns {Promise<number | undefined>}
 * @throws
 */
async function findFreePort(start, end) {
	const testPort = (port) => {
		return new Promise((resolve) => {
			const server = http.createServer();
			server.listen(port, '127.0.0.1', () => {
				server.close();
				resolve(true);
			}).on('error', () => {
				resolve(false);
			});
		});
	};
	for (let port = start; port < end; port++) {
		if (await testPort(port)) {
			return port;
		}
	}
	return undefined;
}

/** @returns { Promise<typeof import('./remoteExtensionHostAgent')> } */
function loadCode() {
	return new Promise((resolve, reject) => {
		const path = require('path');

		// Set default remote native node modules path, if unset
		process.env['VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH'] = process.env['VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH'] || path.join(__dirname, '..', '..', '..', 'remote', 'node_modules');
		require('../../bootstrap-node').injectNodeModuleLookupPath(process.env['VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH']);
		require('../../bootstrap-amd').load('vs/server/remoteExtensionHostAgent', resolve, reject);
	});
}

/**
 * @param {string} question
 * @returns { Promise<boolean> }
 */
function prompt(question) {
	const rl = readline.createInterface({
		input: process.stdin,
		output: process.stdout
	});
	return new Promise((resolve, reject) => {
		rl.question(question + ' ', async function (data) {
			rl.close();
			const str = data.toString().trim().toLowerCase();
			if (str === '' || str === 'y' || str === 'yes') {
				resolve(true);
			} else if (str === 'n' || str === 'no') {
				resolve(false);
			} else {
				process.stdout.write('\nInvalid Response. Answer either yes (y, yes) or no (n, no)\n');
				resolve(await prompt(question));
			}
		});
	});
}

start();
<commit_msg>server cli: refine start-server. For #137658<commit_after>/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

// @ts-check

const perf = require('../base/common/performance');
const performance = require('perf_hooks').performance;
const product = require('../../../product.json');
const readline = require('readline');
const http = require('http');

perf.mark('code/server/start');
// @ts-ignore
global.vscodeServerStartTime = performance.now();

async function start() {
	if (process.argv[2] === '--exec') {
		console.warn('--exec is deprecated and will be removed.');
		process.argv.splice(1, 2);
		require(process.argv[1]);
		return;
	}

	const minimist = require('minimist');

	// Do a quick parse to determine if a server or the cli needs to be started
	const parsedArgs = minimist(process.argv.slice(2), {
		boolean: ['start-server', 'list-extensions', 'print-ip-address', 'help', 'version', 'accept-server-license-terms'],
		string: ['install-extension', 'install-builtin-extension', 'uninstall-extension', 'locate-extension', 'socket-path', 'host', 'port', 'pick-port']
	});

	const extensionLookupArgs = ['list-extensions', 'locate-extension'];
	const extensionInstallArgs = ['install-extension', 'install-builtin-extension', 'uninstall-extension'];

	const shouldSpawnCli = parsedArgs.help || parsedArgs.version || extensionLookupArgs.some(a => !!parsedArgs[a]) || (extensionInstallArgs.some(a => !!parsedArgs[a]) && !parsedArgs['start-server']);

	if (shouldSpawnCli) {
		loadCode().then((mod) => {
			mod.spawnCli();
		});
		return;
	}

	/**
	 * @typedef { import('./remoteExtensionHostAgentServer').IServerAPI } IServerAPI
	 */
	/** @type {IServerAPI | null} */
	let _remoteExtensionHostAgentServer = null;
	/** @type {Promise<IServerAPI> | null} */
	let _remoteExtensionHostAgentServerPromise = null;
	/** @returns {Promise<IServerAPI>} */
	const getRemoteExtensionHostAgentServer = () => {
		if (!_remoteExtensionHostAgentServerPromise) {
			_remoteExtensionHostAgentServerPromise = loadCode().then((mod) => mod.createServer(address));
		}
		return _remoteExtensionHostAgentServerPromise;
	};

	const http = require('http');
	const os = require('os');

	if (Array.isArray(product.serverLicense) && product.serverLicense.length) {
		console.log(product.serverLicense.join('\n'));
		if (product.serverLicensePrompt && parsedArgs['accept-server-license-terms'] !== true) {
			try {
				const accept = await prompt(product.serverLicensePrompt);
				if (!accept) {
					process.exit();
				}
			} catch (e) {
				console.log(e);
				process.exit();
			}
		}
	}

	let firstRequest = true;
	let firstWebSocket = true;

	/** @type {string | import('net').AddressInfo | null} */
	let address = null;
	const server = http.createServer(async (req, res) => {
		if (firstRequest) {
			firstRequest = false;
			perf.mark('code/server/firstRequest');
		}
		const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer();
		return remoteExtensionHostAgentServer.handleRequest(req, res);
	});
	server.on('upgrade', async (req, socket) => {
		if (firstWebSocket) {
			firstWebSocket = false;
			perf.mark('code/server/firstWebSocket');
		}
		const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer();
		// @ts-ignore
		return remoteExtensionHostAgentServer.handleUpgrade(req, socket);
	});
	server.on('error', async (err) => {
		const remoteExtensionHostAgentServer = await getRemoteExtensionHostAgentServer();
		return remoteExtensionHostAgentServer.handleServerError(err);
	});
	const nodeListenOptions = (
		parsedArgs['socket-path']
			? { path: parsedArgs['socket-path'] }
			: { host: parsedArgs['host'], port: await parsePort(parsedArgs['port'], parsedArgs['pick-port']) }
	);
	server.listen(nodeListenOptions, async () => {
		const serverGreeting = product.serverGreeting.join('\n');
		let output = serverGreeting ? `\n\n${serverGreeting}\n\n` : ``;

		if (typeof nodeListenOptions.port === 'number' && parsedArgs['print-ip-address']) {
			const ifaces = os.networkInterfaces();
			Object.keys(ifaces).forEach(function (ifname) {
				ifaces[ifname].forEach(function (iface) {
					if (!iface.internal && iface.family === 'IPv4') {
						output += `IP Address: ${iface.address}\n`;
					}
				});
			});
		}

		address = server.address();
		if (address === null) {
			throw new Error('Unexpected server address');
		}

		// Do not change this line. VS Code looks for this in the output.
		output += `Extension host agent listening on ${typeof address === 'string' ? address : address.port}\n`;
		console.log(output);

		perf.mark('code/server/started');
		// @ts-ignore
		global.vscodeServerListenTime = performance.now();

		await getRemoteExtensionHostAgentServer();
	});

	process.on('exit', () => {
		server.close();
		if (_remoteExtensionHostAgentServer) {
			_remoteExtensionHostAgentServer.dispose();
		}
	});
}

/**
 * If `--pick-port` and `--port` is specified, connect to that port.
 *
 * If not and a port range is specified through `--pick-port`
 * then find a free port in that range. Throw error if no
 * free port available in range.
 *
 * If only `--port` is provided then connect to that port.
 *
 * In absence of specified ports, connect to port 8000.
 * @param {string | undefined} strPort
 * @param {string | undefined} strPickPort
 * @returns {Promise<number>}
 * @throws
 */
async function parsePort(strPort, strPickPort) {
	let specificPort;
	if (strPort) {
		let range;
		if (strPort.match(/^\d+$/)) {
			specificPort = parseInt(strPort, 10);
			if (specificPort === 0 || !strPickPort) {
				return specificPort;
			}
		} else if (range = parseRange(strPort)) {
			const port = await findFreePort(range.start, range.end);
			if (port !== undefined) {
				return port;
			}
			console.warn(`--port: Could not find free port in range: ${range.start}-${range.end}.`);
			process.exit(1);

		} else {
			console.warn('--port "${strPort}" is not a valid number or range.');
			process.exit(1);
		}
	}
	if (strPickPort) {
		const range = parseRange(strPickPort);
		if (range) {
			if (range.start <= specificPort && specificPort <= range.end) {
				return specificPort;
			} else {
				const port = await findFreePort(range.start, range.end);
				if (port !== undefined) {
					return port;
				}
				console.log(`--pick-port: Could not find free port in range: ${range.start}-${range.end}.`);
				process.exit(1);
			}
		} else {
			console.log(`--pick-port "${strPickPort}" is not properly formatted.`);
			process.exit(1);
		}
	}
	return 8000;
}

/**
 * @param {string} strRange
 * @returns {{ start: number; end: number } | undefined}
 */
function parseRange(strRange) {
	const match = strRange.match(/^(\d+)-(\d+)$/);
	if (match) {
		return { start: parseInt(match[1], 10), end: parseInt(match[2], 10) };
	}
	return undefined;
}

/**
 * Starting at the `start` port, look for a free port incrementing
 * by 1 until `end` inclusive. If no free port is found, undefined is returned.
 *
 * @param {number} start
 * @param {number} end
 * @returns {Promise<number | undefined>}
 * @throws
 */
async function findFreePort(start, end) {
	const testPort = (port) => {
		return new Promise((resolve) => {
			const server = http.createServer();
			server.listen(port, '127.0.0.1', () => {
				server.close();
				resolve(true);
			}).on('error', () => {
				resolve(false);
			});
		});
	};
	for (let port = start; port < end; port++) {
		if (await testPort(port)) {
			return port;
		}
	}
	return undefined;
}

/** @returns { Promise<typeof import('./remoteExtensionHostAgent')> } */
function loadCode() {
	return new Promise((resolve, reject) => {
		const path = require('path');

		// Set default remote native node modules path, if unset
		process.env['VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH'] = process.env['VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH'] || path.join(__dirname, '..', '..', '..', 'remote', 'node_modules');
		require('../../bootstrap-node').injectNodeModuleLookupPath(process.env['VSCODE_INJECT_NODE_MODULE_LOOKUP_PATH']);
		require('../../bootstrap-amd').load('vs/server/remoteExtensionHostAgent', resolve, reject);
	});
}

/**
 * @param {string} question
 * @returns { Promise<boolean> }
 */
function prompt(question) {
	const rl = readline.createInterface({
		input: process.stdin,
		output: process.stdout
	});
	return new Promise((resolve, reject) => {
		rl.question(question + ' ', async function (data) {
			rl.close();
			const str = data.toString().trim().toLowerCase();
			if (str === '' || str === 'y' || str === 'yes') {
				resolve(true);
			} else if (str === 'n' || str === 'no') {
				resolve(false);
			} else {
				process.stdout.write('\nInvalid Response. Answer either yes (y, yes) or no (n, no)\n');
				resolve(await prompt(question));
			}
		});
	});
}

start();
<|endoftext|>


<commit_before>/* @flow strict-local */
import React, { PureComponent } from 'react';
import { ScrollView, Keyboard } from 'react-native';
import type { NavigationScreenProp } from 'react-navigation';

import type { ApiResponseServerSettings, Dispatch } from '../types';
import { connect } from '../react-redux';
import { ErrorMsg, Label, SmartUrlInput, Screen, ZulipButton } from '../common';
import { isValidUrl } from '../utils/url';
import * as api from '../api';
import { realmAdd, navigateToAuth } from '../actions';
import styles from '../styles';

type Props = $ReadOnly<{|
  dispatch: Dispatch,
  navigation: NavigationScreenProp<{
    params: ?{|
      realm: string | void,
      initial?: boolean,
    |},
  }>,
  initialRealm: string,
|}>;

type State = {|
  realm: string,
  error: string | null,
  progress: boolean,
|};

class RealmScreen extends PureComponent<Props, State> {
  state = {
    progress: false,
    realm: this.props.initialRealm,
    error: null,
  };

  scrollView: ScrollView;

  tryRealm = async () => {
    const { realm } = this.state;

    this.setState({
      realm,
      progress: true,
      error: null,
    });

    const { dispatch } = this.props;

    try {
      const serverSettings: ApiResponseServerSettings = await api.getServerSettings(realm);
      dispatch(realmAdd(realm));
      dispatch(navigateToAuth(serverSettings));
      Keyboard.dismiss();
    } catch (err) {
      this.setState({ error: 'Cannot connect to server' });
      /* eslint-disable no-console */
      console.warn('RealmScreen: failed to connect to server:', err);
      console.warn(err.stack);
    } finally {
      this.setState({ progress: false });
    }
  };

  handleRealmChange = (value: string) => this.setState({ realm: value });

  componentDidMount() {
    const { initialRealm } = this.props;
    if (initialRealm && initialRealm.length > 0) {
      this.tryRealm();
    }
  }

  render() {
    const { initialRealm, navigation } = this.props;
    const { progress, error, realm } = this.state;

    return (
      <Screen
        title="Welcome"
        canGoBack={!this.props.navigation.state.params?.initial}
        padding
        centerContent
        keyboardShouldPersistTaps="always"
      >
        <Label text="Enter your Zulip server URL:" />
        <SmartUrlInput
          style={styles.marginVertical}
          navigation={navigation}
          defaultProtocol="https://"
          defaultOrganization="your-org"
          defaultDomain="zulipchat.com"
          defaultValue={initialRealm}
          onChangeText={this.handleRealmChange}
          onSubmitEditing={this.tryRealm}
          enablesReturnKeyAutomatically
        />
        {error !== null && <ErrorMsg error={error} />}
        <ZulipButton
          style={styles.halfMarginTop}
          text="Enter"
          progress={progress}
          onPress={this.tryRealm}
          disabled={!isValidUrl(realm)}
        />
      </Screen>
    );
  }
}

export default connect((state, props) => ({
  initialRealm: props.navigation.state.params?.realm ?? '',
}))(RealmScreen);
<commit_msg>realm screen [nfc]: Refactor styles for editability.<commit_after>/* @flow strict-local */
import React, { PureComponent } from 'react';
import { ScrollView, Keyboard } from 'react-native';
import type { NavigationScreenProp } from 'react-navigation';

import type { ApiResponseServerSettings, Dispatch } from '../types';
import { connect } from '../react-redux';
import { ErrorMsg, Label, SmartUrlInput, Screen, ZulipButton } from '../common';
import { isValidUrl } from '../utils/url';
import * as api from '../api';
import { realmAdd, navigateToAuth } from '../actions';

type Props = $ReadOnly<{|
  dispatch: Dispatch,
  navigation: NavigationScreenProp<{
    params: ?{|
      realm: string | void,
      initial?: boolean,
    |},
  }>,
  initialRealm: string,
|}>;

type State = {|
  realm: string,
  error: string | null,
  progress: boolean,
|};

class RealmScreen extends PureComponent<Props, State> {
  state = {
    progress: false,
    realm: this.props.initialRealm,
    error: null,
  };

  scrollView: ScrollView;

  tryRealm = async () => {
    const { realm } = this.state;

    this.setState({
      realm,
      progress: true,
      error: null,
    });

    const { dispatch } = this.props;

    try {
      const serverSettings: ApiResponseServerSettings = await api.getServerSettings(realm);
      dispatch(realmAdd(realm));
      dispatch(navigateToAuth(serverSettings));
      Keyboard.dismiss();
    } catch (err) {
      this.setState({ error: 'Cannot connect to server' });
      /* eslint-disable no-console */
      console.warn('RealmScreen: failed to connect to server:', err);
      console.warn(err.stack);
    } finally {
      this.setState({ progress: false });
    }
  };

  handleRealmChange = (value: string) => this.setState({ realm: value });

  componentDidMount() {
    const { initialRealm } = this.props;
    if (initialRealm && initialRealm.length > 0) {
      this.tryRealm();
    }
  }

  render() {
    const { initialRealm, navigation } = this.props;
    const { progress, error, realm } = this.state;

    const styles = {
      input: { marginVertical: 16 },
      button: { marginTop: 8 },
    };

    return (
      <Screen
        title="Welcome"
        canGoBack={!this.props.navigation.state.params?.initial}
        padding
        centerContent
        keyboardShouldPersistTaps="always"
      >
        <Label text="Enter your Zulip server URL:" />
        <SmartUrlInput
          style={styles.input}
          navigation={navigation}
          defaultProtocol="https://"
          defaultOrganization="your-org"
          defaultDomain="zulipchat.com"
          defaultValue={initialRealm}
          onChangeText={this.handleRealmChange}
          onSubmitEditing={this.tryRealm}
          enablesReturnKeyAutomatically
        />
        {error !== null && <ErrorMsg error={error} />}
        <ZulipButton
          style={styles.button}
          text="Enter"
          progress={progress}
          onPress={this.tryRealm}
          disabled={!isValidUrl(realm)}
        />
      </Screen>
    );
  }
}

export default connect((state, props) => ({
  initialRealm: props.navigation.state.params?.realm ?? '',
}))(RealmScreen);
<|endoftext|>


<commit_before>const React = require('react');
const Reflux = require('reflux');
const Actions = require('../actions/Actions');
const haversine = require('haversine');
const _ = require('underscore');

var shops = require('../fixtures/ShopsFixtures');

var mapCenter = {
    'latitude': -33.4367715,
    'longitude': -70.6276278
}

const ShopsStore = Reflux.createStore({
    listenables: [Actions],
    onSelectedShop(id){
        console.log('Actions: on selected shop')
        var selectedShop = _.find(shops, function(shop){ return shop.id == id });
        this.trigger({selectedShop});
    },
    onAcceptedGeolocation(data){
        mapCenter.latitude = data.lat;
        mapCenter.longitude = data.lng;

        this.trigger({
            me: {
                lat: data.lat,
                lng: data.lng
            },
            shops: this.updateShopsByDistance()
        });
    },
    updateShopsByDistance(){
        return _.sortBy(shops, function(shop){
            shop.distance = haversine(mapCenter, {
                'latitude': shop.lat,
                'longitude': shop.lng
            }, {unit: 'm'});

            return shop.distance;
        }.bind(this));
    },
    getInitialState(){
        return {shops: this.updateShopsByDistance(), selectedShop: {}}
    }
});

export default ShopsStore;
<commit_msg>removed console.log<commit_after>const React = require('react');
const Reflux = require('reflux');
const Actions = require('../actions/Actions');
const haversine = require('haversine');
const _ = require('underscore');

var shops = require('../fixtures/ShopsFixtures');

var mapCenter = {
    'latitude': -33.4367715,
    'longitude': -70.6276278
}

const ShopsStore = Reflux.createStore({
    listenables: [Actions],
    onSelectedShop(id){
        var selectedShop = _.find(shops, function(shop){ return shop.id == id });
        this.trigger({selectedShop});
    },
    onAcceptedGeolocation(data){
        mapCenter.latitude = data.lat;
        mapCenter.longitude = data.lng;

        this.trigger({
            me: {
                lat: data.lat,
                lng: data.lng
            },
            shops: this.updateShopsByDistance()
        });
    },
    updateShopsByDistance(){
        return _.sortBy(shops, function(shop){
            shop.distance = haversine(mapCenter, {
                'latitude': shop.lat,
                'longitude': shop.lng
            }, {unit: 'm'});

            return shop.distance;
        }.bind(this));
    },
    getInitialState(){
        return {shops: this.updateShopsByDistance(), selectedShop: {}}
    }
});

export default ShopsStore;
<|endoftext|>


<commit_before>"use strict";

var NowPlayingConstants = require("../constants/NowPlayingConstants.js");
var NowPlayingActions = require("../actions/NowPlayingActions.js");
var NowPlayingStore = require("../stores/NowPlayingStore.js");

var PlayingStatusStore = require("../stores/PlayingStatusStore.js");

var VolumeStore = require("../stores/VolumeStore.js");

var _audio = new Audio();
var _src = null;
var _playing = false;

function buffered() {
  return _audio.buffered;
}

function play() {
  _audio.play();
}

function pause() {
  _audio.pause();
}

function load() {
  _audio.load();
}

function src() {
  return _src;
}

function setSrc(l) {
  _audio.src = l;
  _src = l;
}

function setCurrentTime(t) {
  _audio.currentTime = t;
}

function currentTime() {
  return _audio.currentTime;
}

function setVolume(t) {
  _audio.volume = t;
}

function volume() {
  return _audio.volume;
}

function duration() {
  return _audio.duration;
}

function onPlayerEvent(evt) {
  switch (evt.type) {
  case "error":
    NowPlayingActions.setError(evt.srcElement.error);
    console.log("Error received from Audio component:");
    console.error(evt);
    break;

  case "progress":
    var range = buffered();
    if (range.length > 0) {
      NowPlayingActions.setBuffered(range.end(range.length - 1));
    }
    break;

  case "play":
    NowPlayingActions.playing(true);
    break;

  case "pause":
    NowPlayingActions.playing(false);
    break;

  case "ended":
    NowPlayingActions.ended(NowPlayingStore.getSource(), NowPlayingStore.getRepeat());
    break;

  case "timeupdate":
    NowPlayingActions.currentTime(currentTime());
    break;

  case "loadedmetadata":
    NowPlayingActions.setDuration(duration());

    setCurrentTime(PlayingStatusStore.getTime());
    if (_playing) {
      play();
    }
    break;

  case "loadstart":
    NowPlayingActions.reset();
    break;

  default:
    console.warn("unhandled player event:");
    console.warn(evt);
    break;
  }
}

function _onNowPlayingControl(type, value) {
  if (type === NowPlayingConstants.SET_CURRENT_TIME) {
    setCurrentTime(value);
  }
}

function update() {
  var track = NowPlayingStore.getTrack();
  if (track) {
    var source = `/track/${track.ID}`;
    var orig = src();
    if (orig !== source) {
      setSrc(source);
      load();
      play();
    }
  }

  var prevPlaying = _playing;
  _playing = NowPlayingStore.getPlaying();
  if (prevPlaying !== _playing) {
    if (_playing) {
      play();
    } else {
      pause();
    }
  }
}

function _onVolumeChange() {
  var v = VolumeStore.getVolume();
  if (volume() !== v) {
    setVolume(v);
  }
}

function init() {
  _audio.addEventListener("error", onPlayerEvent);
  _audio.addEventListener("progress", onPlayerEvent);
  _audio.addEventListener("play", onPlayerEvent);
  _audio.addEventListener("pause", onPlayerEvent);
  _audio.addEventListener("ended", onPlayerEvent);
  _audio.addEventListener("timeupdate", onPlayerEvent);
  _audio.addEventListener("loadedmetadata", onPlayerEvent);
  _audio.addEventListener("loadstart", onPlayerEvent);

  NowPlayingStore.addChangeListener(update);
  NowPlayingStore.addControlListener(_onNowPlayingControl);
  VolumeStore.addChangeListener(_onVolumeChange);

  update();
  _onVolumeChange();
}

var AudioAPI = {

  init: function() {
    init();
  },

};

module.exports = AudioAPI;
<commit_msg>Refactored AudioAPI into ES6 class.<commit_after>"use strict";

var NowPlayingConstants = require("../constants/NowPlayingConstants.js");
var NowPlayingActions = require("../actions/NowPlayingActions.js");
var NowPlayingStore = require("../stores/NowPlayingStore.js");

var PlayingStatusStore = require("../stores/PlayingStatusStore.js");

var VolumeStore = require("../stores/VolumeStore.js");

class AudioAPI {
  constructor() {
    this._audio = new Audio();
    this._src = null;
    this._playing = false;

    this.onPlayerEvent = this.onPlayerEvent.bind(this);

    this._audio.addEventListener("error", this.onPlayerEvent);
    this._audio.addEventListener("progress", this.onPlayerEvent);
    this._audio.addEventListener("play", this.onPlayerEvent);
    this._audio.addEventListener("pause", this.onPlayerEvent);
    this._audio.addEventListener("ended", this.onPlayerEvent);
    this._audio.addEventListener("timeupdate", this.onPlayerEvent);
    this._audio.addEventListener("loadedmetadata", this.onPlayerEvent);
    this._audio.addEventListener("loadstart", this.onPlayerEvent);

    this.update = this.update.bind(this);
    this._onNowPlayingControl = this._onNowPlayingControl.bind(this);
    this._onVolumeChange = this._onVolumeChange.bind(this);

    NowPlayingStore.addChangeListener(this.update);
    NowPlayingStore.addControlListener(this._onNowPlayingControl);
    VolumeStore.addChangeListener(this._onVolumeChange);
  }

  init() {
    this.update();
    this._onVolumeChange();
  }

  buffered() {
    return this._audio.buffered;
  }

  play() {
    return this._audio.play();
  }

  pause() {
    return this._audio.pause();
  }

  load() {
    return this._audio.load();
  }

  src() {
    return this._src;
  }

  setSrc(src) {
    this._audio.src = src;
    this._src = src;
  }

  setCurrentTime(t) {
    this._audio.currentTime = t;
  }

  currentTime() {
    return this._audio.currentTime;
  }

  setVolume(v) {
    this._audio.volume = v;
  }

  volume() {
    return this._audio.volume;
  }

  duration() {
    return this._audio.duration;
  }

  onPlayerEvent(evt) {
    switch (evt.type) {
    case "error":
      NowPlayingActions.setError(evt.srcElement.error);
      console.log("Error received from Audio component:");
      console.error(evt);
      break;

    case "progress":
      var range = this.buffered();
      if (range.length > 0) {
        NowPlayingActions.setBuffered(range.end(range.length - 1));
      }
      break;

    case "play":
      NowPlayingActions.playing(true);
      break;

    case "pause":
      NowPlayingActions.playing(false);
      break;

    case "ended":
      NowPlayingActions.ended(NowPlayingStore.getSource(), NowPlayingStore.getRepeat());
      break;

    case "timeupdate":
      NowPlayingActions.currentTime(this.currentTime());
      break;

    case "loadedmetadata":
      NowPlayingActions.setDuration(this.duration());

      this.setCurrentTime(PlayingStatusStore.getTime());
      if (this._playing) {
        this.play();
      }
      break;

    case "loadstart":
      NowPlayingActions.reset();
      break;

    default:
      console.warn("unhandled player event:");
      console.warn(evt);
      break;
    }
  }

  _onNowPlayingControl(type, value) {
    if (type === NowPlayingConstants.SET_CURRENT_TIME) {
      this.setCurrentTime(value);
    }
  }

  update() {
    var track = NowPlayingStore.getTrack();
    if (track) {
      var source = `/track/${track.ID}`;
      var orig = this.src();
      if (orig !== source) {
        this.setSrc(source);
        this.load();
        this.play();
      }
    }

    var prevPlaying = this._playing;
    this._playing = NowPlayingStore.getPlaying();
    if (prevPlaying !== this._playing) {
      if (this._playing) {
        this.play();
      } else {
        this.pause();
      }
    }
  }

  _onVolumeChange() {
    var v = VolumeStore.getVolume();
    if (this.volume() !== v) {
      this.setVolume(v);
    }
  }
}

export default new AudioAPI();
<|endoftext|>


<commit_before>'use strict';

let cache = {
  roles: [],
  permissions: []
};

/**
 * Gelert.
 * Permissions done simply.
 *
 * @author Kieron Wiltshire <kieron@concept-gaming.com>
 */
export default class MemoryStorageStrategy {

  /**
   * Retrieve all of the permission roles.
   *
   * @returns {Array}
   */
  async getRoles() {
    return Promise.resolve(cache.roles);
  }

  /**
   * Retrieve a role by it's identifier.
   *
   * @param {string|number} id
   * @returns {Role}
   */
  async getRoleById(id) {
    let role = null;
    for (let i = 0; i < cache.roles.length; i++) {
      if (cache.roles[i].id === id) {
        role = cache.roles[i];
        break;
      }
    }
    return Promise.resolve(role);
  }

  /**
   * Retrieve a role by it's name.
   *
   * @param {string} name
   * @returns {Role}
   */
  async getRoleByName(name) {
    let role = null;
    for (let i = 0; i < cache.roles.length; i++) {
      if (cache.roles[i].name === name) {
        role = cache.roles[i];
        break;
      }
    }
    return Promise.resolve(role);
  }

  /**
   * Save the role.
   *
   * @returns {boolean} true if the role was saved successfully
   */
  async saveRole(role) {
    for (let i = 0; i < cache.roles.length; i++) {
      if (cache.roles[i].equals(role)) {
        cache.roles.splice(i, 1);
        break;
      }
    }
    cache.roles.push(role);
    return Promise.resolve();
  }

  /**
   * Delete the role.
   *
   * @returns {boolean} true if the permission was saved successfully
   */
  async deleteRole(role) {
    for (let i = 0; i < cache.roles.length; i++) {
      if (cache.roles[i] === role) {
        cache.roles.splice(i, 1);
        break;
      }
    }
    return Promise.resolve();
  }

  /**
   * Retrieve all of the permissions.
   *
   * @returns {Array}
   */
  async getPermissions() {
    return Promise.resolve(cache.permissions);
  }

  /**
   * Retrieve a permission by it's identifier.
   *
   * @param {string|number} id
   * @returns {Role}
   */
  async getPermissionById(id) {
    let permission = null;
    for (let i = 0; i < cache.permissions.length; i++) {
      if (cache.permissions[i].id === id) {
        permission = cache.permissions[i];
        break;
      }
    }
    return Promise.resolve(permission);
  }

  /**
   * Retrieve a permission by it's name.
   *
   * @param {string} name
   * @returns {Role}
   */
  async getPermissionByName(name) {
    let permission = null;
    for (let i = 0; i < cache.permissions.length; i++) {
      if (cache.permissions[i].name == name) {
        permission = cache.permissions[i];
        break;
      }
    }
    return Promise.resolve(permission);
  }

  /**
   * Save the permission.
   *
   * @returns {boolean} true if the permission was saved successfully
   */
  async savePermission(permission) {
    for (let i = 0; i < cache.permissions.length; i++) {
      if (cache.permissions[i].equals(permission)) {
        cache.permissions.splice(i, 1);
        break;
      }
    }
    cache.permissions.push(permission);
    return Promise.resolve();
  }

  /**
   * Delete the permission.
   *
   * @returns {boolean} true if the permission was saved successfully
   */
  async deletePermission(permission) {
    for (let i = 0; i < cache.permissions.length; i++) {
      if (cache.permissions[i].equals(permission)) {
        cache.permissions.splice(i, 1);
        break;
      }
    }
    return Promise.resolve();
  }

}
<commit_msg>Update memory.js<commit_after>'use strict';

let cache = {
  roles: [],
  permissions: []
};

/**
 * Gelert.
 * Permissions done simply.
 *
 * @author Kieron Wiltshire <kieron.wiltshire@outlook.com>
 */
export default class MemoryStorageStrategy {

  /**
   * Retrieve all of the permission roles.
   *
   * @returns {Array}
   */
  async getRoles() {
    return Promise.resolve(cache.roles);
  }

  /**
   * Retrieve a role by it's identifier.
   *
   * @param {string|number} id
   * @returns {Role}
   */
  async getRoleById(id) {
    let role = null;
    for (let i = 0; i < cache.roles.length; i++) {
      if (cache.roles[i].id === id) {
        role = cache.roles[i];
        break;
      }
    }
    return Promise.resolve(role);
  }

  /**
   * Retrieve a role by it's name.
   *
   * @param {string} name
   * @returns {Role}
   */
  async getRoleByName(name) {
    let role = null;
    for (let i = 0; i < cache.roles.length; i++) {
      if (cache.roles[i].name === name) {
        role = cache.roles[i];
        break;
      }
    }
    return Promise.resolve(role);
  }

  /**
   * Save the role.
   *
   * @returns {boolean} true if the role was saved successfully
   */
  async saveRole(role) {
    for (let i = 0; i < cache.roles.length; i++) {
      if (cache.roles[i].equals(role)) {
        cache.roles.splice(i, 1);
        break;
      }
    }
    cache.roles.push(role);
    return Promise.resolve();
  }

  /**
   * Delete the role.
   *
   * @returns {boolean} true if the permission was saved successfully
   */
  async deleteRole(role) {
    for (let i = 0; i < cache.roles.length; i++) {
      if (cache.roles[i] === role) {
        cache.roles.splice(i, 1);
        break;
      }
    }
    return Promise.resolve();
  }

  /**
   * Retrieve all of the permissions.
   *
   * @returns {Array}
   */
  async getPermissions() {
    return Promise.resolve(cache.permissions);
  }

  /**
   * Retrieve a permission by it's identifier.
   *
   * @param {string|number} id
   * @returns {Role}
   */
  async getPermissionById(id) {
    let permission = null;
    for (let i = 0; i < cache.permissions.length; i++) {
      if (cache.permissions[i].id === id) {
        permission = cache.permissions[i];
        break;
      }
    }
    return Promise.resolve(permission);
  }

  /**
   * Retrieve a permission by it's name.
   *
   * @param {string} name
   * @returns {Role}
   */
  async getPermissionByName(name) {
    let permission = null;
    for (let i = 0; i < cache.permissions.length; i++) {
      if (cache.permissions[i].name == name) {
        permission = cache.permissions[i];
        break;
      }
    }
    return Promise.resolve(permission);
  }

  /**
   * Save the permission.
   *
   * @returns {boolean} true if the permission was saved successfully
   */
  async savePermission(permission) {
    for (let i = 0; i < cache.permissions.length; i++) {
      if (cache.permissions[i].equals(permission)) {
        cache.permissions.splice(i, 1);
        break;
      }
    }
    cache.permissions.push(permission);
    return Promise.resolve();
  }

  /**
   * Delete the permission.
   *
   * @returns {boolean} true if the permission was saved successfully
   */
  async deletePermission(permission) {
    for (let i = 0; i < cache.permissions.length; i++) {
      if (cache.permissions[i].equals(permission)) {
        cache.permissions.splice(i, 1);
        break;
      }
    }
    return Promise.resolve();
  }

}
<|endoftext|>