<commit_before>$(document).ready(function(){
  console.log("what?")

  $("#signup_button").on("click", function(e){
      e.preventDefault();
      console.log("poop")

    $.ajax({
      url: $("#signup_link").attr("href"),
      method: $("#signup_link").attr("method"),
      success: function(response){
        var signup_form = $(response).find("#sign_up_form");
           $("#opening_forms").html(signup_form[0])
      }
    })
  });

  $("#login_button").on("click", function(e){
      e.preventDefault();

      $.ajax({
        url: $("#login_link").attr("href"),
        method: $("#login_link").attr("method"),
        success: function(response){
          var login_form = $(response).find("#login_form");
            $("#opening_forms").html(login_form[0])
        }

      })
  });

});<commit_msg>Update welcome_page.js<commit_after>$(document).ready(function(){
  console.log("what?")

  $("#signup_button").on("click", function(e){
      e.preventDefault();
      console.log("ding")

    $.ajax({
      url: $("#signup_link").attr("href"),
      method: $("#signup_link").attr("method"),
      success: function(response){
        var signup_form = $(response).find("#sign_up_form");
           $("#opening_forms").html(signup_form[0])
      }
    })
  });

  $("#login_button").on("click", function(e){
      e.preventDefault();

      $.ajax({
        url: $("#login_link").attr("href"),
        method: $("#login_link").attr("method"),
        success: function(response){
          var login_form = $(response).find("#login_form");
            $("#opening_forms").html(login_form[0])
        }

      })
  });

});
<|endoftext|>


<commit_before>import domready from './domready'
import { EventEmitter } from 'events'
import {forEach} from 'lodash'
import getTransitionEndEvent from '../helpers/transitionend'

const transitionendEvent = getTransitionEndEvent()

class HouseholdMember extends EventEmitter {
  constructor(index) {
    super()
    this.index = index
  }

  bindToExisting(node) {
    this.node = node
    this.removeBtn = this.node.querySelector('.js-btn-remove')
    this.bindToDOM()
  }

  bindToDOM() {
    this.indexNodes = this.node.querySelectorAll('.js-household-loopindex')
    this.inputs = this.node.querySelectorAll('input')
    this.actionNode = this.node.querySelector('.js-household-action')
    if (this.removeBtn) {
      this.removeBtn.addEventListener('click', this.onRemoveClick)
    }
  }

  add(node, parent) {
    this.node = node
    this.removeBtn = document.createElement('button')
    this.bindToDOM(node)
    this.removeTxt = this.node.getAttribute('data-remove')
    this.removeBtn.innerHTML = this.removeTxt
    this.removeBtn.classList.add('btn')
    this.removeBtn.classList.add('btn--link')
    this.removeBtn.classList.add('pluto')
    this.removeBtn.setAttribute('type', 'button')
    this.node.classList.add('is-hidden')
    this.actionNode.innerHTML = ''
    this.actionNode.appendChild(this.removeBtn)

    const errorNode = this.node.querySelector('.js-has-errors')

    if (errorNode) {
      const fieldNodes = this.node.querySelector('.js-fields')
      if (fieldNodes) {
        const clone = fieldNodes.cloneNode(true)
        errorNode.innerHTML = ''
        errorNode.classList.remove('js-has-errors')
        errorNode.appendChild(clone)
      }
    }

    parent.appendChild(this.node)
    this.node.querySelector('input').focus()
    this.setIndex(this.index)
    forEach(this.inputs, input => { input.value = '' })
    window.setTimeout(this.node.classList.remove('is-hidden'), 100)
  }

  setIndex(index) {
    this.index = index
    forEach(this.indexNodes, node => { node.innerHTML = index })
    forEach(this.inputs, input => {
      const id = input.id
      const label = this.node.querySelector(`label[for=${id}]`)
      const newId = `${id}_${index - 1}`
      input.setAttribute('id', newId)
      label.setAttribute('for', newId)
      input.setAttribute('name', `${input.name.replace(/\d+/, index - 1)}`)
    })
  }

  remove() {
    if (transitionendEvent) {
      this.node.addEventListener(transitionendEvent, this.onTransitionHideEnd, true)
    } else {
      window.setTimeout(this.onTransitionHideEnd, 500)
    }
    this.node.classList.add('is-removed')
  }

  onTransitionHideEnd = (e) => {
    if (e === undefined || e.target.classList.contains('is-removed')) {
      this.node.parentNode.removeChild(this.node)
      this.node.removeEventListener(transitionendEvent, this.onTransitionHideEnd)
      this.emit('removed', this)
    }
  }

  onRemoveClick = (e) => {
    e.preventDefault()
    this.remove()
  }
}

domready(() => {
  const existingPeople = document.querySelectorAll('.js-household-person')
  const btn = document.querySelector('.js-household-btn')
  const householdMembers = []

  if (existingPeople.length === 0) {
    return
  }

  const createHouseholdMember = () => {
    const householdMember = new HouseholdMember(householdMembers.length + 2)
    householdMember.addListener('removed', onRemove)
    householdMembers.push(householdMember)
    return householdMember
  }

  const onRemove = (removedMember) => {
    householdMembers.splice(householdMembers.indexOf(removedMember), 1)
    removedMember.removeListener('removed', onRemove)
    householdMembers.map((member, index) => {
      member.setIndex(index + 2)
    })
  }

  const onAddBtnClick = (e) => {
    e.preventDefault()
    const originalNode = existingPeople[0]
    const newNode = originalNode.cloneNode(true)
    const parent = originalNode.parentNode
    createHouseholdMember().add(newNode, parent)
  }

  forEach(existingPeople, (person, index) => {
    if (index > 0) {
      createHouseholdMember().bindToExisting(person)
    }
  })

  btn.setAttribute('type', 'button')
  btn.addEventListener('click', onAddBtnClick)
})
<commit_msg>fixed bug with dissappearing first name field<commit_after>import domready from './domready'
import { EventEmitter } from 'events'
import {forEach} from 'lodash'
import getTransitionEndEvent from '../helpers/transitionend'

const transitionendEvent = getTransitionEndEvent()

class HouseholdMember extends EventEmitter {
  constructor(index) {
    super()
    this.index = index
  }

  bindToExisting(node) {
    this.node = node
    this.removeBtn = this.node.querySelector('.js-btn-remove')
    this.bindToDOM()
  }

  bindToDOM() {
    this.indexNodes = this.node.querySelectorAll('.js-household-loopindex')
    this.inputs = this.node.querySelectorAll('input')
    this.actionNode = this.node.querySelector('.js-household-action')
    if (this.removeBtn) {
      this.removeBtn.addEventListener('click', this.onRemoveClick)
    }
  }

  add(node, parent) {
    this.node = node
    this.removeBtn = document.createElement('button')
    this.bindToDOM(node)
    this.removeTxt = this.node.getAttribute('data-remove')
    this.removeBtn.innerHTML = this.removeTxt
    this.removeBtn.classList.add('btn')
    this.removeBtn.classList.add('btn--link')
    this.removeBtn.classList.add('pluto')
    this.removeBtn.setAttribute('type', 'button')
    this.node.classList.add('is-hidden')
    this.actionNode.innerHTML = ''
    this.actionNode.appendChild(this.removeBtn)

    const errorNode = this.node.querySelector('.js-has-errors')

    if (errorNode) {
      const fieldNodes = this.node.querySelector('.js-fields')
      if (fieldNodes) {
        const clone = fieldNodes.cloneNode(true)
        errorNode.innerHTML = ''
        errorNode.classList.remove('js-has-errors')
        errorNode.appendChild(clone)
        // grab the inputs again as the cloning makes the original array out of date
        this.inputs = this.node.querySelectorAll('input')
      }
    }

    parent.appendChild(this.node)
    this.node.querySelector('input').focus()
    this.setIndex(this.index)
    forEach(this.inputs, input => { input.value = '' })
    window.setTimeout(this.node.classList.remove('is-hidden'), 100)
  }

  setIndex(index) {
    this.index = index
    forEach(this.indexNodes, node => { node.innerHTML = index })
    forEach(this.inputs, input => {
      const id = input.id
      const label = this.node.querySelector(`label[for=${id}]`)
      const newId = `${id}_${index - 1}`
      input.setAttribute('id', newId)
      label.setAttribute('for', newId)
      input.setAttribute('name', `${input.name.replace(/\d+/, index - 1)}`)
    })
  }

  remove() {
    if (transitionendEvent) {
      this.node.addEventListener(transitionendEvent, this.onTransitionHideEnd, true)
    } else {
      window.setTimeout(this.onTransitionHideEnd, 500)
    }
    this.node.classList.add('is-removed')
  }

  onTransitionHideEnd = (e) => {
    if (e === undefined || e.target.classList.contains('is-removed')) {
      this.node.parentNode.removeChild(this.node)
      this.node.removeEventListener(transitionendEvent, this.onTransitionHideEnd)
      this.emit('removed', this)
    }
  }

  onRemoveClick = (e) => {
    e.preventDefault()
    this.remove()
  }
}

domready(() => {
  const existingPeople = document.querySelectorAll('.js-household-person')
  const btn = document.querySelector('.js-household-btn')
  const householdMembers = []

  if (existingPeople.length === 0) {
    return
  }

  const createHouseholdMember = () => {
    const householdMember = new HouseholdMember(householdMembers.length + 2)
    householdMember.addListener('removed', onRemove)
    householdMembers.push(householdMember)
    return householdMember
  }

  const onRemove = (removedMember) => {
    householdMembers.splice(householdMembers.indexOf(removedMember), 1)
    removedMember.removeListener('removed', onRemove)
    householdMembers.map((member, index) => {
      member.setIndex(index + 2)
    })
  }

  const onAddBtnClick = (e) => {
    e.preventDefault()
    const originalNode = existingPeople[0]
    const newNode = originalNode.cloneNode(true)
    const parent = originalNode.parentNode
    createHouseholdMember().add(newNode, parent)
  }

  forEach(existingPeople, (person, index) => {
    if (index > 0) {
      createHouseholdMember().bindToExisting(person)
    }
  })

  btn.setAttribute('type', 'button')
  btn.addEventListener('click', onAddBtnClick)
})
<|endoftext|>


<commit_before>// ------------------------------------ UI tools -----------------------------------------
var Ui = {
  // Select record id attribute form grid - shouldn't this be an extension of Grid ? Why in Ui? Ui == User interface?
  selectIds: function(grid){
    var selectedIndexes = grid.getSelectedRows();
    var ids, item;
    if (grid == null) return false;
    if (selectedIndexes.length > 0) {
      ids = $.map(selectedIndexes,function(n, i) {
        item = grid.loader.data[n];
        return item['id'];
        }).join();
        return ids;
    } else {
        return false;
    }
  },

    // return true if the dialog of grid with "name" is open, unless return false
  isOpen: function() {
    return ($(".ui-dialog:visible").size() > 0);
  },

  // check if the grid is being edited
  isEditing: function() {
    var editing = false;
    $.each(gridManager.grids, function(){
      if(this.isEditing()) editing = true;
    });
    return editing;
  },

  //check if filter panel is open
  filterPanelOpen: function() {
    return ($('.slick-headerrow-columns:visible').size() > 0 && $( document.activeElement ).parent().attr('class') === 'slick-headerrow-columns');
  },

  // Select grid names
  selectGridNames: function() {
    var gridContainers = $(".grid_container"), gridName;
    return $.map( gridContainers, function(container){
      gridName = $.trim($(container).attr("id").split("grid_")[1]);
      if (gridName) {
        return gridName;
      }
    });
  },

  // Reset form
  resetForm: function(name) {
    $(':input','#new_' + name).not(':button, :submit, :reset, :hidden').val('').removeAttr('checked').removeAttr('selected');
    // For chosen
    $('ul.chzn-choices li.search-choice').remove();
  },

  // Create and open dialog
  openDialog: function(name) {
    $( '#' + name + '-form' ).dialog({
      height: 300,
      width: 500,
      show: "blind",
      modal: true,
      open: function(event, ui) {
      // The latest jqueryui had fixed the open event's bug,so the below will be works fine
      $( '#' + name + '-form input:text' ).first().focus();
			},
      close: function(event, ui) {
        $(this).find("input:text").val("");
        $(this).find(".field_error").text("");
        setTimeout(function(){
          Ui.highlightCreatedRows(name);
          gridManager.createdIds = [];
        }, 300);
        window._focused = {};
      }
    });
  },

  // Close dialog
  closeDialog: function(name) {
    $( '#' + name + '-form' ).dialog( "close" );
    setTimeout(function(){
      Ui.highlightCreatedRows(name);
      gridManager.createdIds = [];
      }, 300);
  },

  // Handle delete confirm with dialog
  deleteGrids: function(ids) {
    $( "#confirm_dialog" ).dialog({
      modal: true,
      buttons: {
        Yes: function() {
          Requests.deleteByAjax(Ui.findCurrentGrid(), ids);
          $( this ).dialog( "close" );
        },
        Cancel: function() {
          $( this ).dialog( "close" );
        }
      }
    });
  },

  // Highlight the created rows after close the dialog
  highlightCreatedRows: function(name) {
    var grid = gridManager.getGrid(name),
    createdRows = [];
    $.each(gridManager.createdIds, function(){
      if (grid.getRowByRecordId(this).row) {
        createdRows.push(grid.getRowByRecordId(this).row);
      }
    });
    $.each(createdRows, function(){
      $(this).effect( 'highlight', {}, 5000 );
    });
  },

  // Flash the notification
  flashNotice: function(ids, action) {
    var recordSize = $.isArray(ids) ? ids.length : ids.split(',').length,
    recordUnit = recordSize > 1 ? 'records' : 'record',
    actionDesc = action === 'delete' ? 'has been deleted!' : 'has been created!';

    if (recordSize > 0) {
      $('.notice_flash').remove();
      $('#indicators').before('
' + recordSize + ' ' + recordUnit + ' ' + actionDesc + '
');
      $('.notice_flash').fadeOut(7000);
    }
  },

  // Find the selected grid
  findCurrentGrid: function() {
    var currentGrid = null;
    currentGridContainer = $('.grid_container:visible');
    if (currentGridContainer.size() == 0) {
      return null;
    }
    gridName = currentGridContainer.attr('id').split('grid_')[1];

    if (gridManager.grids.length == 1) {
      currentGrid = gridManager.grids[0]
    } else {
      if (currentGridContainer.size() == 1) {
        currentGrid = gridManager.getGrid(gridName);
      } else {
        $.each(gridManager.grids, function(){
          if(this.getSelectedRows().length > 0) currentGrid = this;
        });
      }
    }
    return currentGrid;
  },

  addAble: function(grid) {
    return grid.actions.indexOf('add') != -1;
  },

  deleteAble: function(grid) {
    return grid.actions.indexOf('delete') != -1;
	},

	formatData: function(grid, arrayData) {
	  var data = {}, columns;
    columns = grid.loader.getColumns();
	  $.each(columns, function(index, column){
	    data[column['id']] = arrayData[index];
	  })
	  return data;
	}

};

// ------------------------- keypress action --------------------------------------
(function($) {
  $(document).keypress(function(e){
    var isEditing = Ui.isEditing(),
    isOpen = Ui.isOpen(),
    filterPanelOpen = Ui.filterPanelOpen(),
    grid = Ui.findCurrentGrid();
    if (grid) {
      var ids = Ui.selectIds(grid),
      gridSize = gridManager.grids.length;

      if (isOpen || isEditing || filterPanelOpen) {
        return true;
      } else {
        if (Ui.deleteAble(grid) && (e.which == 100 || e.which == 68)) {  // keypress 'D' for delete
          if (ids) {
            Ui.deleteGrids(ids);
            return false;
          }
          return false;
        } else if (Ui.addAble(grid) && (e.which == 99 || e.which == 67)) {  // keypress 'C' for show dialog
          if (gridSize > 0 && grid) {
            Ui.openDialog(grid.name);
            return false;
          }
          return false;
        } else {
          return true;
        }
      }
    }
  });
})(jQuery);
<commit_msg>MISC - Destroy jqueryui dialog instead of close<commit_after>// ------------------------------------ UI tools -----------------------------------------
var Ui = {
  // Select record id attribute form grid - shouldn't this be an extension of Grid ? Why in Ui? Ui == User interface?
  selectIds: function(grid){
    var selectedIndexes = grid.getSelectedRows();
    var ids, item;
    if (grid == null) return false;
    if (selectedIndexes.length > 0) {
      ids = $.map(selectedIndexes,function(n, i) {
        item = grid.loader.data[n];
        return item['id'];
        }).join();
        return ids;
    } else {
        return false;
    }
  },

    // return true if the dialog of grid with "name" is open, unless return false
  isOpen: function() {
    return ($(".ui-dialog:visible").size() > 0);
  },

  // check if the grid is being edited
  isEditing: function() {
    var editing = false;
    $.each(gridManager.grids, function(){
      if(this.isEditing()) editing = true;
    });
    return editing;
  },

  //check if filter panel is open
  filterPanelOpen: function() {
    return ($('.slick-headerrow-columns:visible').size() > 0 && $( document.activeElement ).parent().attr('class') === 'slick-headerrow-columns');
  },

  // Select grid names
  selectGridNames: function() {
    var gridContainers = $(".grid_container"), gridName;
    return $.map( gridContainers, function(container){
      gridName = $.trim($(container).attr("id").split("grid_")[1]);
      if (gridName) {
        return gridName;
      }
    });
  },

  // Reset form
  resetForm: function(name) {
    $(':input','#new_' + name).not(':button, :submit, :reset, :hidden').val('').removeAttr('checked').removeAttr('selected');
    // For chosen
    $('ul.chzn-choices li.search-choice').remove();
  },

  // Create and open dialog
  openDialog: function(name) {
    $( '#' + name + '-form' ).dialog({
      height: 300,
      width: 500,
      show: "blind",
      modal: true,
      open: function(event, ui) {
      // The latest jqueryui had fixed the open event's bug,so the below will be works fine
      $( '#' + name + '-form input:text' ).first().focus();
			},
      close: function(event, ui) {
        $(this).find("input:text").val("");
        $(this).find(".field_error").text("");
        setTimeout(function(){
          Ui.highlightCreatedRows(name);
          gridManager.createdIds = [];
        }, 300);
        window._focused = {};
      }
    });
  },

  // Close dialog
  closeDialog: function(name) {
    $( '#' + name + '-form' ).dialog('destroy');
    setTimeout(function(){
      Ui.highlightCreatedRows(name);
      gridManager.createdIds = [];
      }, 300);
  },

  // Handle delete confirm with dialog
  deleteGrids: function(ids) {
    $( "#confirm_dialog" ).dialog({
      modal: true,
      buttons: {
        Yes: function() {
          Requests.deleteByAjax(Ui.findCurrentGrid(), ids);
          $( this ).dialog( "close" );
        },
        Cancel: function() {
          $( this ).dialog( "close" );
        }
      }
    });
  },

  // Highlight the created rows after close the dialog
  highlightCreatedRows: function(name) {
    var grid = gridManager.getGrid(name),
    createdRows = [];
    $.each(gridManager.createdIds, function(){
      if (grid.getRowByRecordId(this).row) {
        createdRows.push(grid.getRowByRecordId(this).row);
      }
    });
    $.each(createdRows, function(){
      $(this).effect( 'highlight', {}, 5000 );
    });
  },

  // Flash the notification
  flashNotice: function(ids, action) {
    var recordSize = $.isArray(ids) ? ids.length : ids.split(',').length,
    recordUnit = recordSize > 1 ? 'records' : 'record',
    actionDesc = action === 'delete' ? 'has been deleted!' : 'has been created!';

    if (recordSize > 0) {
      $('.notice_flash').remove();
      $('#indicators').before('
' + recordSize + ' ' + recordUnit + ' ' + actionDesc + '
');
      $('.notice_flash').fadeOut(7000);
    }
  },

  // Find the selected grid
  findCurrentGrid: function() {
    var currentGrid = null;
    currentGridContainer = $('.grid_container:visible');
    if (currentGridContainer.size() == 0) {
      return null;
    }
    gridName = currentGridContainer.attr('id').split('grid_')[1];

    if (gridManager.grids.length == 1) {
      currentGrid = gridManager.grids[0]
    } else {
      if (currentGridContainer.size() == 1) {
        currentGrid = gridManager.getGrid(gridName);
      } else {
        $.each(gridManager.grids, function(){
          if(this.getSelectedRows().length > 0) currentGrid = this;
        });
      }
    }
    return currentGrid;
  },

  addAble: function(grid) {
    return grid.actions.indexOf('add') != -1;
  },

  deleteAble: function(grid) {
    return grid.actions.indexOf('delete') != -1;
	},

	formatData: function(grid, arrayData) {
	  var data = {}, columns;
    columns = grid.loader.getColumns();
	  $.each(columns, function(index, column){
	    data[column['id']] = arrayData[index];
	  })
	  return data;
	}

};

// ------------------------- keypress action --------------------------------------
(function($) {
  $(document).keypress(function(e){
    var isEditing = Ui.isEditing(),
    isOpen = Ui.isOpen(),
    filterPanelOpen = Ui.filterPanelOpen(),
    grid = Ui.findCurrentGrid();
    if (grid) {
      var ids = Ui.selectIds(grid),
      gridSize = gridManager.grids.length;

      if (isOpen || isEditing || filterPanelOpen) {
        return true;
      } else {
        if (Ui.deleteAble(grid) && (e.which == 100 || e.which == 68)) {  // keypress 'D' for delete
          if (ids) {
            Ui.deleteGrids(ids);
            return false;
          }
          return false;
        } else if (Ui.addAble(grid) && (e.which == 99 || e.which == 67)) {  // keypress 'C' for show dialog
          if (gridSize > 0 && grid) {
            Ui.openDialog(grid.name);
            return false;
          }
          return false;
        } else {
          return true;
        }
      }
    }
  });
})(jQuery);
<|endoftext|>


<commit_before>(function () {
    "use strict";
    HTMLElement.prototype.scrollSwipe = function () {
        var target = this,
            container,
            data = {},
            swiper = (function () {
                function createElement(type, styles) {
                    var el = document.createElement(type);
                    for (var property in styles) {
                        el.style[property] = styles[property];
                    }
                    return el;
                }

                function dispatch(name, delta) {
                    if ((Math.abs(delta.x) > 1) || (Math.abs(delta.y) > 1))
                        return target.dispatchEvent(new CustomEvent(name, {
                            detail: {
                                delta: delta,
                                bubbles: false,
                                cancelable: true
                            }
                        }));
                }
                function reset() {
                    container.scrollLeft = container.clientWidth;
                    container.scrollTop = container.clientHeight;
                    data.last = {
                        x: container.clientWidth * .5,
                        y: container.clientHeight * .5,
                        t: 0
                    };
                    return true;
                }

                function scrollable() {
                    var center = {
                            x: container.clientWidth * 1.5,
                            y: container.clientHeight * 1.5
                        },
                        timer = null,
                        starttime = 0,
                        swiping = false;
                    reset();
                    container.onscroll = function () {
                        //todo swipeEnd if overshot
                        var delta,
                            d = new Date().getTime();
                        if (!swiping) {
                            starttime = d;
                            delta = data.last;
                            dispatch("swipeStart", delta);
                            swiping = true;
                        } else {
                            delta = {
                                x: center.x - container.scrollLeft - data.last.x,
                                y: center.y - container.scrollTop - data.last.y,
                                t: d - starttime - data.last.t
                            };
                            data.last = {
                                x: center.x - container.scrollLeft,
                                y: center.y - container.scrollTop,
                                t: d - starttime
                            };
                            dispatch("swipeMove", delta);
                        }
                        if (timer) {
                            clearTimeout(timer);
                        }
                        timer = setTimeout(function () {
                            timer = null;
                            swiping = false;
                            d = new Date().getTime();
                            delta = {
                                x: center.x - container.scrollLeft,
                                y: center.y - container.scrollTop,
                                t: d - starttime
                            };
                            dispatch("swipeEnd", delta);
                            if (Math.abs(delta.y) > Math.abs(delta.x)) {
                                if (delta.y < 0) {
                                    dispatch("swipeUp", delta);
                                } else {
                                    dispatch("swipeDown", delta);
                                }
                            } else {
                                if (delta.x < 0) {
                                    dispatch("swipeLeft", delta);
                                } else {
                                    dispatch("swipeRight", delta);
                                }
                            }
                            reset();
                        }, 100);
                    };
                    return true;
                }

                return {
                    createElement: createElement,
                    scrollable: scrollable
                }
            })();
        container = swiper.createElement('div', {
            zIndex: 2147483646,
            overflow: "auto",
            opacity: 0,
            top: 0,
            left: 0,
            position: "absolute",
            width: "100%",
            height: "100%",
            webkitUserSelect: "none",
            webkitOverflowScrolling: "touch"
        });
        container.appendChild(swiper.createElement('div', {
            position: "relative",
            width: "300%",
            height: "300%"
        }));
        target.insertBefore(container, target.firstElementChild);
        swiper.scrollable();
        return target;
    }
})();
<commit_msg>multiplication optomize bit shift<commit_after>(function () {
    "use strict";
    HTMLElement.prototype.scrollSwipe = function () {
        var target = this,
            container,
            data = {},
            swiper = (function () {
                function createElement(type, styles) {
                    var el = document.createElement(type);
                    for (var property in styles) {
                        el.style[property] = styles[property];
                    }
                    return el;
                }

                function dispatch(name, delta) {
                    if ((Math.abs(delta.x) > 1) || (Math.abs(delta.y) > 1))
                        return target.dispatchEvent(new CustomEvent(name, {
                            detail: {
                                delta: delta,
                                bubbles: false,
                                cancelable: true
                            }
                        }));
                }
                function reset() {
                    container.scrollLeft = container.clientWidth;
                    container.scrollTop = container.clientHeight;
                    data.last = {
                        x: container.clientWidth >> 1,
                        y: container.clientHeight >> 1,
                        t: 0
                    };
                    return true;
                }

                function scrollable() {
                    var center = {
                            x: (container.clientWidth >> 1) + container.clientWidth,
                            y: (container.clientHeight >> 1) + container.clientHeight
                        },
                        timer = null,
                        starttime = 0,
                        swiping = false;
                    reset();
                    container.onscroll = function () {
                        //todo swipeEnd if overshot
                        var delta,
                            d = new Date().getTime();
                        if (!swiping) {
                            starttime = d;
                            delta = data.last;
                            dispatch("swipeStart", delta);
                            swiping = true;
                        } else {
                            delta = {
                                x: center.x - container.scrollLeft - data.last.x,
                                y: center.y - container.scrollTop - data.last.y,
                                t: d - starttime - data.last.t
                            };
                            data.last = {
                                x: center.x - container.scrollLeft,
                                y: center.y - container.scrollTop,
                                t: d - starttime
                            };
                            dispatch("swipeMove", delta);
                        }
                        if (timer) {
                            clearTimeout(timer);
                        }
                        timer = setTimeout(function () {
                            timer = null;
                            swiping = false;
                            d = new Date().getTime();
                            delta = {
                                x: center.x - container.scrollLeft,
                                y: center.y - container.scrollTop,
                                t: d - starttime
                            };
                            dispatch("swipeEnd", delta);
                            if (Math.abs(delta.y) > Math.abs(delta.x)) {
                                if (delta.y < 0) {
                                    dispatch("swipeUp", delta);
                                } else {
                                    dispatch("swipeDown", delta);
                                }
                            } else {
                                if (delta.x < 0) {
                                    dispatch("swipeLeft", delta);
                                } else {
                                    dispatch("swipeRight", delta);
                                }
                            }
                            reset();
                        }, 100);
                    };
                    return true;
                }

                return {
                    createElement: createElement,
                    scrollable: scrollable
                }
            })();
        container = swiper.createElement('div', {
            zIndex: 2147483646,
            overflow: "auto",
            opacity: 0,
            top: 0,
            left: 0,
            position: "absolute",
            width: "100%",
            height: "100%",
            webkitUserSelect: "none",
            webkitOverflowScrolling: "touch"
        });
        container.appendChild(swiper.createElement('div', {
            position: "relative",
            width: "300%",
            height: "300%"
        }));
        target.insertBefore(container, target.firstElementChild);
        swiper.scrollable();
        return target;
    }
})();
<|endoftext|>


<commit_before>function RepoController() {

  this.view = new RepoView()
  this.repolist = new RepoList()

}

RepoController.prototype.load = function() {
  this.repolist.getRepos()
}

RepoController.prototype.renderRepo = function(repo){
  $(this.view.title).html(repo.name)
  $(this.view.fullName).html(repo.full_name)
  $(this.view.description).html(repo.description)
  $(this.view.language).html(repo.language)
  $(this.view.stars).html(repo.stargazers_count )
  $(this.view.forks).html(repo.forks_count)
  $(this.view.contributorsCount).html(repo.contributors_count)
  $(this.view.contributorFile).html(repo.contributorIcon())
  $(this.view.contributorsPercent).html((repo.contributors_count *100 / repo.stargazers_count).toFixed(2) +"%")
  $(this.view.pullrequestPercent).html((repo.pull_request_count *100 / repo.open_issues_count).toFixed(2) +"%")

}

RepoController.prototype.loadNext = function(){
  $("#issue-list").empty()
  var repo = this.repolist.repos.shift()
  var nextRepo = this.repolist.repos[0]
  this.renderRepo(repo);
  repo.issues.length > 0 ? repo.renderIssues() : ""
  //Preload the next repo's issues so they are ready by the time the user clicks
  nextRepo.getIssues()
}

RepoController.prototype.bindEvents = function(){

  var that = this

  $('#lang-nav li').on('click', 'a', function(e){
      e.preventDefault();
      var lang = $(this).text().toLowerCase();
      that.repolist.reloadByLanguage(lang,that)
  });

  // posting the upvotes
  $('#star').on('click', function(e){
    e.preventDefault();
    var statusUpdate = {'repo_full_name': $('#repo-full-name').text()}
    $.ajax({
      url: '/star',
      method: 'POST',
      dataType: 'json',
      data: statusUpdate
    });
  });

  // posting the downvotes
  $('#hide').on('click', function(e){
    e.preventDefault();
    var statusUpdate = {'repo_full_name': $('#repo-full-name').text()}
    $.ajax({
      url: '/hide',
      method: 'POST',
      dataType: 'json',
      data: statusUpdate
    });
  });

  $('#display-buttons button').on('click', this.loadNext.bind(repoController))
  $('#display-buttons button').on('click', this.toggleTimeout(this))

}

RepoController.prototype.toggleTimeout = function(controller) {

  return function(event){
    var that = event.target
    $(that).addClass('disabled');
    $(that).off();

    setTimeout(function(){
      $(that).removeClass('disabled');
      $(that).on('click', controller.loadNext.bind(controller));
      $(that).on('click', controller.toggleTimeout(controller));
    }, 1500)
  }

}

<commit_msg>add repo action listeners back after toggling off<commit_after>function RepoController() {

  this.view = new RepoView()
  this.repolist = new RepoList()

}

RepoController.prototype.load = function() {
  this.repolist.getRepos()
}

RepoController.prototype.renderRepo = function(repo){
  $(this.view.title).html(repo.name)
  $(this.view.fullName).html(repo.full_name)
  $(this.view.description).html(repo.description)
  $(this.view.language).html(repo.language)
  $(this.view.stars).html(repo.stargazers_count )
  $(this.view.forks).html(repo.forks_count)
  $(this.view.contributorsCount).html(repo.contributors_count)
  $(this.view.contributorFile).html(repo.contributorIcon())
  $(this.view.contributorsPercent).html((repo.contributors_count *100 / repo.stargazers_count).toFixed(2) +"%")
  $(this.view.pullrequestPercent).html((repo.pull_request_count *100 / repo.open_issues_count).toFixed(2) +"%")

}

RepoController.prototype.loadNext = function(){
  $("#issue-list").empty()
  var repo = this.repolist.repos.shift()
  var nextRepo = this.repolist.repos[0]
  this.renderRepo(repo);
  repo.issues.length > 0 ? repo.renderIssues() : ""
  //Preload the next repo's issues so they are ready by the time the user clicks
  nextRepo.getIssues()
}

RepoController.prototype.bindEvents = function(){

  var that = this

  $('#lang-nav li').on('click', 'a', function(e){
      e.preventDefault();
      var lang = $(this).text().toLowerCase();
      that.repolist.reloadByLanguage(lang,that)
  });

  // posting the upvotes
  $('#star').on('click', function(e){
    e.preventDefault();
    var statusUpdate = {'repo_full_name': $('#repo-full-name').text()}
    $.ajax({
      url: '/star',
      method: 'POST',
      dataType: 'json',
      data: statusUpdate
    });
  });

  // posting the downvotes
  $('#hide').on('click', function(e){
    e.preventDefault();
    var statusUpdate = {'repo_full_name': $('#repo-full-name').text()}
    $.ajax({
      url: '/hide',
      method: 'POST',
      dataType: 'json',
      data: statusUpdate
    });
  });

  $('#display-buttons button').on('click', this.loadNext.bind(repoController))
  $('#display-buttons button').on('click', this.toggleTimeout(this))

}

RepoController.prototype.toggleTimeout = function(controller) {

  return function(event){
    var that = event.target
    $(that).addClass('disabled');
    $(that).off();

    setTimeout(function(){
      $(that).removeClass('disabled');
      $(that).on('click', controller.loadNext.bind(controller));
      $(that).on('click', controller.toggleTimeout(controller));

      if($(that).is('#hide')){
        $(that).on('click', function(e){
          e.preventDefault();
          var statusUpdate = {'repo_full_name': $('#repo-full-name').text()}
          $.ajax({
            url: '/hide',
            method: 'POST',
            dataType: 'json',
            data: statusUpdate
          });
        });
        } else if($(that).is('#star')){
          $(that).on('click', function(e){
            e.preventDefault();
            var statusUpdate = {'repo_full_name': $('#repo-full-name').text()}
            $.ajax({
              url: '/star',
              method: 'POST',
              dataType: 'json',
              data: statusUpdate
            });
          });
        }
    }, 1500)
  }

}

<|endoftext|>


<commit_before>// ELMO.Views.QuestionForm
//
// View model for Question form
(function(ns, klass) {

  // constructor
  ns.QuestionForm = klass = function(params) { var self = this;
    self.params = params;

    // hookup type change event and trigger immediately
    var type_box = $('div.question_fields .form_field#qtype_name .control select');
    type_box.on('change', function(e){ self.question_type_changed(); });

    // run the type box changed event immediately
    // this might be the only time it runs since the form might be in show mode
    self.question_type_changed();

    // hookup add option set link
    $('div.question_fields a.create_option_set').on('click', function(){ self.show_option_set_form(); return false; });

    // hookup form submit for modal
    $('#create-option-set .btn-primary').on('click', function() {$('form.option_set_form').submit();});

    // register a callback for when option set form submission is done
    $(document).on('option_set_form_submit_success', 'form.option_set_form', function(e, option_set){
      self.option_set_created(option_set);
    });
  }

  // gets the current value of the field with the given name
  // still works if field is read_only
  klass.prototype.field_value = function(field_name) { var self = this;
    var field_div = $('.question_fields .form_field[data-field-name=' + field_name + '] .control');

    // if read only
    if (field_div.is('.read_only')) {
      // first get the wrapper
      var wrapper = field_div.find('.ro-val');

      // now try to get the wrapper's data-val value, or just the wrapper's contents failing that
      return wrapper.data('val') || wrapper.text();

    // otherwise (not read only) just get the field value
    } else
      return field_div.find('input, select, textarea').val();
  }

  klass.prototype.question_type_changed = function() { var self = this;
    var selected_type = self.field_value('qtype_name');

    // show/hide option set field and hint
    var show_opt_set = (selected_type == "select_one" || selected_type == "select_multiple");
    var optionSet = $("div.question_fields .form_field[data-field-name=option_set_id]");
    if (show_opt_set) {
      optionSet.show();
    } else {
      optionSet.hide();
    }

    // reset select if hiding
    if (!show_opt_set)
      $("div.question_fields .form_field[data-field-name=option_set_id] .control select").val('');

    // show/hide max/min
    var show_max_min = (selected_type == "decimal" || selected_type == "integer");
    $(".question_fields .minmax")[show_max_min ? 'show' : 'hide']();

    // reset boxes if hiding
    if (!show_max_min) {
      $(".form_field#minimum input[id$='_minimum']").val("");
      $(".form_field#minimum input[id$='_minstrictly']").prop("checked", false);
      $(".form_field#maximum input[id$='_maximum']").val("");
      $(".form_field#maximum input[id$='_maxstrictly']").prop("checked", false);
    }
  }

  // shows the create option set form and sets up a callback to receive the result
  klass.prototype.show_option_set_form = function() { var self = this;
    // show the loading indicator
    $('div.question_fields #option_set_id .loading_indicator').show();

    // populate and show the modal
    $("#create-option-set .modal-body.option-set").load(self.params.new_option_set_path, function(){
      $("#create-option-set").modal('show');
    });
  }

  // called when the option set is created so we can add it to the dropdown
  klass.prototype.option_set_created = function(option_set) { var self = this;
    // close the dialog
    $("#create-option-set").modal('hide');

    // add the new option set to the list and select it
    $('div.question_fields .form_field#option_set_id select').append($('<option>', {value: option_set.id}).text(option_set.name))
      .val(option_set.id);

    // flash the option set row
    $('div.question_fields .form_field#option_set_id').effect("highlight", {}, 1000);
  };

}(ELMO.Views));<commit_msg>forgot one thing to the hint question<commit_after>// ELMO.Views.QuestionForm
//
// View model for Question form
(function(ns, klass) {

  // constructor
  ns.QuestionForm = klass = function(params) { var self = this;
    self.params = params;

    // hookup type change event and trigger immediately
    var type_box = $('div.question_fields .form_field#qtype_name .control select');
    type_box.on('change', function(e){ self.question_type_changed(); });

    // run the type box changed event immediately
    // this might be the only time it runs since the form might be in show mode
    self.question_type_changed();

    // hookup add option set link
    $('div.question_fields a.create_option_set').on('click', function(){ self.show_option_set_form(); return false; });

    // hookup form submit for modal
    $('#create-option-set .btn-primary').on('click', function() {$('form.option_set_form').submit();});

    // register a callback for when option set form submission is done
    $(document).on('option_set_form_submit_success', 'form.option_set_form', function(e, option_set){
      self.option_set_created(option_set);
    });
  }

  // gets the current value of the field with the given name
  // still works if field is read_only
  klass.prototype.field_value = function(field_name) { var self = this;
    var field_div = $('.question_fields .form_field[data-field-name=' + field_name + '] .control');

    // if read only
    if (field_div.is('.read_only')) {
      // first get the wrapper
      var wrapper = field_div.find('.ro-val');

      // now try to get the wrapper's data-val value, or just the wrapper's contents failing that
      return wrapper.data('val') || wrapper.text();

    // otherwise (not read only) just get the field value
    } else
      return field_div.find('input, select, textarea').val();
  }

  klass.prototype.question_type_changed = function() { var self = this;
    var selected_type = self.field_value('qtype_name');

    // show/hide option set field and hint
    var show_opt_set = (selected_type == "select_one" || selected_type == "select_multiple");
    var optionSet = $("div.question_fields .form_field[data-field-name=option_set_id]");
    show_opt_set ? optionSet.show() : optionSet.hide();

    // reset select if hiding
    if (!show_opt_set)
      $("div.question_fields .form_field[data-field-name=option_set_id] .control select").val('');

    // show/hide max/min
    var show_max_min = (selected_type == "decimal" || selected_type == "integer");
    $(".question_fields .minmax")[show_max_min ? 'show' : 'hide']();

    // reset boxes if hiding
    if (!show_max_min) {
      $(".form_field#minimum input[id$='_minimum']").val("");
      $(".form_field#minimum input[id$='_minstrictly']").prop("checked", false);
      $(".form_field#maximum input[id$='_maximum']").val("");
      $(".form_field#maximum input[id$='_maxstrictly']").prop("checked", false);
    }
  }

  // shows the create option set form and sets up a callback to receive the result
  klass.prototype.show_option_set_form = function() { var self = this;
    // show the loading indicator
    $('div.question_fields #option_set_id .loading_indicator').show();

    // populate and show the modal
    $("#create-option-set .modal-body.option-set").load(self.params.new_option_set_path, function(){
      $("#create-option-set").modal('show');
    });
  }

  // called when the option set is created so we can add it to the dropdown
  klass.prototype.option_set_created = function(option_set) { var self = this;
    // close the dialog
    $("#create-option-set").modal('hide');

    // add the new option set to the list and select it
    $('div.question_fields .form_field#option_set_id select').append($('<option>', {value: option_set.id}).text(option_set.name))
      .val(option_set.id);

    // flash the option set row
    $('div.question_fields .form_field#option_set_id').effect("highlight", {}, 1000);
  };

}(ELMO.Views));<|endoftext|>


<commit_before>(function($) {
  $(".countries-wrapper").attr("aria-live", "polite");
  $.expr[':'].contains = function(obj, index, meta){
    return (obj.textContent || obj.innerText || "").toUpperCase().indexOf(meta[3].toUpperCase()) >= 0;
  };

  var headingHasVisibleCountries = function(headingFirstLetter) {
    return $("section#" + headingFirstLetter.toUpperCase()).find("li:visible").length > 0;
  };

  var input = $("form#country-filter input#country"),
      listItems = $("ul.countries li"),
      countryHeadings = $(".inner section").not(":first").children("h1");

  var filterHeadings = function() {
    countryHeadings.each(function(index, elem) {
      var $elem = $(elem), header = $elem.text();
      headingHasVisibleCountries(header) ? $elem.show() : $elem.hide();
    });
  };

  var filterListItems = function(filter) {
    filterHeadings();
    listItems.each(function(i, item) {
      var $item = $(item);
      var link = $item.children("a");
      $item.html(link);
    }).show();
    if(filter && filter.length > 0) {
      listItems.filter(":not(:contains(" + filter + "))").hide();
      var synonyms = findSynonym(filter);
      $.each(synonyms, function(i, match) {
        if(match.countries.length) {
          $.each(match.countries, function(i, country) {
            listItems.filter(":hidden").filter(":contains(" + country + ")").show().append("(" + match.synonym + ")");
          });
        }
      });
      filterHeadings();
    } else {
      countryHeadings.show();
    }
  };

  var findSynonym = function(search) {
    var countrySynonyms = {
      "United States": "USA",
      "America": "USA",
      "Dubai": "United Arab Emirates",
      "UAE": "United Arab Emirates",
      "East Timor": "Timor-Leste",
      "Ivory Coast": "Côte d'Ivoire",
      "PNG": "Papua New Guinea",
      "Ibiza": "Spain",
      "Borneo": ["Indonesia", "Malaysia", "Brunei"]
    };

    var foundSynonyms = [];
    for(var prop in countrySynonyms) {
      if(prop.toLowerCase().indexOf(search.toLowerCase()) > -1) {
        foundSynonyms.push({
          synonym: prop,
          countries: $.isArray(countrySynonyms[prop]) ? countrySynonyms[prop] : [countrySynonyms[prop]]
        });
      }
    }
    return foundSynonyms;
  }

  input.change(function(e) {
    var filter = $(this).val();
    filterListItems(filter);
    findSynonym(filter);
    e.preventDefault();
  }).keyup(function() {
    $(this).change();
  }).keypress(function(event) {
    if (event.which == 13) {
      event.preventDefault();
    }
  });
}(jQuery));
<commit_msg>Add Mallorca -> Spain synonym<commit_after>(function($) {
  $(".countries-wrapper").attr("aria-live", "polite");
  $.expr[':'].contains = function(obj, index, meta){
    return (obj.textContent || obj.innerText || "").toUpperCase().indexOf(meta[3].toUpperCase()) >= 0;
  };

  var headingHasVisibleCountries = function(headingFirstLetter) {
    return $("section#" + headingFirstLetter.toUpperCase()).find("li:visible").length > 0;
  };

  var input = $("form#country-filter input#country"),
      listItems = $("ul.countries li"),
      countryHeadings = $(".inner section").not(":first").children("h1");

  var filterHeadings = function() {
    countryHeadings.each(function(index, elem) {
      var $elem = $(elem), header = $elem.text();
      headingHasVisibleCountries(header) ? $elem.show() : $elem.hide();
    });
  };

  var filterListItems = function(filter) {
    filterHeadings();
    listItems.each(function(i, item) {
      var $item = $(item);
      var link = $item.children("a");
      $item.html(link);
    }).show();
    if(filter && filter.length > 0) {
      listItems.filter(":not(:contains(" + filter + "))").hide();
      var synonyms = findSynonym(filter);
      $.each(synonyms, function(i, match) {
        if(match.countries.length) {
          $.each(match.countries, function(i, country) {
            listItems.filter(":hidden").filter(":contains(" + country + ")").show().append("(" + match.synonym + ")");
          });
        }
      });
      filterHeadings();
    } else {
      countryHeadings.show();
    }
  };

  var findSynonym = function(search) {
    var countrySynonyms = {
      "United States": "USA",
      "America": "USA",
      "Dubai": "United Arab Emirates",
      "UAE": "United Arab Emirates",
      "East Timor": "Timor-Leste",
      "Ivory Coast": "Côte d'Ivoire",
      "PNG": "Papua New Guinea",
      "Ibiza": "Spain",
      "Mallorca": "Spain",
      "Borneo": ["Indonesia", "Malaysia", "Brunei"]
    };

    var foundSynonyms = [];
    for(var prop in countrySynonyms) {
      if(prop.toLowerCase().indexOf(search.toLowerCase()) > -1) {
        foundSynonyms.push({
          synonym: prop,
          countries: $.isArray(countrySynonyms[prop]) ? countrySynonyms[prop] : [countrySynonyms[prop]]
        });
      }
    }
    return foundSynonyms;
  }

  input.change(function(e) {
    var filter = $(this).val();
    filterListItems(filter);
    findSynonym(filter);
    e.preventDefault();
  }).keyup(function() {
    $(this).change();
  }).keypress(function(event) {
    if (event.which == 13) {
      event.preventDefault();
    }
  });
}(jQuery));
<|endoftext|>


<commit_before>(function() {
  "use strict";

  function uniqueEmailValidatorDirective() {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, ngModel) {
        //not used in this example
        var apiUrl = attrs.uniqueEmailValidator;

        function setAsLoading(bool) {
          ngModel.$setValidity('recordLoading', !bool);
        }

        function setAsAvailable(bool) {
          ngModel.$setValidity('recordAvailable', bool);
        }

        ngModel.$parsers.push(function(value) {
          if (!value || value.length === 0) {
            return;
          }

          setAsLoading(true);
          setAsAvailable(false);

          if (value === 'admin@example.com') {
            setAsLoading(false);
            setAsAvailable(false);
          } else {
            setAsLoading(false);
            setAsAvailable(true);
          }

          return value;
        });
      }
    };
  }

  angular.module('directives.uniqueEmailValidator', [])
    .directive('uniqueEmailValidator', uniqueEmailValidatorDirective);
})();
<commit_msg>adding some comments<commit_after>(function() {
  "use strict";

  function uniqueEmailValidatorDirective() {
    return {
      require: 'ngModel',
      link: function(scope, element, attrs, ngModel) {
        //not used in this example
        var apiUrl = attrs.uniqueEmailValidator;

        function setAsLoading(bool) {
          ngModel.$setValidity('recordLoading', !bool);
        }

        function setAsAvailable(bool) {
          ngModel.$setValidity('recordAvailable', bool);
        }

        ngModel.$parsers.push(function(value) {
          if (!value || value.length === 0) {
            return;
          }

          setAsLoading(true);
          setAsAvailable(false);

          //in real world you should call server here
          if (value === 'admin@example.com') {
            setAsLoading(false);
            setAsAvailable(false);
          } else {
            setAsLoading(false);
            setAsAvailable(true);
          }

          return value;
        });
      }
    };
  }

  angular.module('directives.uniqueEmailValidator', [])
    .directive('uniqueEmailValidator', uniqueEmailValidatorDirective);
})();
<|endoftext|>


<commit_before>import React from 'react';
import Relay from 'react-relay';
import shallowCompare from 'react-addons-shallow-compare';

import AnchoredPopover from '../shared/Popover/anchored';
import Button from '../shared/Button';
import Spinner from '../shared/Spinner';
import UserAvatar from '../shared/UserAvatar';

import FlashesStore from '../../stores/FlashesStore';

import EmailCreateMutation from '../../mutations/EmailCreate';
import EmailResendVerificationMutation from '../../mutations/EmailResendVerification';
import NoticeDismissMutation from '../../mutations/NoticeDismiss';

class AvatarWithEmailPrompt extends React.Component {
  static propTypes = {
    build: React.PropTypes.shape({
      createdBy: React.PropTypes.shape({
        email: React.PropTypes.string
      })
    }).isRequired,
    viewer: React.PropTypes.shape({
      emails: React.PropTypes.shape({
        edges: React.PropTypes.arrayOf(
          React.PropTypes.shape({
            node: React.PropTypes.shape({
              id: React.PropTypes.string,
              address: React.PropTypes.string,
              verified: React.PropTypes.bool
            })
          })
        )
      }).isRequired,
      notice: React.PropTypes.shape({
        dismissedAt: React.PropTypes.string
      })
    }).isRequired,
    relay: React.PropTypes.object
  };

  state = {
    isAddingEmail: false,
    isSendingVerification: false,
    hasSentSomething: false,
    hasBeenDismissed: false
  };

  getUserEmail(email) {
    const userEmails = this.props.viewer.emails.edges;

    const userEmail = userEmails.find(
      ({ node: { address: userEmail } }) => (
        userEmail.toLowerCase() === email.toLowerCase()
      )
    );

    if (userEmail) {
      return userEmail.node;
    }
  }

  isCurrentUsersValidatedEmail(email) {
    const userEmail = this.getUserEmail(email);
    return userEmail && userEmail.verified;
  }

  shouldComponentUpdate(nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
  }

  componentWillReceiveProps(nextProps) {
    const { createdBy } = nextProps.build;

    if (createdBy && createdBy.email && !this.isCurrentUsersValidatedEmail(createdBy.email)) {
      this.props.relay.setVariables({
        isTryingToPrompt: true,
        emailForPrompt: createdBy.email.toLowerCase()
      });
    }
  }

  handleDismissClick = () => {
    const mutation = new NoticeDismissMutation({ viewer: this.props.viewer, notice: this.props.viewer.notice });

    Relay.Store.commitUpdate(mutation, { onFailure: this.handleMutationFailure });
  };

  handleMutationFailure = (transaction) => {
    this.setState({ isAddingEmail: false });

    FlashesStore.flash(FlashesStore.ERROR, transaction.getError());
  };

  handleAddEmailClick = () => {
    this.setState({ isAddingEmail: true });

    const mutation = new EmailCreateMutation({ address: this.props.build.createdBy.email, viewer: this.props.viewer });

    Relay.Store.commitUpdate(mutation, { onSuccess: this.handleEmailAddedSuccess, onFailure: this.handleMutationFailure });
  };

  handleResendVerificationClick = () => {
    this.setState({ isSendingVerification: true });

    const mutation = new EmailResendVerificationMutation({ email: this.getUserEmail(this.props.build.createdBy.email) });

    Relay.Store.commitUpdate(mutation, { onSuccess: this.handleVerificationResentSuccess, onFailure: this.handleMutationFailure });
  };

  handleEmailAddedSuccess = () => {
    this.setState({ isAddingEmail: false, hasSentSomething: true });
  };

  handleVerificationResentSuccess = () => {
    this.setState({ isSendingVerification: false, hasSentSomething: true });
  };

  handleLocalDismissClick = () => {
    this.setState({ hasBeenDismissed: true });
  }

  renderContent() {
    const {
      build: {
        createdBy: {
          email
        }
      },
      relay: {
        variables: {
          isTryingToPrompt
        }
      },
      viewer: {
        notice
      }
    } = this.props;
    const { isAddingEmail, isSendingVerification, hasBeenDismissed, hasSentSomething } = this.state;
    const wrapperClassName = 'center px3 py2';

    // There won't be an email address if this build was created by a
    // registered user or if this build just has no owner (perhaps it was
    // created by Buildkite)
    if (!email) {
      return null;
    }

    // If we haven't decided to send a query for this yet, don't show anything!
    if (!isTryingToPrompt) {
      return null;
    }

    // If the user has seen the notice and has been dismissed
    if (notice && notice.dismissedAt) {
      return null;
    }

    // If the user has dismissed this notice instance
    if (hasBeenDismissed) {
      return null;
    }

    if (isAddingEmail || isSendingVerification) {
      return (

          <Spinner />

            {isSendingVerification ? 'Resending verification email…' : `Adding ${email}…`}

      );
    }

    const userEmail = this.getUserEmail(email);

    if (userEmail) {
      if (userEmail.verified) {
        return null;
      }

      if (hasSentSomething) {
        return (

              Verification Needed

              Click the link we’ve just emailed to {email} to finish adding this email to your account.

            <Button
              className="block mt2"
              theme="default"
              outline={true}
              style={{ width: '100%' }}
              onClick={this.handleLocalDismissClick}
            >
              Dismiss
            </Button>

        );
      }

      return (

            Verification Needed

            We’ve emailed a link to {email} to add this email to your account.

            If it hasn’t arrived, you can resend it from here!

          <Button
            className="block mt2"
            theme="default"
            outline={true}
            style={{ width: '100%' }}
            onClick={this.handleResendVerificationClick}
          >
            Resend Verification Email
          </Button>

      );
    }

    // Otherwise, we've got an unknown (to Buildkite) email address on our hands!
    return (

          Do you own this email address? If so, add it to your Buildkite account to take ownership of this build.

        <Button
          className="block my2"
          style={{ width: '100%' }}
          onClick={this.handleAddEmailClick}
        >
          Add {email}
        </Button>
        <Button
          className="block"
          theme="default"
          outline={true}
          style={{ width: '100%' }}
          onClick={this.handleDismissClick}
        >
          Dismiss
        </Button>

    );
  }

  render() {
    const { build } = this.props;

    const avatar = (
      <UserAvatar
        user={build.createdBy}
        style={{ width: 32, height: 32 }}
      />
    );

    const content = this.renderContent();

    if (content) {
      return (
        <AnchoredPopover
          alwaysShow={true}
          width={400}
        >
          {avatar}
          {content}
        </AnchoredPopover>
      );
    }

    return avatar;
  }
}

export default Relay.createContainer(AvatarWithEmailPrompt, {
  initialVariables: {
    emailForPrompt: null,
    isTryingToPrompt: false
  },

  fragments: {
    build: () => Relay.QL`
      fragment on Build {
        createdBy {
          ...on UnregisteredUser {
            email
            name
            avatar {
              url
            }
          }
          ...on User {
            name
            avatar {
              url
            }
          }
        }
      }
    `,
    viewer: () => Relay.QL`
      fragment on Viewer {
        ${EmailCreateMutation.getFragment('viewer')}
        emails(first: 50) {
          edges {
            node {
              id
              address
              verified
            }
          }
        }
        notice(namespace: NOTICE_NAMESPACE_EMAIL_SUGGESTION, scope: $emailForPrompt) @include(if: $isTryingToPrompt) {
          ${NoticeDismissMutation.getFragment('notice')}
          dismissedAt
        }
      }
    `
  }
});
<commit_msg>Padding swap<commit_after>import React from 'react';
import Relay from 'react-relay';
import shallowCompare from 'react-addons-shallow-compare';

import AnchoredPopover from '../shared/Popover/anchored';
import Button from '../shared/Button';
import Spinner from '../shared/Spinner';
import UserAvatar from '../shared/UserAvatar';

import FlashesStore from '../../stores/FlashesStore';

import EmailCreateMutation from '../../mutations/EmailCreate';
import EmailResendVerificationMutation from '../../mutations/EmailResendVerification';
import NoticeDismissMutation from '../../mutations/NoticeDismiss';

class AvatarWithEmailPrompt extends React.Component {
  static propTypes = {
    build: React.PropTypes.shape({
      createdBy: React.PropTypes.shape({
        email: React.PropTypes.string
      })
    }).isRequired,
    viewer: React.PropTypes.shape({
      emails: React.PropTypes.shape({
        edges: React.PropTypes.arrayOf(
          React.PropTypes.shape({
            node: React.PropTypes.shape({
              id: React.PropTypes.string,
              address: React.PropTypes.string,
              verified: React.PropTypes.bool
            })
          })
        )
      }).isRequired,
      notice: React.PropTypes.shape({
        dismissedAt: React.PropTypes.string
      })
    }).isRequired,
    relay: React.PropTypes.object
  };

  state = {
    isAddingEmail: false,
    isSendingVerification: false,
    hasSentSomething: false,
    hasBeenDismissed: false
  };

  getUserEmail(email) {
    const userEmails = this.props.viewer.emails.edges;

    const userEmail = userEmails.find(
      ({ node: { address: userEmail } }) => (
        userEmail.toLowerCase() === email.toLowerCase()
      )
    );

    if (userEmail) {
      return userEmail.node;
    }
  }

  isCurrentUsersValidatedEmail(email) {
    const userEmail = this.getUserEmail(email);
    return userEmail && userEmail.verified;
  }

  shouldComponentUpdate(nextProps, nextState) {
    return shallowCompare(this, nextProps, nextState);
  }

  componentWillReceiveProps(nextProps) {
    const { createdBy } = nextProps.build;

    if (createdBy && createdBy.email && !this.isCurrentUsersValidatedEmail(createdBy.email)) {
      this.props.relay.setVariables({
        isTryingToPrompt: true,
        emailForPrompt: createdBy.email.toLowerCase()
      });
    }
  }

  handleDismissClick = () => {
    const mutation = new NoticeDismissMutation({ viewer: this.props.viewer, notice: this.props.viewer.notice });

    Relay.Store.commitUpdate(mutation, { onFailure: this.handleMutationFailure });
  };

  handleMutationFailure = (transaction) => {
    this.setState({ isAddingEmail: false });

    FlashesStore.flash(FlashesStore.ERROR, transaction.getError());
  };

  handleAddEmailClick = () => {
    this.setState({ isAddingEmail: true });

    const mutation = new EmailCreateMutation({ address: this.props.build.createdBy.email, viewer: this.props.viewer });

    Relay.Store.commitUpdate(mutation, { onSuccess: this.handleEmailAddedSuccess, onFailure: this.handleMutationFailure });
  };

  handleResendVerificationClick = () => {
    this.setState({ isSendingVerification: true });

    const mutation = new EmailResendVerificationMutation({ email: this.getUserEmail(this.props.build.createdBy.email) });

    Relay.Store.commitUpdate(mutation, { onSuccess: this.handleVerificationResentSuccess, onFailure: this.handleMutationFailure });
  };

  handleEmailAddedSuccess = () => {
    this.setState({ isAddingEmail: false, hasSentSomething: true });
  };

  handleVerificationResentSuccess = () => {
    this.setState({ isSendingVerification: false, hasSentSomething: true });
  };

  handleLocalDismissClick = () => {
    this.setState({ hasBeenDismissed: true });
  }

  renderContent() {
    const {
      build: {
        createdBy: {
          email
        }
      },
      relay: {
        variables: {
          isTryingToPrompt
        }
      },
      viewer: {
        notice
      }
    } = this.props;
    const { isAddingEmail, isSendingVerification, hasBeenDismissed, hasSentSomething } = this.state;
    const wrapperClassName = 'center px3 py2';

    // There won't be an email address if this build was created by a
    // registered user or if this build just has no owner (perhaps it was
    // created by Buildkite)
    if (!email) {
      return null;
    }

    // If we haven't decided to send a query for this yet, don't show anything!
    if (!isTryingToPrompt) {
      return null;
    }

    // If the user has seen the notice and has been dismissed
    if (notice && notice.dismissedAt) {
      return null;
    }

    // If the user has dismissed this notice instance
    if (hasBeenDismissed) {
      return null;
    }

    if (isAddingEmail || isSendingVerification) {
      return (

          <Spinner />

            {isSendingVerification ? 'Resending verification email…' : `Adding ${email}…`}

      );
    }

    const userEmail = this.getUserEmail(email);

    if (userEmail) {
      if (userEmail.verified) {
        return null;
      }

      if (hasSentSomething) {
        return (

              Verification Needed

              Click the link we’ve just emailed to {email} to finish adding this email to your account.

            <Button
              className="block mt2"
              theme="default"
              outline={true}
              style={{ width: '100%' }}
              onClick={this.handleLocalDismissClick}
            >
              Dismiss
            </Button>

        );
      }

      return (

            Verification Needed

            We’ve emailed a link to {email} to add this email to your account.

            If it hasn’t arrived, you can resend it from here!

          <Button
            className="block mt2"
            theme="default"
            outline={true}
            style={{ width: '100%' }}
            onClick={this.handleResendVerificationClick}
          >
            Resend Verification Email
          </Button>

      );
    }

    // Otherwise, we've got an unknown (to Buildkite) email address on our hands!
    return (

          Do you own this email address? If so, add it to your Buildkite account to take ownership of this build.

        <Button
          className="block my2"
          style={{ width: '100%' }}
          onClick={this.handleAddEmailClick}
        >
          Add {email}
        </Button>
        <Button
          className="block"
          theme="default"
          outline={true}
          style={{ width: '100%' }}
          onClick={this.handleDismissClick}
        >
          Dismiss
        </Button>

    );
  }

  render() {
    const { build } = this.props;

    const avatar = (
      <UserAvatar
        user={build.createdBy}
        style={{ width: 32, height: 32 }}
      />
    );

    const content = this.renderContent();

    if (content) {
      return (
        <AnchoredPopover
          alwaysShow={true}
          width={400}
        >
          {avatar}
          {content}
        </AnchoredPopover>
      );
    }

    return avatar;
  }
}

export default Relay.createContainer(AvatarWithEmailPrompt, {
  initialVariables: {
    emailForPrompt: null,
    isTryingToPrompt: false
  },

  fragments: {
    build: () => Relay.QL`
      fragment on Build {
        createdBy {
          ...on UnregisteredUser {
            email
            name
            avatar {
              url
            }
          }
          ...on User {
            name
            avatar {
              url
            }
          }
        }
      }
    `,
    viewer: () => Relay.QL`
      fragment on Viewer {
        ${EmailCreateMutation.getFragment('viewer')}
        emails(first: 50) {
          edges {
            node {
              id
              address
              verified
            }
          }
        }
        notice(namespace: NOTICE_NAMESPACE_EMAIL_SUGGESTION, scope: $emailForPrompt) @include(if: $isTryingToPrompt) {
          ${NoticeDismissMutation.getFragment('notice')}
          dismissedAt
        }
      }
    `
  }
});
<|endoftext|>


<commit_before>(function() {
'use strict';

    angular
        .module('app')
        .component('gallery', {
            templateUrl: 'components/gallery/gallery.html',
            controller: GalleryController,
            controllerAs: "vm",
            bindings: {
            },
        });

    GalleryController.$inject = [];
    function GalleryController() {
        this.items = [
            {
                name: "Template 1",
                price: "£100000",
                seller: "George"
            },
            {
                name: "Template 2",
                price: "£1000",
                seller: "Mike"
            },
            {
                name: "Template 1",
                price: "£100000",
                seller: "George"
            }];
        this.previews = [
            {
                name: "Template 1",
                price: "£100000",
                seller: "George"
            },
            {
                name: "Template 2",
                price: "£1000",
                seller: "Mike"
            },
            {
                name: "Template 1",
                price: "£100000",
                seller: "George"
            },
        ];
        this.$onInit = function() { };
        this.$onChanges = function(changesObj) { };
        this.$onDestory = function() { };
    }
})();<commit_msg>Update gallery.comp.js<commit_after>(function() {
'use strict';

    angular
        .module('app')
        .component('gallery', {
            templateUrl: 'components/gallery/gallery.html',
            controller: GalleryController,
            controllerAs: "vm",
            bindings: {
            },
        });

    GalleryController.$inject = [];
    function GalleryController() {
        this.items = [];
        this.previews = [
            {
                name: "Lands End Panorama",
                price: "$74.99",
                seller: "George Smith"
                img: "https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&ved=&url=http%3A%2F%2Fpbs.twimg.com%2Fprofile_images%2F440941961349201920%2FWZKquS-P.jpeg&psig=AFQjCNFF0ihTpDQut-hJgGJIzNSzB9_7mQ&ust=1473288381708933&cad=rjt"
            },
            {
                name: "Golden Gate Sunny Shot",
                price: "$99.99",
                seller: "Michael Gump"
                img: "http://maiden-voyage-travel.com/wp-content/uploads/2013/01/Golden-Gate-Bridge-San-Fran.jpg"
            },
            {
                name: "Pier 39 Long Exposure",
                price: "$54.99",
                seller: "Frank Daniels"
                img: "https://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&ved=&url=http%3A%2F%2Fpbs.twimg.com%2Fprofile_images%2F440941961349201920%2FWZKquS-P.jpeg&psig=AFQjCNFF0ihTpDQut-hJgGJIzNSzB9_7mQ&ust=1473288381708933&cad=rjt"
            },
        ];
        this.$onInit = function() { };
        this.$onChanges = function(changesObj) { };
        this.$onDestory = function() { };
    }
})();
<|endoftext|>


<commit_before>import { computed } from '@ember/object';
import { A } from '@ember/array';
import { inject as service } from '@ember/service';
import Component from '@ember/component';
import { task, timeout } from 'ember-concurrency';

export default Component.extend({
    store: service(),
    newNode: null,
    more: false,
    institutionsSelected: computed.oneWay('user.institutions'),

    actions: {
        select(institution) {
            if (this.get('institutionsSelected').includes(institution)) {
                this.get('institutionsSelected').removeObject(institution);
            } else {
                this.get('institutionsSelected').pushObject(institution);
            }
            this.notifyPropertyChange('institutionsSelected');
        },
        selectAll() {
            this.set('institutionsSelected', this.get('user.institutions').slice());
        },
        removeAll() {
            this.set('institutionsSelected', A([]));
        },
        toggleMore() {
            this.toggleProperty('more');
        },
        closeModal() {
            this.set('newNode', null);
            this.get('closeModal')();
        },
        reload() {
            this.set('newNode', null);
            this.get('closeModal')();
            this.get('reloadNodes')();
        },
        pushEnter() {
            if (this.get('nodeTitle.length')) {
                this.get('createNode').perform();
            }
        },
    },

    findNodes: task(function* (term) {
        yield timeout(500);
        const user = yield this.get('user');
        const nodes = yield user.queryHasMany('nodes', { 'filter[title]': term });
        return nodes;
    }).restartable(),

    createNode: task(function* () {
        const data = {
            public: false,
            category: 'project',
            title: this.get('nodeTitle'),
            description: this.get('description'),
        };
        if (this.get('templateFrom')) {
            data.templateFrom = this.get('templateFrom.id');
        }
        const store = yield this.get('store');
        const node = yield store.createRecord('node', data).save();
        if (this.get('institutionsSelected.length')) {
            yield node.get('affiliatedInstitutions');
            this.get('institutionsSelected').forEach(inst => node.get('affiliatedInstitutions').pushObject(inst));
            yield node.save();
        }
        this.set('newNode', node);
    }).drop(),
});
<commit_msg>Fix bug with unselecting institution removing it from user.institutions. why does oneWay not prevent that<commit_after>import { computed } from '@ember/object';
import { A } from '@ember/array';
import { inject as service } from '@ember/service';
import Component from '@ember/component';
import { task, timeout } from 'ember-concurrency';

export default Component.extend({
    store: service(),
    newNode: null,
    more: false,
    institutionsSelected: computed.oneWay('user.institutions'),

    actions: {
        select(institution) {
            this.set('institutionsSelected', this.get('institutionsSelected').slice());
            if (this.get('institutionsSelected').includes(institution)) {
                this.get('institutionsSelected').removeObject(institution);
            } else {
                this.get('institutionsSelected').pushObject(institution);
            }
            this.notifyPropertyChange('institutionsSelected');
        },
        selectAll() {
            this.set('institutionsSelected', this.get('user.institutions').slice());
        },
        removeAll() {
            this.set('institutionsSelected', A([]));
        },
        toggleMore() {
            this.toggleProperty('more');
        },
        closeModal() {
            this.set('newNode', null);
            this.get('closeModal')();
        },
        reload() {
            this.set('newNode', null);
            this.get('closeModal')();
            this.get('reloadNodes')();
        },
        pushEnter() {
            if (this.get('nodeTitle.length')) {
                this.get('createNode').perform();
            }
        },
    },

    findNodes: task(function* (term) {
        yield timeout(500);
        const user = yield this.get('user');
        const nodes = yield user.queryHasMany('nodes', { 'filter[title]': term });
        return nodes;
    }).restartable(),

    createNode: task(function* () {
        const data = {
            public: false,
            category: 'project',
            title: this.get('nodeTitle'),
            description: this.get('description'),
        };
        if (this.get('templateFrom')) {
            data.templateFrom = this.get('templateFrom.id');
        }
        const store = yield this.get('store');
        const node = yield store.createRecord('node', data).save();
        if (this.get('institutionsSelected.length')) {
            yield node.get('affiliatedInstitutions');
            this.get('institutionsSelected').forEach(inst => node.get('affiliatedInstitutions').pushObject(inst));
            yield node.save();
        }
        this.set('newNode', node);
    }).drop(),
});
<|endoftext|>


<commit_before>import {Observable as O} from 'rx';

import {clamp} from '../../../lib/utils';

const clampPosition = (modifierFn, {minX, minY, maxX, maxY}) =>
  (cam) => {
    const {x,y,zoom} = modifierFn(cam);
    return {
      zoom,
      x: clamp(x, minX, maxX),
      y: clamp(y, minY, maxY),
    };
  }
;

const zoomModifier = (min, max) => ({factor, pivot}) => ({x, y, zoom}) => {
  const newZoom = clamp(zoom * factor, min, max);
  const realFactor = newZoom / zoom;
  const panFactor = (1 - 1 / realFactor);

  return {
    zoom: newZoom,
    x: x + (pivot.x - x) * panFactor,
    y: y + (pivot.y - y) * panFactor,
  };
};

const panModifier = (delta) => ({x, y, zoom}) => ({
  zoom,
  x: x - delta.x,
  y: y - delta.y,
});

const autoCenterModifier = ({
  width, height, pivotX = 0.5, pivotY = 0,
}) => ({minX, minY, maxX, maxY}) => {
  const centerX = (maxX + minX) / 2;
  const centerY = (maxY + minY) / 2;
  const contentWidth = maxX - minX;
  const contentHeight = maxY - minY;
  const xRatio = (width - 20) / contentWidth;
  const zoom = xRatio;

  return () => ({
    x: centerX + (pivotX - 0.5) * contentWidth,
    y: centerY + (pivotY - 0.5) * contentHeight + height / 2 / zoom,
    zoom,
  });
};

const ContentThunk = function thunkConstructor(node, key) {
  this.node = node;
  this.key = key;
};
ContentThunk.prototype.type = "Thunk";
ContentThunk.prototype.render = function thunkRender(previous) {
  if (!previous || previous.key !== this.key) {
    return this.node;
  } else {
    return previous.vnode;
  }
};

export default ({props$, camera$, bounds$, content$}, actions) => {
  const contentThunk$ = content$.map((content, index) => {
    return new ContentThunk(content, index % 2);
  });

  const distinctBounds$ = bounds$
    .distinctUntilChanged(
      (a) => a,
      (a,b) => a.minX === b.minX && a.maxX === b.maxX &&
        a.minY === b.minY && a.maxY === b.maxY
    );

  return O.combineLatest(
    props$,
    camera$,
    (props, initCamera) =>
      distinctBounds$
      .flatMapLatest((bounds) =>
        O.merge(
          actions.zoom$.map(zoomModifier(0.2, 5)),
          actions.pan$.map(panModifier),
          distinctBounds$
          .map(autoCenterModifier(props))
        ).map((mod) => clampPosition(mod, bounds))
        .startWith(({x, y, zoom}) => ({
          zoom,
          x: clamp(x, bounds.minX, bounds.maxX),
          y: clamp(y, bounds.minY, bounds.maxY),
        }))
      )
      .startWith({
        zoom: initCamera.zoom,
        x: initCamera.x,
        y: initCamera.y,
      })
      .scan((cam, modFn) => modFn(cam))
      .combineLatest(bounds$, contentThunk$, (cam, bounds, content) => ({
        width: props.width,
        height: props.height,
        camera: cam,
        bounds,
        content,
      }))
  ).switch();
};
<commit_msg>clamp zoom level when autocentering<commit_after>import {Observable as O} from 'rx';

import {clamp} from '../../../lib/utils';

const clampPosition = (modifierFn, {minX, minY, maxX, maxY}) =>
  (cam) => {
    const {x,y,zoom} = modifierFn(cam);
    return {
      zoom,
      x: clamp(x, minX, maxX),
      y: clamp(y, minY, maxY),
    };
  }
;

const zoomModifier = (min, max) => ({factor, pivot}) => ({x, y, zoom}) => {
  const newZoom = clamp(zoom * factor, min, max);
  const realFactor = newZoom / zoom;
  const panFactor = (1 - 1 / realFactor);

  return {
    zoom: newZoom,
    x: x + (pivot.x - x) * panFactor,
    y: y + (pivot.y - y) * panFactor,
  };
};

const panModifier = (delta) => ({x, y, zoom}) => ({
  zoom,
  x: x - delta.x,
  y: y - delta.y,
});

const autoCenterModifier = ({
  width, height, pivotX = 0.5, pivotY = 0,
}) => ({minX, minY, maxX, maxY}) => {
  const centerX = (maxX + minX) / 2;
  const centerY = (maxY + minY) / 2;
  const contentWidth = maxX - minX;
  const contentHeight = maxY - minY;
  const xRatio = (width - 20) / contentWidth;
  const zoom = xRatio;

  return () => ({
    x: centerX + (pivotX - 0.5) * contentWidth,
    y: centerY + (pivotY - 0.5) * contentHeight + height / 2 / zoom,
    zoom: clamp(zoom, 0.2, 5),
  });
};

const ContentThunk = function thunkConstructor(node, key) {
  this.node = node;
  this.key = key;
};
ContentThunk.prototype.type = "Thunk";
ContentThunk.prototype.render = function thunkRender(previous) {
  if (!previous || previous.key !== this.key) {
    return this.node;
  } else {
    return previous.vnode;
  }
};

export default ({props$, camera$, bounds$, content$}, actions) => {
  const contentThunk$ = content$.map((content, index) => {
    return new ContentThunk(content, index % 2);
  });

  const distinctBounds$ = bounds$
    .distinctUntilChanged(
      (a) => a,
      (a,b) => a.minX === b.minX && a.maxX === b.maxX &&
        a.minY === b.minY && a.maxY === b.maxY
    );

  return O.combineLatest(
    props$,
    camera$,
    (props, initCamera) =>
      distinctBounds$
      .flatMapLatest((bounds) =>
        O.merge(
          actions.zoom$.map(zoomModifier(0.2, 5)),
          actions.pan$.map(panModifier),
          distinctBounds$
          .map(autoCenterModifier(props))
        ).map((mod) => clampPosition(mod, bounds))
        .startWith(({x, y, zoom}) => ({
          zoom,
          x: clamp(x, bounds.minX, bounds.maxX),
          y: clamp(y, bounds.minY, bounds.maxY),
        }))
      )
      .startWith({
        zoom: initCamera.zoom,
        x: initCamera.x,
        y: initCamera.y,
      })
      .scan((cam, modFn) => modFn(cam))
      .combineLatest(bounds$, contentThunk$, (cam, bounds, content) => ({
        width: props.width,
        height: props.height,
        camera: cam,
        bounds,
        content,
      }))
  ).switch();
};
<|endoftext|>


<commit_before>import React from 'react';
import Relay from 'react-relay';
import classNames from 'classnames';

import Icon from '../../shared/Icon';
import Dropdown from '../../shared/Dropdown';
import BuildState from '../../icons/BuildState';
import Favorite from '../../icons/Favorite';
import Emojify from '../../shared/Emojify';

import PipelineFavoriteMutation from '../../../mutations/PipelineFavorite';

import Metric from './metric';
import Graph from './graph';
import SectionLink from './section-link';
import Build from './build';

class Pipeline extends React.Component {
  static propTypes = {
    pipeline: React.PropTypes.shape({
      name: React.PropTypes.string.isRequired,
      slug: React.PropTypes.string.isRequired,
      description: React.PropTypes.string,
      defaultBranch: React.PropTypes.string.isRequired,
      favorite: React.PropTypes.bool.isRequired,
      url: React.PropTypes.string.isRequired,
      metrics: React.PropTypes.shape({
        edges: React.PropTypes.arrayOf(
          React.PropTypes.shape({
            node: React.PropTypes.shape({
              label: React.PropTypes.string.isRequired,
              value: React.PropTypes.string,
              url: React.PropTypes.string
            }).isRequired
          }).isRequired
        )
      }).isRequired,
      defaultBranchBuilds: React.PropTypes.shape({
        edges: React.PropTypes.arrayOf(
          React.PropTypes.shape({
            node: React.PropTypes.object.isRequired
          }).isRequired
        )
      }).isRequired,
      featuredDefaultBranchBuilds: React.PropTypes.shape({
        edges: React.PropTypes.arrayOf(
          React.PropTypes.shape({
            node: React.PropTypes.object.isRequired
          }).isRequired
        )
      }).isRequired,
      allBuilds: React.PropTypes.shape({
        count: React.PropTypes.number.isRequired
      }).isRequired
    }).isRequired
  };

  state = {
    showingMenu: false
  };

  render() {
    return (

        {this.renderFeaturedBuildIcon()}

        <SectionLink className="flex items-center flex-auto px2" href={this.props.pipeline.url}>

{this.props.pipeline.name}

            {this.renderDescription()}

        </SectionLink>

          {this.renderMetrics()}

        {this.renderGraph()}

          <button className="btn p0 mb1" onClick={this.handleFavoriteClick}>
            <Favorite favorite={this.props.pipeline.favorite} />
          </button>

          <Dropdown align="center" width={180} onToggle={this.handleMenuToggle}>
            <button className="btn p0 gray hover-dark-gray">
              <Icon icon="menu" className={classNames({ "dark-gray": this.state.showingMenu })} />
            </button>

            <a href={`${this.props.pipeline.url}/settings`} className="btn block hover-lime">Configure Pipeline
          </Dropdown>

    );
  }

  renderDescription() {
    if(this.props.pipeline.description) {
      return (

          {this.props.pipeline.description ? <Emojify className="h5 regular" text={this.props.pipeline.description} /> : null}

      );
    }
  }

  renderFeaturedBuildIcon() {
    let featuredBuildEdge = this.props.pipeline.featuredDefaultBranchBuilds.edges[0];

    if(featuredBuildEdge) {
      let featuredBuild = featuredBuildEdge.node;

      return (

          <Build build={featuredBuild}>
            <SectionLink href={featuredBuild.url} className="block line-height-1">
              <BuildState state={featuredBuild.state} />
            </SectionLink>
          </Build>

      );
    } else {
      return (

          <BuildState state="pending" />

      );
    }
  }

  renderMetrics() {
    if(this.props.pipeline.allBuilds.count > 0) {
      return this.props.pipeline.metrics.edges.map((edge) => {
        return (
          <Metric key={edge.node.label} label={edge.node.label} value={edge.node.value} href={edge.node.url} />
        );
      })
    }
  }

  renderGraph() {
    if(this.props.pipeline.defaultBranchBuilds.edges.length > 0) {
      return (

{this.props.pipeline.defaultBranch}

            <Graph builds={this.props.pipeline.defaultBranchBuilds}  />

      )
    }
  }

  handleMenuToggle = (visible) => {
    this.setState({ showingMenu: visible });
  };

  handleFavoriteClick = () => {
    var mutation = new PipelineFavoriteMutation({
      pipeline: this.props.pipeline,
      favorite: !this.props.pipeline.favorite
    });

    Relay.Store.commitUpdate(mutation, {
      onFailure: this.handlePipelineFavoriteMutationFailure
    });
  }

  handlePipelineFavoriteMutationFailure = (transaction) => {
    alert(transaction.getError());
  }
}

export default Relay.createContainer(Pipeline, {
  fragments: {
    pipeline: () => Relay.QL`
      fragment on Pipeline {
        ${PipelineFavoriteMutation.getFragment('pipeline')}
        id
        name
        slug
        description
        defaultBranch
        url
        favorite
        metrics(first: 6) {
          edges {
            node {
              label
              value
              url
            }
          }
        }
        featuredDefaultBranchBuilds: builds(first: 1, state: [ BUILD_STATE_PASSED, BUILD_STATE_FAILED, BUILD_STATE_CANCELED ]) {
          edges {
            node {
              state
              message
              startedAt
              finishedAt
              url
              user {
                name
                avatar {
                  url
                }
              }
            }
          }
        }
        defaultBranchBuilds: builds(first: 30, state: [ BUILD_STATE_RUNNING, BUILD_STATE_PASSED, BUILD_STATE_FAILED, BUILD_STATE_CANCELED, BUILD_STATE_CANCELING ]) {
          edges {
            node {
              state
              message
              startedAt
              finishedAt
              url
              user {
                name
                avatar {
                  url
                }
              }
            }
          }
        }
        allBuilds: builds {
          count
        }
      }
    `
  }
});
<commit_msg>Always show the metrics and graph even if there isn't any data<commit_after>import React from 'react';
import Relay from 'react-relay';
import classNames from 'classnames';

import Icon from '../../shared/Icon';
import Dropdown from '../../shared/Dropdown';
import BuildState from '../../icons/BuildState';
import Favorite from '../../icons/Favorite';
import Emojify from '../../shared/Emojify';

import PipelineFavoriteMutation from '../../../mutations/PipelineFavorite';

import Metric from './metric';
import Graph from './graph';
import SectionLink from './section-link';
import Build from './build';

class Pipeline extends React.Component {
  static propTypes = {
    pipeline: React.PropTypes.shape({
      name: React.PropTypes.string.isRequired,
      slug: React.PropTypes.string.isRequired,
      description: React.PropTypes.string,
      defaultBranch: React.PropTypes.string.isRequired,
      favorite: React.PropTypes.bool.isRequired,
      url: React.PropTypes.string.isRequired,
      metrics: React.PropTypes.shape({
        edges: React.PropTypes.arrayOf(
          React.PropTypes.shape({
            node: React.PropTypes.shape({
              label: React.PropTypes.string.isRequired,
              value: React.PropTypes.string,
              url: React.PropTypes.string
            }).isRequired
          }).isRequired
        )
      }).isRequired,
      defaultBranchBuilds: React.PropTypes.shape({
        edges: React.PropTypes.arrayOf(
          React.PropTypes.shape({
            node: React.PropTypes.object.isRequired
          }).isRequired
        )
      }).isRequired,
      featuredDefaultBranchBuilds: React.PropTypes.shape({
        edges: React.PropTypes.arrayOf(
          React.PropTypes.shape({
            node: React.PropTypes.object.isRequired
          }).isRequired
        )
      }).isRequired
    }).isRequired
  };

  state = {
    showingMenu: false
  };

  render() {
    return (

        {this.renderFeaturedBuildIcon()}

        <SectionLink className="flex items-center flex-auto px2" href={this.props.pipeline.url}>

{this.props.pipeline.name}

            {this.renderDescription()}

        </SectionLink>

          {this.props.pipeline.metrics.edges.map((edge) => {
            return (
              <Metric key={edge.node.label} label={edge.node.label} value={edge.node.value} href={edge.node.url} />
              );
          })}

{this.props.pipeline.defaultBranch}

            <Graph builds={this.props.pipeline.defaultBranchBuilds}  />

          <button className="btn p0 mb1" onClick={this.handleFavoriteClick}>
            <Favorite favorite={this.props.pipeline.favorite} />
          </button>

          <Dropdown align="center" width={180} onToggle={this.handleMenuToggle}>
            <button className="btn p0 gray hover-dark-gray">
              <Icon icon="menu" className={classNames({ "dark-gray": this.state.showingMenu })} />
            </button>

            <a href={`${this.props.pipeline.url}/settings`} className="btn block hover-lime">Configure Pipeline
          </Dropdown>

    );
  }

  renderDescription() {
    if(this.props.pipeline.description) {
      return (

          {this.props.pipeline.description ? <Emojify className="h5 regular" text={this.props.pipeline.description} /> : null}

      );
    }
  }

  renderFeaturedBuildIcon() {
    let featuredBuildEdge = this.props.pipeline.featuredDefaultBranchBuilds.edges[0];

    if(featuredBuildEdge) {
      let featuredBuild = featuredBuildEdge.node;

      return (

          <Build build={featuredBuild}>
            <SectionLink href={featuredBuild.url} className="block line-height-1">
              <BuildState state={featuredBuild.state} />
            </SectionLink>
          </Build>

      );
    } else {
      return (

          <BuildState state="pending" />

      );
    }
  }

  handleMenuToggle = (visible) => {
    this.setState({ showingMenu: visible });
  };

  handleFavoriteClick = () => {
    var mutation = new PipelineFavoriteMutation({
      pipeline: this.props.pipeline,
      favorite: !this.props.pipeline.favorite
    });

    Relay.Store.commitUpdate(mutation, {
      onFailure: this.handlePipelineFavoriteMutationFailure
    });
  }

  handlePipelineFavoriteMutationFailure = (transaction) => {
    alert(transaction.getError());
  }
}

export default Relay.createContainer(Pipeline, {
  fragments: {
    pipeline: () => Relay.QL`
      fragment on Pipeline {
        ${PipelineFavoriteMutation.getFragment('pipeline')}
        id
        name
        slug
        description
        defaultBranch
        url
        favorite
        metrics(first: 6) {
          edges {
            node {
              label
              value
              url
            }
          }
        }
        featuredDefaultBranchBuilds: builds(first: 1, state: [ BUILD_STATE_PASSED, BUILD_STATE_FAILED, BUILD_STATE_CANCELED ]) {
          edges {
            node {
              state
              message
              startedAt
              finishedAt
              url
              user {
                name
                avatar {
                  url
                }
              }
            }
          }
        }
        defaultBranchBuilds: builds(first: 30, state: [ BUILD_STATE_RUNNING, BUILD_STATE_PASSED, BUILD_STATE_FAILED, BUILD_STATE_CANCELED, BUILD_STATE_CANCELING ]) {
          edges {
            node {
              state
              message
              startedAt
              finishedAt
              url
              user {
                name
                avatar {
                  url
                }
              }
            }
          }
        }
      }
    `
  }
});
<|endoftext|>